diff --git a/.github/workflows/ebrains-push.yml b/.github/workflows/ebrains-push.yml new file mode 100644 index 000000000..b648b1e79 --- /dev/null +++ b/.github/workflows/ebrains-push.yml @@ -0,0 +1,25 @@ +name: Mirror to EBRAINS + +on: + push: + branches: [ master ] + +jobs: + sync_to_ebrains: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'nest' }} + steps: + - name: sycnmaster + uses: wei/git-sync@v3 + with: + source_repo: "nest/nestml" + source_branch: "master" + destination_repo: "https://ghpusher:${{ secrets.EBRAINS_NESTML_GITLAB }}@gitlab.ebrains.eu/nest/nestml.git" + destination_branch: "main" + - name: synctags + uses: wei/git-sync@v3 + with: + source_repo: "nest/nestml" + source_branch: "refs/tags/*" + destination_repo: "https://ghpusher:${{ secrets.EBRAINS_NESTML_GITLAB }}@gitlab.ebrains.eu/nest/nestml.git" + destination_branch: "refs/tags/*" diff --git a/.github/workflows/nestml-build.yml b/.github/workflows/nestml-build.yml new file mode 100644 index 000000000..2fdbb9205 --- /dev/null +++ b/.github/workflows/nestml-build.yml @@ -0,0 +1,138 @@ +name: NESTML compatibility check with older NEST versions + +on: [push, pull_request] + +jobs: + build_and_test: + runs-on: ubuntu-latest + strategy: + matrix: + nest_branch: ["v2.20.2", "v3.3", "master"] + fail-fast: false + steps: + # Checkout the repository contents + - name: Checkout NESTML code + uses: actions/checkout@v2 + + # Setup Python version + - name: Setup Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: 3.9 + + # Install dependencies + - name: Install apt dependencies + run: | + sudo apt-get update + sudo apt-get install libltdl7-dev libgsl0-dev libncurses5-dev libreadline6-dev pkg-config + sudo apt-get install python3-all-dev python3-matplotlib python3-numpy python3-scipy ipython3 + + # Install Python dependencies + - name: Python dependencies + run: | + python -m pip install --upgrade pip pytest jupyterlab matplotlib pycodestyle scipy + python -m pip install -r requirements.txt + + # Static code analysis + - name: Static code style analysis + run: | + python3 extras/codeanalysis/check_copyright_headers.py && python3 -m pycodestyle $GITHUB_WORKSPACE -v --ignore=E241,E501,E714,E713,E714,E252,W503 --exclude=$GITHUB_WORKSPACE/doc,$GITHUB_WORKSPACE/.git,$GITHUB_WORKSPACE/NESTML.egg-info,$GITHUB_WORKSPACE/pynestml/generated,$GITHUB_WORKSPACE/extras,$GITHUB_WORKSPACE/build,$GITHUB_WORKSPACE/.github + + # Install Java + - name: Install Java 11 + uses: actions/setup-java@v1 + with: + java-version: '11.0.x' + java-package: jre + + # Install Antlr4 + - name: Install Antlr4 + run: | + wget http://www.antlr.org/download/antlr-4.10-complete.jar + echo \#\!/bin/bash > antlr4 + echo java -cp \"`pwd`/antlr-4.10-complete.jar:$CLASSPATH\" org.antlr.v4.Tool \"\$@\" >> antlr4 + echo >> antlr4 + chmod +x antlr4 + echo PATH=$PATH:`pwd` >> $GITHUB_ENV + + # Install NEST simulator + - name: NEST simulator + run: | + python -m pip install cython + echo "GITHUB_WORKSPACE = $GITHUB_WORKSPACE" + cd $GITHUB_WORKSPACE/.. + NEST_SIMULATOR=$(pwd)/nest-simulator + NEST_INSTALL=$(pwd)/nest_install + echo "NEST_SIMULATOR = $NEST_SIMULATOR" + echo "NEST_INSTALL = $NEST_INSTALL" + + git clone --depth=1 https://github.com/nest/nest-simulator --branch ${{ matrix.nest_branch }} + mkdir nest_install + echo "NEST_INSTALL=$NEST_INSTALL" >> $GITHUB_ENV + cd nest_install + cmake -DCMAKE_INSTALL_PREFIX=$NEST_INSTALL $NEST_SIMULATOR + make && make install + cd .. + + # Install NESTML (repeated) + - name: Install NESTML + run: | + cd $GITHUB_WORKSPACE + export PYTHONPATH=${{ env.PYTHONPATH }}:${{ env.NEST_INSTALL }}/lib/python3.9/site-packages + #echo PYTHONPATH=`pwd` >> $GITHUB_ENV + echo "PYTHONPATH=$PYTHONPATH" >> $GITHUB_ENV + python setup.py install + + - name: Generate Lexer and Parser using Antlr4 + run: | + cd $GITHUB_WORKSPACE + find pynestml/generated -not -name __init__.py -a -not -name generated -delete + cd pynestml/grammars + ./generate_lexer_parser + + # Unit tests + - name: Run unit tests + run: | + pytest -s -o norecursedirs='*' -o log_cli=true -o log_cli_level="DEBUG" tests || : + git ls-remote git://github.com/nest/nest-simulator.git | grep refs/heads/master | cut -f 1 > latest_nest_master_commit_hash.txt + echo "Latest NEST master commit hash:" + cat latest_nest_master_commit_hash.txt + + # Integration tests: prepare (make module containing all NESTML models) + - name: Setup integration tests + run: | + cd $GITHUB_WORKSPACE + # exclude third factor plasticity models; these will only compile successfully if code generation is as a neuron+synapse pair + export ALL_MODEL_FILENAMES=`find models/neurons -name "*.nestml" | paste -sd " "` + echo $ALL_MODEL_FILENAMES + echo "NEST_INSTALL = ${{ env.NEST_INSTALL }}" + echo "NEST_VERSION = ${{ matrix.nest_branch }}" + sed -i 's|%NEST_PATH%|${{ env.NEST_INSTALL }}|' tests/nest_tests/resources/nest_codegen_opts.json + sed -i 's|%NEST_VERSION%|${{ matrix.nest_branch }}|' tests/nest_tests/resources/nest_codegen_opts.json + nestml --input_path $ALL_MODEL_FILENAMES --target_path target --suffix _nestml --logging_level INFO --module_name nestml_allmodels_module --codegen_opts tests/nest_tests/resources/nest_codegen_opts.json + + # Integration tests + - name: Run integration tests + env: + LD_LIBRARY_PATH: ${{ env.NEST_INSTALL }}/lib/nest + run: | + cd $GITHUB_WORKSPACE + rc=0 + for fn in $GITHUB_WORKSPACE/tests/nest_tests/*.py; do + pytest -s -o log_cli=true -o log_cli_level="DEBUG" ${fn} || rc=1 + done; + exit $rc + + # Run IPython/Jupyter notebooks + - name: Run Jupyter notebooks + if: ${{ matrix.nest_branch == 'master' }} + run: | + cd $GITHUB_WORKSPACE + ipynb_fns=$(find $GITHUB_WORKSPACE/doc/tutorials -name '*.ipynb') + rc=0 + for fn in $ipynb_fns; do + cd `dirname ${fn}` + ipython3 ${fn} || rc=1 + done; + cd $GITHUB_WORKSPACE + exit $rc diff --git a/.gitignore b/.gitignore index df376338a..24e3c5561 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ target/ .idea/ .mypy_cache/ +.eggs/ build/ buildNest/ venv/ @@ -26,3 +27,14 @@ venv *.gdf *~ *.iml +/generated/ +/NESTML.egg-info/ +.pydevproject +linkingModel.py + + +/generated_aeif_cond_alpha/ +/generated_goal/ +/generated_snapshot/ +/generated_RingBufferStar/ +/generated_cout/ diff --git a/.readthedocs.yml b/.readthedocs.yml index f65a95bdb..aa428d5c0 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,7 +1,13 @@ -type: sphinx -configuration: doc/sphinx-apidoc/conf.py +version: 2 + +build: + os: ubuntu-20.04 + tools: + python: "3.9" + +sphinx: + configuration: doc/sphinx-apidoc/conf.py + python: - version: 3 - requirements_file: requirements.txt -formats: - - none + install: + - requirements: doc/requirements.txt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6bc999c51..000000000 --- a/.travis.yml +++ /dev/null @@ -1,110 +0,0 @@ -language: python - -sudo: true - -python: "3.6" - -addons: - apt: - packages: - - build-essential - - cmake - - libltdl7-dev - - libgsl0-dev - - libncurses5-dev - - libreadline6-dev - - pkg-config - - python-all-dev - - python-matplotlib - - python-numpy - - python-scipy - -before_install: - # in before_install, we install all the NESTML dependencies - - # install antrl4 - - sudo apt install openjdk-8-jre - - wget http://www.antlr.org/download/antlr-4.8-complete.jar - - echo \#\!/bin/bash > antlr4 - - echo java -cp \"`pwd`/antlr-4.8-complete.jar:$CLASSPATH\" org.antlr.v4.Tool \"\$@\" >> antlr4 - - echo >> antlr4 - - chmod +x antlr4 - - export PATH=$PATH:`pwd` - - # install Python module dependencies - - pip install --upgrade pip pytest - - pip install -r requirements.txt - - pip uninstall --yes sympy - - pip install sympy==1.4 - - pip install pycodestyle - - # install latest odetoolbox from git master (N.B. GSL/PyGSL installation is skipped as NESTML ignores stiffness test result) - - pip uninstall --yes odetoolbox - - pip install git+https://github.com/nest/ode-toolbox.git - -install: - # in install, we install NESTML itself - - export PYTHONPATH=$PYTHONPATH:`pwd` - - echo $PYTHONPATH - - python setup.py install - -before_script: - # use antlr4 to re-generate lexer+parser - - cd $TRAVIS_BUILD_DIR - - find pynestml/generated -not -name __init__.py -a -not -name generated -delete - - cd pynestml/grammars - - ./generate_lexer_parser - - cd ../.. - -stages: - - pycodestyle - - test - - integration - -jobs: - include: - - stage: pycodestyle - script: python3 extras/codeanalysis/check_copyright_headers.py && python3 -m pycodestyle /home/travis/build/nest/nestml -v --ignore=E241,E501,E303,E714,E713,E714,E252,W503 --exclude=/home/travis/build/nest/nestml/doc,/home/travis/build/nest/nestml/.git,/home/travis/build/nest/nestml/NESTML.egg-info,/home/travis/build/nest/nestml/pynestml/generated,/home/travis/build/nest/nestml/extras,/home/travis/build/nest/nestml/build - - - stage: test - script: pytest -s -o norecursedirs='*' -o log_cli=true -o log_cli_level="DEBUG" tests - - - stage: integration - install: - # install nest-simulator - - pip install cython - - cd - - git clone --depth=1 https://github.com/nest/nest-simulator - - mkdir nest_install - - cd nest_install - - export PYTHON_INCLUDE_DIR=`python3 -c "from sysconfig import get_paths; info = get_paths(); print(info['include'])"` - - echo $PYTHON_INCLUDE_DIR - - export PYTHON_LIB_DIR=`find /usr/lib/x86_64-linux-gnu -name "libpython3*.so"` - - echo $PYTHON_LIB_DIR - - cmake -DCMAKE_INSTALL_PREFIX=~/nest_install -DPYTHON_LIBRARY=$PYTHON_LIB_DIR -DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR ~/nest-simulator - - make && make install - - # install NESTML itself - - cd $TRAVIS_BUILD_DIR - - export PYTHONPATH=$PYTHONPATH:/home/travis/virtualenv/python3.6.7/lib/python3.6/site-packages - - echo $PYTHONPATH - - python setup.py install - - script: - - nestml --input_path models --target_path target --suffix _nestml --logging_level INFO --module_name nestml_allmodels_module - - cd target - - cmake -Dwith-nest=/home/travis/nest_install/bin/nest-config . - - make && make install - - cd .. - - export PYNESTKERNEL_LOCATION=`find /home/travis/nest_install/lib -name pynestkernel.so` - - export PYNESTKERNEL_LOCATION=`dirname $PYNESTKERNEL_LOCATION` - - export PYNESTKERNEL_LOCATION=`dirname $PYNESTKERNEL_LOCATION` - - echo $PYNESTKERNEL_LOCATION - - export PYTHONPATH=$PYTHONPATH:$PYNESTKERNEL_LOCATION - # tests have to run in separate processes, hence the loop over files. This works better than pytest-xdist and pytest-forked, because they cannot show debug (stdout) output. - - | - rc=0 - for fn in $TRAVIS_BUILD_DIR/tests/nest_tests/*.py; do - pytest -s -o log_cli=true -o log_cli_level="DEBUG" ${fn} || rc=1 - done; - exit $rc diff --git a/doc/citing.rst b/doc/citing.rst index d42e58c03..96bea92d2 100644 --- a/doc/citing.rst +++ b/doc/citing.rst @@ -9,6 +9,12 @@ In general, please cite the software release that you are using. In case you wis Software releases ----------------- +Charl A.P. Linssen, Pooja N. Babu, Jingxuan He, Jochen Martin Eppler, Bernhard Rumpe and Abigail Morrison (2022). **NESTML 5.1.0.** Zenodo. `doi:10.5281/zenodo.7071624 `_. + +Charl A.P. Linssen, Pooja N. Babu, Ayssar Benelhedi, Robin De Schepper, Tanguy Fardet, Jochen Martin Eppler, Bernhard Rumpe and Abigail Morrison (2022). **NESTML 5.0.0.** Zenodo. `doi:10.5281/zenodo.5784175 `_. + +Pooja Nagendra Babu, Charl Linssen, Jochen Martin Eppler, Tobias Schulte to Brinke, Abolfazl Ziaeemehr, Tanguy Fardet, Younes Bouhadjar, Renato Duarte, Bernhard Rumpe and Abigail Morrison (2021). **NESTML 4.0.** Zenodo. `doi:10.5281/zenodo.4740083 `_. + Charl Linssen, Bernhard Rumpe, Sebastian Berns, Tanguy Fardet, Konstantin Perun, Tobias Schulte to Brinke, Dennis Terhorst, Jochen M. Eppler and Abigail Morrison (2020). **NESTML 3.1.** Zenodo. `doi:10.5281/zenodo.3697733 `_. Konstantin Perun, Philip Traeder, Jochen Martin Eppler, Dimitri Plotnikov, Tammo Ippen, Tanguy Fardet, Guido Trensch, Sanin Aleksey, Inga Blundell and Jakob Jordan (2018) **NESTML 3.0.** Zenodo. `doi:10.5281/zenodo.1412608 `_. diff --git a/doc/extending.rst b/doc/extending.rst new file mode 100644 index 000000000..b359b9442 --- /dev/null +++ b/doc/extending.rst @@ -0,0 +1,79 @@ +Extending NESTML +################ + +The NESTML toolchain is lightweight, modular and extensible. + + +Internal workflow +----------------- + +When NESTML is invoked, several steps are executed in sequence. First, the model(s) are parsed and validated. Then, depending on which target platform has been selected, transformations may occur, such as variable name rewriting in case of conflict with a keyword in the target language). The transformed models are then passed to the code generator, which combines them with a set of templates. Finally, an optional build stage compiles and builds the code, for example to yield a dynamically loadable library (``.so`` or ``.dll`` file). + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/internal_workflow.png + :alt: NESTML model(s) → Parsing and validation → Transform → (+ Templates) → Generate code (and build) → Executable (binary) code + +A more detailed description of the internal architecture of NESTML can be found in the following places: + +* Tammo Ippen, "NESTML - Creating a Neuron Modeling Language and Generating Efficient Code for the NEST Simulator with MontiCore". Master's thesis, RWTH Aachen University (2013) `PDF `__ +* Konstantin Perun, "Reengineering of NestML with Python". Master's thesis, RWTH Aachen University (2018) `PDF `__ +* Dimitri Plotnikov, "NESTML - die Domänenspezifische Sprache für den NEST-Simulator Neuronaler Netzwerke im Human Brain Project". Doctoral thesis, RWTH Aachen University (2017) `PDF `__ + + * A condensed online English version is available: :doc:`pynestml_toolchain/index` + + +API documentation +----------------- + +API documentation is automatically generated from source code and can be browsed here: :mod:`pynestml` **module index** + + +Running NESTML with custom templates +------------------------------------ + +NESTML generates model-specific code using a set of Jinja templates. The templates for each target platform are located in the `pynestml/codegeneration/resources_* `__ subdirectories. (For more information on code generation using templates, see :ref:`Section 3.1: AST Transformations and Code Generation`.) For example, for NEST, NESTML by default uses the templates in the directory `pynestml/codegeneration/resources_nest/point_neuron `__. These defaults are specified in the code generator within its default values dictionary (``_default_options``, see for instance https://github.com/nest/nestml/blob/master/pynestml/codegeneration/nest_code_generator.py). + +The default directory can be changed by specifying code generator options that override the default values. This can be done either by passing these options via the ``codegen_opts`` parameter of the NESTML Python API call to ``generate_target()``, or on the command line, through the ``--codegen_opts`` parameter to a JSON file. For example: + +.. code-block:: bash + + nestml --input_path models/neurons/iaf_psc_exp.nestml --codegen_opts /home/nest/work/codegen_options.json + +An example ``codegen_options.json`` file for NEST could look as follows: + +.. code-block:: json + + { + "templates": + { + "path": "/home/nest/work/custom_templates", + "model_templates": { + "neuron": ["@NEURON_NAME@.cpp.jinja2", "@NEURON_NAME@.h.jinja2"], + "synapse": ["@SYNAPSE_NAME@.h.jinja2"] + }, + "module_templates": ["setup/CMakeLists.txt.jinja2", + "setup/@MODULE_NAME@.h.jinja2","setup/@MODULE_NAME@.cpp.jinja2"] + } + } + +The ``templates`` option in the JSON file contains information on the custom Jinja templates to be used for code generation. + +* The ``path`` option indicates the root directory of the custom Jinja templates. +* The ``model_templates`` option indicates the names of the Jinja templates for neuron and synapse model(s) or relative path to a directory containing the neuron and synapse model(s) templates. +* The ``module_templates`` option indicates the names or relative path to a directory containing the Jinja templates for the module. + +The escape sequence ``@NEURON_NAME@`` (resp. ``@SYNAPSE_NAME@``, ``@MODULE_NAME@``) will be replaced with the name of the neuron model (resp. synapse model or name of the module) during code generation. + +If a directory is given, the directory is recursively searched for templates (files ending in the ``.jinja2`` extension), for example: + +.. code-block:: python + + codegen_opts = {"templates": {"module_templates": ["setup"]}} + + +Adding a new target platform +---------------------------- + +* Add a new set of templates in a new directory under `https://github.com/nest/nestml/tree/master/pynestml/codegeneration/resources_* `__. +* Implement a new code generator, for example based on the existing `nest_code_generator.py `_. +* Optionally, implement a new builder, for example based on the existing `nest_builder.py `_. +* Add the new target platform to the frontend in `pynestml_frontend.py `__. diff --git a/doc/extending/Dimitri_Plotnikov_Doctoral_Thesis.pdf b/doc/extending/Dimitri_Plotnikov_Doctoral_Thesis.pdf new file mode 100644 index 000000000..df77247c2 Binary files /dev/null and b/doc/extending/Dimitri_Plotnikov_Doctoral_Thesis.pdf differ diff --git a/doc/extending/Konstantin_Perun_Master_thesis.pdf b/doc/extending/Konstantin_Perun_Master_thesis.pdf new file mode 100644 index 000000000..c19196873 Binary files /dev/null and b/doc/extending/Konstantin_Perun_Master_thesis.pdf differ diff --git a/doc/extending/Tammo_Ippen_Master_Thesis.pdf b/doc/extending/Tammo_Ippen_Master_Thesis.pdf new file mode 100644 index 000000000..cc9c34ee0 Binary files /dev/null and b/doc/extending/Tammo_Ippen_Master_Thesis.pdf differ diff --git a/doc/fig/Asymmetric-STDP-learning-window-Spike-timing-window-of-STDP-for-the-induction-of.png b/doc/fig/Asymmetric-STDP-learning-window-Spike-timing-window-of-STDP-for-the-induction-of.png new file mode 100644 index 000000000..f6fd44bde Binary files /dev/null and b/doc/fig/Asymmetric-STDP-learning-window-Spike-timing-window-of-STDP-for-the-induction-of.png differ diff --git a/doc/fig/code_gen_opts.png b/doc/fig/code_gen_opts.png new file mode 100644 index 000000000..4b6175bb4 Binary files /dev/null and b/doc/fig/code_gen_opts.png differ diff --git a/doc/fig/code_gen_opts.svg b/doc/fig/code_gen_opts.svg new file mode 100644 index 000000000..a4e430167 --- /dev/null +++ b/doc/fig/code_gen_opts.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + NESTMLmodels + + Code generatoroptions + + Code generation + + NEST extensionmodule + + + + + diff --git a/doc/fig/fncom-04-00141-g003.jpg b/doc/fig/fncom-04-00141-g003.jpg new file mode 100644 index 000000000..c7ff6ff64 Binary files /dev/null and b/doc/fig/fncom-04-00141-g003.jpg differ diff --git a/doc/fig/internal_workflow.png b/doc/fig/internal_workflow.png new file mode 100644 index 000000000..7c6ca01d8 Binary files /dev/null and b/doc/fig/internal_workflow.png differ diff --git a/doc/fig/internal_workflow.svg b/doc/fig/internal_workflow.svg new file mode 100644 index 000000000..7aba0b0d0 --- /dev/null +++ b/doc/fig/internal_workflow.svg @@ -0,0 +1,1242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + NESTMLmodel(s) + + Parsing andvalidation + + Transform + + Generate code(and build) + + + + + Executable(binary) code + + + + + + + + + Templates + + diff --git a/doc/fig/nestml_clip_art.png b/doc/fig/nestml_clip_art.png new file mode 100644 index 000000000..f48fdf57a Binary files /dev/null and b/doc/fig/nestml_clip_art.png differ diff --git a/doc/fig/neuron_synapse_co_generation.png b/doc/fig/neuron_synapse_co_generation.png new file mode 100644 index 000000000..971ae0219 Binary files /dev/null and b/doc/fig/neuron_synapse_co_generation.png differ diff --git a/doc/fig/neuron_synapse_co_generation.svg b/doc/fig/neuron_synapse_co_generation.svg new file mode 100644 index 000000000..46ad7799e --- /dev/null +++ b/doc/fig/neuron_synapse_co_generation.svg @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + NESTMLneuron model + + + NESTMLsynapse model + + Code generation + + NEST C++neuron model + + NEST C++synapse model + + + + + + NESTMLneuron model + + NESTMLsynapse model + + Code generation + + NEST C++neuron model + + NEST C++synapse model + + + + + + Code generation + a + b + + diff --git a/doc/fig/stdp-nearest-neighbour.png b/doc/fig/stdp-nearest-neighbour.png new file mode 100644 index 000000000..f84c4c234 Binary files /dev/null and b/doc/fig/stdp-nearest-neighbour.png differ diff --git a/doc/fig/stdp_synapse_test.png b/doc/fig/stdp_synapse_test.png new file mode 100644 index 000000000..9a1b1de2c Binary files /dev/null and b/doc/fig/stdp_synapse_test.png differ diff --git a/doc/fig/stdp_test_window.png b/doc/fig/stdp_test_window.png new file mode 100644 index 000000000..8797d9f70 Binary files /dev/null and b/doc/fig/stdp_test_window.png differ diff --git a/doc/fig/stdp_triplet_synapse_test.png b/doc/fig/stdp_triplet_synapse_test.png new file mode 100644 index 000000000..c2c586fcb Binary files /dev/null and b/doc/fig/stdp_triplet_synapse_test.png differ diff --git a/doc/fig/synapse_conceptual.png b/doc/fig/synapse_conceptual.png new file mode 100644 index 000000000..38719d1ea Binary files /dev/null and b/doc/fig/synapse_conceptual.png differ diff --git a/doc/installation.rst b/doc/installation.rst index a8aea2f63..19993da7d 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -1,25 +1,22 @@ Installing NESTML ================= -Please note that only Python 3 is supported. The instructions below assume that ``python`` is aliased to or refers to ``python3``, and ``pip`` to ``pip3``. +Please note that only Python 3.9 (and later versions) are supported. The instructions below assume that ``python`` is aliased to or refers to ``python3``, and ``pip`` to ``pip3``. Installing the latest release from PyPI --------------------------------------- -.. Attention:: As NESTML is currently getting close to its version 4.0 release, we recommend using the development version (see below under :ref:`Installing the latest development version from GitHub`). - The easiest way to install NESTML is to use the `Python Package Index (PyPI) `_. This requires the Python package management system ``pip`` to be installed. In Ubuntu, Mint and Debian Linux you can install ``pip`` as follows: .. code-block:: bash sudo apt install python3-pip - NESTML can then be installed into your local user directory via: .. code-block:: bash - pip install nestml --user + pip install --pre nestml Installing the latest development version from GitHub @@ -40,6 +37,15 @@ Install into your local user directory using: python setup.py install --user +.. Attention:: + + When using the latest development version, you may also need the development version of ODE-toolbox. It can be installed by running: + + .. code-block:: bash + + pip install git+https://github.com/nest/ode-toolbox + + Testing ------- @@ -66,7 +72,7 @@ Test the path to ``c++``: .. code-block:: bash - which c++ + which c++ # '/home/graber/miniconda3/envs/wnestml/bin/c++' Edit ``nest-config`` and correct the entry under ``--compiler`` with the output returned by ``which c++``: @@ -87,8 +93,15 @@ The corresponding paths in ``ipython`` are: .. code-block:: python - from pynestml.frontend.pynestml_frontend import to_nest, install_nest - to_nest(input_path="/home/graber/work/nestml/doc/tutorial/izhikevich_solution.nestml", - target_path="/tmp/nestml-component", - logging_level="INFO") - install_nest("/tmp/nestml-component", "/home/graber/miniconda3/envs/wnestml/") + from pynestml.frontend.pynestml_frontend import generate_nest_target + generate_nest_target(input_path="/home/graber/work/nestml/doc/tutorial/izhikevich_solution.nestml", + target_path="/tmp/nestml-component", + logging_level="INFO") + + +Docker installation +------------------- + +NESTML is installed as part of the official NEST Simulator `Docker `_ image. + +For detailed instructions, please see https://nest-simulator.readthedocs.io/en/latest/installation/index.html. diff --git a/doc/models_library/aeif_cond_alpha.rst b/doc/models_library/aeif_cond_alpha.rst index 15bea9d2c..a28fb3807 100644 --- a/doc/models_library/aeif_cond_alpha.rst +++ b/doc/models_library/aeif_cond_alpha.rst @@ -1,30 +1,30 @@ aeif_cond_alpha ############### -aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model +aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model Description +++++++++++ -aeif_cond_alpha is the adaptive exponential integrate and fire neuron according -to Brette and Gerstner (2005). -Synaptic conductances are modelled as alpha-functions. +aeif_cond_alpha is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of a bi-exponential ("alpha") function. The membrane potential is given by the following differential equation: .. math:: - C_m \frac{dV}{dt} = - -g_L(V-E_L)+g_L\Delta_T\exp\left(\frac{V-V_{th}}{\Delta_T}\right) - - g_e(t)(V-E_e) \\ - -g_i(t)(V-E_i)-w +I_e + C_m \frac{dV_m}{dt} = + -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - + g_e(t)(V_m-E_e) \\ + -g_i(t)(V_m-E_i)-w + I_e and .. math:: - \tau_w \frac{dw}{dt} = a(V-E_L) - w + \tau_w \frac{dw}{dt} = a(V_m-E_L) - w + +Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. References @@ -35,12 +35,14 @@ References activity. Journal of Neurophysiology. 943637-3642 DOI: https://doi.org/10.1152/jn.00686.2005 + See also ++++++++ iaf_cond_alpha, aeif_cond_exp + Parameters ++++++++++ @@ -57,15 +59,15 @@ Parameters "g_L", "nS", "30.0nS", "Leak Conductance" "E_L", "mV", "-70.6mV", "Leak reversal Potential (aka resting potential)" "a", "nS", "4nS", "spike adaptation parametersSubthreshold adaptation" - "b", "pA", "80.5pA", "pike-triggered adaptation" + "b", "pA", "80.5pA", "Spike-triggered adaptation" "Delta_T", "mV", "2.0mV", "Slope factor" "tau_w", "ms", "144.0ms", "Adaptation time constant" "V_th", "mV", "-50.4mV", "Threshold Potential" "V_peak", "mV", "0mV", "Spike detection threshold" - "E_ex", "mV", "0mV", "synaptic parametersExcitatory reversal Potential" - "tau_syn_ex", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "E_in", "mV", "-85.0mV", "Inhibitory reversal Potential" - "tau_syn_in", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" + "E_exc", "mV", "0mV", "synaptic parametersExcitatory reversal Potential" + "tau_syn_exc", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" + "E_inh", "mV", "-85.0mV", "Inhibitory reversal Potential" + "tau_syn_inh", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" "I_e", "pA", "0pA", "constant external input current" @@ -96,7 +98,7 @@ Equations .. math:: - \frac{ dw } { dt }= \frac 1 { \tau_{w} } \left( { (a \cdot (V_{m} - E_{L}) - w) } \right) + \frac{ dw } { dt }= \frac 1 { \tau_{w} } \left( { (a \cdot (V_{bounded} - E_{L}) - w) } \right) @@ -105,73 +107,69 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron aeif_cond_alpha: - initial_values: + state: V_m mV = E_L # Membrane potential w pA = 0pA # Spike-adaptation current end equations: - function V_bounded mV = min(V_m,V_peak) # prevent exponential divergence - kernel g_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel g_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - - /* Add functions to simplify the equation definition of V_m*/ - function exp_arg real = (V_bounded - V_th) / Delta_T - function I_spike pA = g_L * Delta_T * exp(exp_arg) - function I_syn_exc pA = convolve(g_ex,spikesExc) * (V_bounded - E_ex) - function I_syn_inh pA = convolve(g_in,spikesInh) * (V_bounded - E_in) + inline V_bounded mV = min(V_m,V_peak) # prevent exponential divergence + kernel g_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel g_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + # Add inlines to simplify the equation definition of V_m + inline exp_arg real = (V_bounded - V_th) / Delta_T + inline I_spike pA = g_L * Delta_T * exp(exp_arg) + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_bounded - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_bounded - E_inh) V_m'=(-g_L * (V_bounded - E_L) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim) / C_m - w'=(a * (V_m - E_L) - w) / tau_w + w'=(a * (V_bounded - E_L) - w) / tau_w end parameters: - - /* membrane parameters*/ + # membrane parameters C_m pF = 281.0pF # Membrane Capacitance t_ref ms = 0.0ms # Refractory period V_reset mV = -60.0mV # Reset Potential g_L nS = 30.0nS # Leak Conductance E_L mV = -70.6mV # Leak reversal Potential (aka resting potential) + # spike adaptation parameters - /* spike adaptation parameters*/ + # spike adaptation parameters a nS = 4nS # Subthreshold adaptation - b pA = 80.5pA # pike-triggered adaptation + b pA = 80.5pA # Spike-triggered adaptation Delta_T mV = 2.0mV # Slope factor tau_w ms = 144.0ms # Adaptation time constant V_th mV = -50.4mV # Threshold Potential V_peak mV = 0mV # Spike detection threshold + # synaptic parameters - /* synaptic parameters*/ - E_ex mV = 0mV # Excitatory reversal Potential - tau_syn_ex ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - E_in mV = -85.0mV # Inhibitory reversal Potential - tau_syn_in ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse + # synaptic parameters + E_exc mV = 0mV # Excitatory reversal Potential + tau_syn_exc ms = 0.2ms # Synaptic Time Constant Excitatory Synapse + E_inh mV = -85.0mV # Inhibitory reversal Potential + tau_syn_inh ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: - - /* Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude*/ - /* conductance excursion.*/ - PSConInit_E nS/ms = nS * e / tau_syn_ex - - /* Impulse to add to DG_INH on spike arrival to evoke unit-amplitude*/ - /* conductance excursion.*/ - PSConInit_I nS/ms = nS * e / tau_syn_in - - /* refractory time in steps*/ + # Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude conductance excursion + PSConInit_E nS/ms = nS * e / tau_syn_exc + # Impulse to add to DG_INH on spike arrival to evoke unit-amplitude conductance excursion + PSConInit_I nS/ms = nS * e / tau_syn_inh + # refractory time in steps RefractoryCounts integer = steps(t_ref) - /* counts number of tick during the refractory period*/ + # counts number of tick during the refractory period - /* counts number of tick during the refractory period*/ + # counts number of tick during the refractory period r integer end input: - spikesInh nS <-inhibitory spike - spikesExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -180,8 +178,8 @@ Source code update: integrate_odes() if r > 0: # refractory - r = r - 1 # decrement refractory ticks count - V_m = V_reset + r -= 1 # decrement refractory ticks count + V_m = V_reset # clamp potential elif V_m >= V_peak: r = RefractoryCounts V_m = V_reset # clamp potential @@ -202,4 +200,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.605256 \ No newline at end of file + Generated at 2022-03-28 19:04:29.432312 \ No newline at end of file diff --git a/doc/models_library/aeif_cond_alpha_characterisation.rst b/doc/models_library/aeif_cond_alpha_characterisation.rst new file mode 100644 index 000000000..065c3ec08 --- /dev/null +++ b/doc/models_library/aeif_cond_alpha_characterisation.rst @@ -0,0 +1,12 @@ +Synaptic response +----------------- + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response.png + :alt: aeif_cond_alpha_nestml + +f-I curve +--------- + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve.png + :alt: aeif_cond_alpha_nestml + diff --git a/doc/models_library/aeif_cond_exp.rst b/doc/models_library/aeif_cond_exp.rst index ec6755cf4..095285197 100644 --- a/doc/models_library/aeif_cond_exp.rst +++ b/doc/models_library/aeif_cond_exp.rst @@ -1,8 +1,8 @@ aeif_cond_exp ############# -aeif_cond_exp - Conductance based exponential integrate-and-fire neuron model +aeif_cond_exp - Conductance based exponential integrate-and-fire neuron model Description +++++++++++ @@ -11,33 +11,29 @@ aeif_cond_exp is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of truncated exponentials. -This implementation uses the embedded 4th order Runge-Kutta-Fehlberg -solver with adaptive stepsize to integrate the differential equation. - The membrane potential is given by the following differential equation: .. math:: - C dV/dt= -g_L(V-E_L)+g_L*\Delta_T*\exp((V-V_T)/\Delta_T)-g_e(t)(V-E_e) \\ - -g_i(t)(V-E_i)-w +I_e + C_m \frac{dV_m}{dt} = + -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - g_e(t)(V_m-E_e) \\ + -g_i(t)(V_m-E_i)-w +I_e and .. math:: - \tau_w * dw/dt = a(V-E_L) - W + \tau_w \frac{dw}{dt} = a(V_m-E_L) - w -Note that the spike detection threshold :math:`V_{peak}` is automatically set to -:math:`V_th+10` mV to avoid numerical instabilites that may result from -setting :math:`V_{peak}` too high. +Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. References ++++++++++ -.. [1] Brette R and Gerstner W (2005). Adaptive Exponential - Integrate-and-Fire Model as an Effective Description of Neuronal - Activity. J Neurophysiol 94:3637-3642. +.. [1] Brette R and Gerstner W (2005). Adaptive exponential + integrate-and-fire model as an effective description of neuronal + activity. Journal of Neurophysiology. 943637-3642 DOI: https://doi.org/10.1152/jn.00686.2005 @@ -47,6 +43,7 @@ See also iaf_cond_exp, aeif_cond_alpha + Parameters ++++++++++ @@ -62,16 +59,16 @@ Parameters "V_reset", "mV", "-60.0mV", "Reset Potential" "g_L", "nS", "30.0nS", "Leak Conductance" "E_L", "mV", "-70.6mV", "Leak reversal Potential (aka resting potential)" - "a", "nS", "4nS", "spike adaptation parametersSubthreshold adaptation." - "b", "pA", "80.5pA", "Spike-trigg_exred adaptation." + "a", "nS", "4nS", "spike adaptation parametersSubthreshold adaptation" + "b", "pA", "80.5pA", "Spike-triggered adaptation" "Delta_T", "mV", "2.0mV", "Slope factor" "tau_w", "ms", "144.0ms", "Adaptation time constant" "V_th", "mV", "-50.4mV", "Threshold Potential" - "V_peak", "mV", "0mV", "Spike detection threshold." - "E_ex", "mV", "0mV", "synaptic parametersExcitatory reversal Potential" - "tau_syn_ex", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "E_in", "mV", "-85.0mV", "Inhibitory reversal Potential" - "tau_syn_in", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" + "V_peak", "mV", "0mV", "Spike detection threshold" + "E_exc", "mV", "0mV", "synaptic parametersExcitatory reversal Potential" + "tau_syn_exc", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" + "E_inh", "mV", "-85.0mV", "Inhibitory reversal Potential" + "tau_syn_inh", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" "I_e", "pA", "0pA", "constant external input current" @@ -111,65 +108,65 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron aeif_cond_exp: - initial_values: + state: V_m mV = E_L # Membrane potential w pA = 0pA # Spike-adaptation current end equations: - function V_bounded mV = min(V_m,V_peak) # prevent exponential divergence - kernel g_in = exp(-1 / tau_syn_in * t) - kernel g_ex = exp(-1 / tau_syn_ex * t) - - /* Add aliases to simplify the equation definition of V_m*/ - function exp_arg real = (V_bounded - V_th) / Delta_T - function I_spike pA = g_L * Delta_T * exp(exp_arg) - function I_syn_exc pA = convolve(g_ex,spikeExc) * (V_bounded - E_ex) - function I_syn_inh pA = convolve(g_in,spikeInh) * (V_bounded - E_in) + inline V_bounded mV = min(V_m,V_peak) # prevent exponential divergence + kernel g_inh = exp(-t / tau_syn_inh) + kernel g_exc = exp(-t / tau_syn_exc) + # Add inlines to simplify the equation definition of V_m + inline exp_arg real = (V_bounded - V_th) / Delta_T + inline I_spike pA = g_L * Delta_T * exp(exp_arg) + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_bounded - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_bounded - E_inh) V_m'=(-g_L * (V_bounded - E_L) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim) / C_m w'=(a * (V_bounded - E_L) - w) / tau_w end parameters: - - /* membrane parameters*/ + # membrane parameters C_m pF = 281.0pF # Membrane Capacitance t_ref ms = 0.0ms # Refractory period V_reset mV = -60.0mV # Reset Potential g_L nS = 30.0nS # Leak Conductance E_L mV = -70.6mV # Leak reversal Potential (aka resting potential) + # spike adaptation parameters - /* spike adaptation parameters*/ - a nS = 4nS # Subthreshold adaptation. - b pA = 80.5pA # Spike-trigg_exred adaptation. + # spike adaptation parameters + a nS = 4nS # Subthreshold adaptation + b pA = 80.5pA # Spike-triggered adaptation Delta_T mV = 2.0mV # Slope factor tau_w ms = 144.0ms # Adaptation time constant V_th mV = -50.4mV # Threshold Potential - V_peak mV = 0mV # Spike detection threshold. + V_peak mV = 0mV # Spike detection threshold + # synaptic parameters - /* synaptic parameters*/ - E_ex mV = 0mV # Excitatory reversal Potential - tau_syn_ex ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - E_in mV = -85.0mV # Inhibitory reversal Potential - tau_syn_in ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse + # synaptic parameters + E_exc mV = 0mV # Excitatory reversal Potential + tau_syn_exc ms = 0.2ms # Synaptic Time Constant Excitatory Synapse + E_inh mV = -85.0mV # Inhibitory reversal Potential + tau_syn_inh ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: - - /* refractory time in steps*/ + # refractory time in steps RefractoryCounts integer = steps(t_ref) - /* counts number of tick during the refractory period*/ + # counts number of tick during the refractory period - /* counts number of tick during the refractory period*/ + # counts number of tick during the refractory period r integer end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -200,4 +197,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.193728 \ No newline at end of file + Generated at 2022-03-28 19:04:29.501988 \ No newline at end of file diff --git a/doc/models_library/aeif_cond_exp_characterisation.rst b/doc/models_library/aeif_cond_exp_characterisation.rst new file mode 100644 index 000000000..924e1ebd6 --- /dev/null +++ b/doc/models_library/aeif_cond_exp_characterisation.rst @@ -0,0 +1,12 @@ +Synaptic response +----------------- + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response.png + :alt: aeif_cond_exp_nestml + +f-I curve +--------- + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve.png + :alt: aeif_cond_exp_nestml + diff --git a/doc/models_library/hh_cond_exp_destexhe.rst b/doc/models_library/hh_cond_exp_destexhe.rst index d7f632978..97789ae56 100644 --- a/doc/models_library/hh_cond_exp_destexhe.rst +++ b/doc/models_library/hh_cond_exp_destexhe.rst @@ -1,8 +1,8 @@ hh_cond_exp_destexhe #################### -hh_cond_exp_destexhe - Hodgin Huxley based model, Traub, Destexhe and Mainen modified +hh_cond_exp_destexhe - Hodgin Huxley based model, Traub, Destexhe and Mainen modified Description +++++++++++ @@ -27,18 +27,13 @@ References .. [4] Z. Mainen, J. Joerges, J. R. Huguenard and T. J. Sejnowski (1995) A Model of Spike Initiation in Neocortical Pyramidal Neurons. Neuron -Author -++++++ - -Tobias Schulte to Brinke - - See also ++++++++ hh_cond_exp_traub + Parameters ++++++++++ @@ -57,16 +52,24 @@ Parameters "E_K", "mV", "-90.0mV", "Potassium reversal potential" "E_L", "mV", "-80.0mV", "Leak reversal Potential (aka resting potential)" "V_T", "mV", "-58.0mV", "Voltage offset that controls dynamics. For default" - "tau_syn_ex", "ms", "2.7ms", "parameters, V_T = -63mV results in a threshold around -50mV.Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "10.5ms", "Synaptic Time Constant for Inhibitory Synapse" - "I_e", "pA", "0pA", "Constant Current" - "E_ex", "mV", "0.0mV", "Excitatory synaptic reversal potential" - "E_in", "mV", "-75.0mV", "Inhibitory synaptic reversal potential" + "tau_syn_exc", "ms", "2.7ms", "parameters, V_T = -63mV results in a threshold around -50mV.Synaptic Time Constant Excitatory Synapse" + "tau_syn_inh", "ms", "10.5ms", "Synaptic Time Constant for Inhibitory Synapse" + "E_exc", "mV", "0.0mV", "Excitatory synaptic reversal potential" + "E_inh", "mV", "-75.0mV", "Inhibitory synaptic reversal potential" "g_M", "nS", "173.18nS", "Conductance of non-inactivating K+ channel" - "g_noise_ex0", "uS", "0.012uS", "Conductance OU noiseMean of the excitatory noise conductance" - "g_noise_in0", "uS", "0.057uS", "Mean of the inhibitory noise conductance" - "sigma_noise_ex", "uS", "0.003uS", "Standard deviation of the excitatory noise conductance" - "sigma_noise_in", "uS", "0.0066uS", "Standard deviation of the inhibitory noise conductance" + "g_noise_exc0", "uS", "0.012uS", "Conductance OU noiseMean of the excitatory noise conductance" + "g_noise_inh0", "uS", "0.057uS", "Mean of the inhibitory noise conductance" + "sigma_noise_exc", "uS", "0.003uS", "Standard deviation of the excitatory noise conductance" + "sigma_noise_inh", "uS", "0.0066uS", "Standard deviation of the inhibitory noise conductance" + "alpha_n_init", "1 / ms", "0.032 / (ms * mV) * (15.0mV - V_m) / (exp((15.0mV - V_m) / 5.0mV) - 1.0)", "" + "beta_n_init", "1 / ms", "0.5 / ms * exp((10.0mV - V_m) / 40.0mV)", "" + "alpha_m_init", "1 / ms", "0.32 / (ms * mV) * (13.0mV - V_m) / (exp((13.0mV - V_m) / 4.0mV) - 1.0)", "" + "beta_m_init", "1 / ms", "0.28 / (ms * mV) * (V_m - 40.0mV) / (exp((V_m - 40.0mV) / 5.0mV) - 1.0)", "" + "alpha_h_init", "1 / ms", "0.128 / ms * exp((17.0mV - V_m) / 18.0mV)", "" + "beta_h_init", "1 / ms", "(4.0 / (1.0 + exp((40.0mV - V_m) / 5.0mV))) / ms", "" + "alpha_p_init", "1 / ms", "0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp(-(V_m + 30.0mV) / 9.0mV))", "" + "beta_p_init", "1 / ms", "-0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp((V_m + 30.0mV) / 9.0mV))", "" + "I_e", "pA", "0pA", "constant external input current" @@ -79,15 +82,10 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" + "g_noise_exc", "uS", "g_noise_exc0", "" + "g_noise_inh", "uS", "g_noise_inh0", "" "V_m", "mV", "E_L", "Membrane potential" - "alpha_n_init", "1 / ms", "0.032 / (ms * mV) * (15.0mV - V_m) / (exp((15.0mV - V_m) / 5.0mV) - 1.0)", "" - "beta_n_init", "1 / ms", "0.5 / ms * exp((10.0mV - V_m) / 40.0mV)", "" - "alpha_m_init", "1 / ms", "0.32 / (ms * mV) * (13.0mV - V_m) / (exp((13.0mV - V_m) / 4.0mV) - 1.0)", "" - "beta_m_init", "1 / ms", "0.28 / (ms * mV) * (V_m - 40.0mV) / (exp((V_m - 40.0mV) / 5.0mV) - 1.0)", "" - "alpha_h_init", "1 / ms", "0.128 / ms * exp((17.0mV - V_m) / 18.0mV)", "" - "beta_h_init", "1 / ms", "(4.0 / (1.0 + exp((40.0mV - V_m) / 5.0mV))) / ms", "" - "alpha_p_init", "1 / ms", "0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp(-(V_m + 30.0mV) / 9.0mV))", "" - "beta_p_init", "1 / ms", "-0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp((V_m + 30.0mV) / 9.0mV))", "" "Act_m", "real", "alpha_m_init / (alpha_m_init + beta_m_init)", "" "Act_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "" "Inact_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "" @@ -128,55 +126,42 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron hh_cond_exp_destexhe: state: - r integer # counts number of tick during the refractory period - g_noise_ex uS = g_noise_ex0 - g_noise_in uS = g_noise_in0 - end - initial_values: + r integer = 0 # counts number of tick during the refractory period + g_noise_exc uS = g_noise_exc0 + g_noise_inh uS = g_noise_inh0 V_m mV = E_L # Membrane potential - function alpha_n_init 1/ms = 0.032 / (ms * mV) * (15.0mV - V_m) / (exp((15.0mV - V_m) / 5.0mV) - 1.0) - function beta_n_init 1/ms = 0.5 / ms * exp((10.0mV - V_m) / 40.0mV) - function alpha_m_init 1/ms = 0.32 / (ms * mV) * (13.0mV - V_m) / (exp((13.0mV - V_m) / 4.0mV) - 1.0) - function beta_m_init 1/ms = 0.28 / (ms * mV) * (V_m - 40.0mV) / (exp((V_m - 40.0mV) / 5.0mV) - 1.0) - function alpha_h_init 1/ms = 0.128 / ms * exp((17.0mV - V_m) / 18.0mV) - function beta_h_init 1/ms = (4.0 / (1.0 + exp((40.0mV - V_m) / 5.0mV))) / ms - function alpha_p_init 1/ms = 0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp(-(V_m + 30.0mV) / 9.0mV)) - function beta_p_init 1/ms = -0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp((V_m + 30.0mV) / 9.0mV)) Act_m real = alpha_m_init / (alpha_m_init + beta_m_init) Act_h real = alpha_h_init / (alpha_h_init + beta_h_init) Inact_n real = alpha_n_init / (alpha_n_init + beta_n_init) Noninact_p real = alpha_p_init / (alpha_p_init + beta_p_init) end equations: - - /* synapses: exponential conductance*/ - kernel g_in = exp(-1 / tau_syn_in * t) - kernel g_ex = exp(-1 / tau_syn_ex * t) - - /* Add aliases to simplify the equation definition of V_m*/ - function I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * (V_m - E_Na) - function I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - function I_M pA = g_M * Noninact_p * (V_m - E_K) - function I_noise pA = (g_noise_ex * (V_m - E_ex) + g_noise_in * (V_m - E_in)) - function I_syn_exc pA = convolve(g_ex,spikeExc) * (V_m - E_ex) - function I_syn_inh pA = convolve(g_in,spikeInh) * (V_m - E_in) + # synapses: exponential conductance + kernel g_inh = exp(-t / tau_syn_inh) + kernel g_exc = exp(-t / tau_syn_exc) + # Add aliases to simplify the equation definition of V_m + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * (V_m - E_Na) + inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + inline I_M pA = g_M * Noninact_p * (V_m - E_K) + inline I_noise pA = (g_noise_exc * (V_m - E_exc) + g_noise_inh * (V_m - E_inh)) + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) V_m'=(-I_Na - I_K - I_M - I_L - I_syn_exc - I_syn_inh + I_e + I_stim - I_noise) / C_m - - /* channel dynamics*/ - function V_rel mV = V_m - V_T - function alpha_n 1/ms = 0.032 / (ms * mV) * (15.0mV - V_rel) / (exp((15.0mV - V_rel) / 5.0mV) - 1.0) - function beta_n 1/ms = 0.5 / ms * exp((10.0mV - V_rel) / 40.0mV) - function alpha_m 1/ms = 0.32 / (ms * mV) * (13.0mV - V_rel) / (exp((13.0mV - V_rel) / 4.0mV) - 1.0) - function beta_m 1/ms = 0.28 / (ms * mV) * (V_rel - 40.0mV) / (exp((V_rel - 40.0mV) / 5.0mV) - 1.0) - function alpha_h 1/ms = 0.128 / ms * exp((17.0mV - V_rel) / 18.0mV) - function beta_h 1/ms = (4.0 / (1.0 + exp((40.0mV - V_rel) / 5.0mV))) / ms - function alpha_p 1/ms = 0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp(-(V_m + 30.0mV) / 9.0mV)) - function beta_p 1/ms = -0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp((V_m + 30.0mV) / 9.0mV)) + # channel dynamics + inline V_rel mV = V_m - V_T + inline alpha_n 1/ms = 0.032 / (ms * mV) * (15.0mV - V_rel) / (exp((15.0mV - V_rel) / 5.0mV) - 1.0) + inline beta_n 1/ms = 0.5 / ms * exp((10.0mV - V_rel) / 40.0mV) + inline alpha_m 1/ms = 0.32 / (ms * mV) * (13.0mV - V_rel) / (exp((13.0mV - V_rel) / 4.0mV) - 1.0) + inline beta_m 1/ms = 0.28 / (ms * mV) * (V_rel - 40.0mV) / (exp((V_rel - 40.0mV) / 5.0mV) - 1.0) + inline alpha_h 1/ms = 0.128 / ms * exp((17.0mV - V_rel) / 18.0mV) + inline beta_h 1/ms = (4.0 / (1.0 + exp((40.0mV - V_rel) / 5.0mV))) / ms + inline alpha_p 1/ms = 0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp(-(V_m + 30.0mV) / 9.0mV)) + inline beta_p 1/ms = -0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp((V_m + 30.0mV) / 9.0mV)) Act_m'=(alpha_m - (alpha_m + beta_m) * Act_m) Act_h'=(alpha_h - (alpha_h + beta_h) * Act_h) Inact_n'=(alpha_n - (alpha_n + beta_n) * Inact_n) @@ -192,32 +177,42 @@ Source code E_K mV = -90.0mV # Potassium reversal potential E_L mV = -80.0mV # Leak reversal Potential (aka resting potential) V_T mV = -58.0mV # Voltage offset that controls dynamics. For default - /* parameters, V_T = -63mV results in a threshold around -50mV.*/ - - /* parameters, V_T = -63mV results in a threshold around -50mV.*/ - tau_syn_ex ms = 2.7ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 10.5ms # Synaptic Time Constant for Inhibitory Synapse - I_e pA = 0pA # Constant Current - E_ex mV = 0.0mV # Excitatory synaptic reversal potential - E_in mV = -75.0mV # Inhibitory synaptic reversal potential - g_M nS = 173.18nS # Conductance of non-inactivating K+ channel + # parameters, V_T = -63mV results in a threshold around -50mV. - /* Conductance OU noise*/ - g_noise_ex0 uS = 0.012uS # Mean of the excitatory noise conductance - g_noise_in0 uS = 0.057uS # Mean of the inhibitory noise conductance - sigma_noise_ex uS = 0.003uS # Standard deviation of the excitatory noise conductance - sigma_noise_in uS = 0.0066uS # Standard deviation of the inhibitory noise conductance + # parameters, V_T = -63mV results in a threshold around -50mV. + tau_syn_exc ms = 2.7ms # Synaptic Time Constant Excitatory Synapse + tau_syn_inh ms = 10.5ms # Synaptic Time Constant for Inhibitory Synapse + E_exc mV = 0.0mV # Excitatory synaptic reversal potential + E_inh mV = -75.0mV # Inhibitory synaptic reversal potential + g_M nS = 173.18nS # Conductance of non-inactivating K+ channel + # Conductance OU noise + + # Conductance OU noise + g_noise_exc0 uS = 0.012uS # Mean of the excitatory noise conductance + g_noise_inh0 uS = 0.057uS # Mean of the inhibitory noise conductance + sigma_noise_exc uS = 0.003uS # Standard deviation of the excitatory noise conductance + sigma_noise_inh uS = 0.0066uS # Standard deviation of the inhibitory noise conductance + alpha_n_init 1/ms = 0.032 / (ms * mV) * (15.0mV - V_m) / (exp((15.0mV - V_m) / 5.0mV) - 1.0) + beta_n_init 1/ms = 0.5 / ms * exp((10.0mV - V_m) / 40.0mV) + alpha_m_init 1/ms = 0.32 / (ms * mV) * (13.0mV - V_m) / (exp((13.0mV - V_m) / 4.0mV) - 1.0) + beta_m_init 1/ms = 0.28 / (ms * mV) * (V_m - 40.0mV) / (exp((V_m - 40.0mV) / 5.0mV) - 1.0) + alpha_h_init 1/ms = 0.128 / ms * exp((17.0mV - V_m) / 18.0mV) + beta_h_init 1/ms = (4.0 / (1.0 + exp((40.0mV - V_m) / 5.0mV))) / ms + alpha_p_init 1/ms = 0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp(-(V_m + 30.0mV) / 9.0mV)) + beta_p_init 1/ms = -0.0001 / (ms * mV) * (V_m + 30.0mV) / (1.0 - exp((V_m + 30.0mV) / 9.0mV)) + # constant external input current + I_e pA = 0pA end internals: RefractoryCounts integer = 20 - D_ex uS**2/ms = 2 * sigma_noise_ex ** 2 / tau_syn_ex - D_in uS**2/ms = 2 * sigma_noise_in ** 2 / tau_syn_in - A_ex uS = ((D_ex * tau_syn_ex / 2) * (1 - exp(-2 * resolution() / tau_syn_ex))) ** 0.5 - A_in uS = ((D_in * tau_syn_in / 2) * (1 - exp(-2 * resolution() / tau_syn_in))) ** 0.5 + D_exc uS**2/ms = 2 * sigma_noise_exc ** 2 / tau_syn_exc + D_inh uS**2/ms = 2 * sigma_noise_inh ** 2 / tau_syn_inh + A_exc uS = ((D_exc * tau_syn_exc / 2) * (1 - exp(-2 * resolution() / tau_syn_exc))) ** 0.5 + A_inh uS = ((D_inh * tau_syn_inh / 2) * (1 - exp(-2 * resolution() / tau_syn_inh))) ** 0.5 end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -226,10 +221,9 @@ Source code update: U_old mV = V_m integrate_odes() - g_noise_ex = g_noise_ex0 + (g_noise_ex - g_noise_ex0) * exp(-resolution() / tau_syn_ex) + A_ex * random_normal(0,1) - g_noise_in = g_noise_in0 + (g_noise_in - g_noise_in0) * exp(-resolution() / tau_syn_in) + A_in * random_normal(0,1) - - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + g_noise_exc = g_noise_exc0 + (g_noise_exc - g_noise_exc0) * exp(-resolution() / tau_syn_exc) + A_exc * random_normal(0,1) + g_noise_inh = g_noise_inh0 + (g_noise_inh - g_noise_inh0) * exp(-resolution() / tau_syn_inh) + A_inh * random_normal(0,1) + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: r -= 1 elif V_m > V_T + 30mV and U_old > V_m: @@ -250,4 +244,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.480312 + Generated at 2022-03-28 19:04:29.925703 \ No newline at end of file diff --git a/doc/models_library/hh_cond_exp_traub.rst b/doc/models_library/hh_cond_exp_traub.rst index e2ff17509..de1a91311 100644 --- a/doc/models_library/hh_cond_exp_traub.rst +++ b/doc/models_library/hh_cond_exp_traub.rst @@ -1,8 +1,8 @@ hh_cond_exp_traub ################# -hh_cond_exp_traub - Hodgkin-Huxley model for Brette et al (2007) review +hh_cond_exp_traub - Hodgkin-Huxley model for Brette et al (2007) review Description +++++++++++ @@ -33,7 +33,6 @@ spike, it is essential to choose a sufficiently long refractory period. Traub and Miles used :math:`t_{ref} = 3` ms [2, p 118], while we used :math:`t_{ref} = 2` ms in [2]_. - References ++++++++++ @@ -51,11 +50,6 @@ See also hh_psc_alpha -Author -++++++ - -Schrader - Parameters ++++++++++ @@ -67,19 +61,25 @@ Parameters :widths: auto - "g_Na", "nS", "20000.0nS", "Na Conductance" - "g_K", "nS", "6000.0nS", "K Conductance" + "g_Na", "nS", "20000nS", "Na Conductance" + "g_K", "nS", "6000nS", "K Conductance" "g_L", "nS", "10nS", "Leak Conductance" - "C_m", "pF", "200.0pF", "Membrane Capacitance" + "C_m", "pF", "200pF", "Membrane Capacitance" "E_Na", "mV", "50mV", "Reversal potentials" - "E_K", "mV", "-90.0mV", "Potassium reversal potential" - "E_L", "mV", "-60.0mV", "Leak reversal Potential (aka resting potential)" - "V_T", "mV", "-63.0mV", "Voltage offset that controls dynamics. For default" - "tau_syn_ex", "ms", "5.0ms", "parameters, V_T = -63 mV results in a threshold around -50 mV.Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "10.0ms", "Synaptic Time Constant for Inhibitory Synapse" - "t_ref", "ms", "2.0ms", "Refractory period" - "E_ex", "mV", "0.0mV", "Excitatory synaptic reversal potential" - "E_in", "mV", "-80.0mV", "Inhibitory synaptic reversal potential" + "E_K", "mV", "-90mV", "Potassium reversal potential" + "E_L", "mV", "-60mV", "Leak reversal potential (aka resting potential)" + "V_T", "mV", "-63mV", "Voltage offset that controls dynamics. For default" + "tau_syn_exc", "ms", "5ms", "parameters, V_T = -63 mV results in a threshold around -50 mV.Synaptic time constant of excitatory synapse" + "tau_syn_inh", "ms", "10ms", "Synaptic time constant of inhibitory synapse" + "t_ref", "ms", "2ms", "Refractory period" + "E_exc", "mV", "0mV", "Excitatory synaptic reversal potential" + "E_inh", "mV", "-80mV", "Inhibitory synaptic reversal potential" + "alpha_n_init", "1 / ms", "0.032 / (ms * mV) * (15.0mV - E_L) / (exp((15.0mV - E_L) / 5.0mV) - 1.0)", "" + "beta_n_init", "1 / ms", "0.5 / ms * exp((10.0mV - E_L) / 40.0mV)", "" + "alpha_m_init", "1 / ms", "0.32 / (ms * mV) * (13.0mV - E_L) / (exp((13.0mV - E_L) / 4.0mV) - 1.0)", "" + "beta_m_init", "1 / ms", "0.28 / (ms * mV) * (E_L - 40.0mV) / (exp((E_L - 40.0mV) / 5.0mV) - 1.0)", "" + "alpha_h_init", "1 / ms", "0.128 / ms * exp((17.0mV - E_L) / 18.0mV)", "" + "beta_h_init", "1 / ms", "(4.0 / (1.0 + exp((40.0mV - E_L) / 5.0mV))) / ms", "" "I_e", "pA", "0pA", "constant external input current" @@ -93,13 +93,8 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" "V_m", "mV", "E_L", "Membrane potential" - "alpha_n_init", "1 / ms", "0.032 / (ms * mV) * (15.0mV - V_m) / (exp((15.0mV - V_m) / 5.0mV) - 1.0)", "" - "beta_n_init", "1 / ms", "0.5 / ms * exp((10.0mV - V_m) / 40.0mV)", "" - "alpha_m_init", "1 / ms", "0.32 / (ms * mV) * (13.0mV - V_m) / (exp((13.0mV - V_m) / 4.0mV) - 1.0)", "" - "beta_m_init", "1 / ms", "0.28 / (ms * mV) * (V_m - 40.0mV) / (exp((V_m - 40.0mV) / 5.0mV) - 1.0)", "" - "alpha_h_init", "1 / ms", "0.128 / ms * exp((17.0mV - V_m) / 18.0mV)", "" - "beta_h_init", "1 / ms", "(4.0 / (1.0 + exp((40.0mV - V_m) / 5.0mV))) / ms", "" "Act_m", "real", "alpha_m_init / (alpha_m_init + beta_m_init)", "" "Act_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "" "Inact_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "" @@ -135,78 +130,72 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron hh_cond_exp_traub: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # Membrane potential - function alpha_n_init 1/ms = 0.032 / (ms * mV) * (15.0mV - V_m) / (exp((15.0mV - V_m) / 5.0mV) - 1.0) - function beta_n_init 1/ms = 0.5 / ms * exp((10.0mV - V_m) / 40.0mV) - function alpha_m_init 1/ms = 0.32 / (ms * mV) * (13.0mV - V_m) / (exp((13.0mV - V_m) / 4.0mV) - 1.0) - function beta_m_init 1/ms = 0.28 / (ms * mV) * (V_m - 40.0mV) / (exp((V_m - 40.0mV) / 5.0mV) - 1.0) - function alpha_h_init 1/ms = 0.128 / ms * exp((17.0mV - V_m) / 18.0mV) - function beta_h_init 1/ms = (4.0 / (1.0 + exp((40.0mV - V_m) / 5.0mV))) / ms Act_m real = alpha_m_init / (alpha_m_init + beta_m_init) Act_h real = alpha_h_init / (alpha_h_init + beta_h_init) Inact_n real = alpha_n_init / (alpha_n_init + beta_n_init) end equations: - - /* synapses: exponential conductance*/ - kernel g_in = exp(-1 / tau_syn_in * t) - kernel g_ex = exp(-1 / tau_syn_ex * t) - - /* Add aliases to simplify the equation definition of V_m*/ - function I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * (V_m - E_Na) - function I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - function I_syn_exc pA = convolve(g_ex,spikeExc) * (V_m - E_ex) - function I_syn_inh pA = convolve(g_in,spikeInh) * (V_m - E_in) + # synapses: exponential conductance + kernel g_inh = exp(-t / tau_syn_inh) + kernel g_exc = exp(-t / tau_syn_exc) + # Add aliases to simplify the equation definition of V_m + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * (V_m - E_Na) + inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) V_m'=(-I_Na - I_K - I_L - I_syn_exc - I_syn_inh + I_e + I_stim) / C_m - - /* channel dynamics*/ - function V_rel mV = V_m - V_T - function alpha_n 1/ms = 0.032 / (ms * mV) * (15.0mV - V_rel) / (exp((15.0mV - V_rel) / 5.0mV) - 1.0) - function beta_n 1/ms = 0.5 / ms * exp((10.0mV - V_rel) / 40.0mV) - function alpha_m 1/ms = 0.32 / (ms * mV) * (13.0mV - V_rel) / (exp((13.0mV - V_rel) / 4.0mV) - 1.0) - function beta_m 1/ms = 0.28 / (ms * mV) * (V_rel - 40.0mV) / (exp((V_rel - 40.0mV) / 5.0mV) - 1.0) - function alpha_h 1/ms = 0.128 / ms * exp((17.0mV - V_rel) / 18.0mV) - function beta_h 1/ms = (4.0 / (1.0 + exp((40.0mV - V_rel) / 5.0mV))) / ms + # channel dynamics + inline V_rel mV = V_m - V_T + inline alpha_n 1/ms = 0.032 / (ms * mV) * (15.0mV - V_rel) / (exp((15.0mV - V_rel) / 5.0mV) - 1.0) + inline beta_n 1/ms = 0.5 / ms * exp((10.0mV - V_rel) / 40.0mV) + inline alpha_m 1/ms = 0.32 / (ms * mV) * (13.0mV - V_rel) / (exp((13.0mV - V_rel) / 4.0mV) - 1.0) + inline beta_m 1/ms = 0.28 / (ms * mV) * (V_rel - 40.0mV) / (exp((V_rel - 40.0mV) / 5.0mV) - 1.0) + inline alpha_h 1/ms = 0.128 / ms * exp((17.0mV - V_rel) / 18.0mV) + inline beta_h 1/ms = (4.0 / (1.0 + exp((40.0mV - V_rel) / 5.0mV))) / ms Act_m'=(alpha_m - (alpha_m + beta_m) * Act_m) Act_h'=(alpha_h - (alpha_h + beta_h) * Act_h) Inact_n'=(alpha_n - (alpha_n + beta_n) * Inact_n) end parameters: - g_Na nS = 20000.0nS # Na Conductance - g_K nS = 6000.0nS # K Conductance + g_Na nS = 20000nS # Na Conductance + g_K nS = 6000nS # K Conductance g_L nS = 10nS # Leak Conductance - C_m pF = 200.0pF # Membrane Capacitance + C_m pF = 200pF # Membrane Capacitance E_Na mV = 50mV # Reversal potentials - E_K mV = -90.0mV # Potassium reversal potential - E_L mV = -60.0mV # Leak reversal Potential (aka resting potential) - V_T mV = -63.0mV # Voltage offset that controls dynamics. For default - /* parameters, V_T = -63 mV results in a threshold around -50 mV.*/ - - /* parameters, V_T = -63 mV results in a threshold around -50 mV.*/ - tau_syn_ex ms = 5.0ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 10.0ms # Synaptic Time Constant for Inhibitory Synapse - t_ref ms = 2.0ms # Refractory period - E_ex mV = 0.0mV # Excitatory synaptic reversal potential - E_in mV = -80.0mV # Inhibitory synaptic reversal potential - - /* constant external input current*/ + E_K mV = -90mV # Potassium reversal potential + E_L mV = -60mV # Leak reversal potential (aka resting potential) + V_T mV = -63mV # Voltage offset that controls dynamics. For default + # parameters, V_T = -63 mV results in a threshold around -50 mV. + + # parameters, V_T = -63 mV results in a threshold around -50 mV. + tau_syn_exc ms = 5ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 10ms # Synaptic time constant of inhibitory synapse + t_ref ms = 2ms # Refractory period + E_exc mV = 0mV # Excitatory synaptic reversal potential + E_inh mV = -80mV # Inhibitory synaptic reversal potential + alpha_n_init 1/ms = 0.032 / (ms * mV) * (15.0mV - E_L) / (exp((15.0mV - E_L) / 5.0mV) - 1.0) + beta_n_init 1/ms = 0.5 / ms * exp((10.0mV - E_L) / 40.0mV) + alpha_m_init 1/ms = 0.32 / (ms * mV) * (13.0mV - E_L) / (exp((13.0mV - E_L) / 4.0mV) - 1.0) + beta_m_init 1/ms = 0.28 / (ms * mV) * (E_L - 40.0mV) / (exp((E_L - 40.0mV) / 5.0mV) - 1.0) + alpha_h_init 1/ms = 0.128 / ms * exp((17.0mV - E_L) / 18.0mV) + beta_h_init 1/ms = (4.0 / (1.0 + exp((40.0mV - E_L) / 5.0mV))) / ms + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -215,8 +204,7 @@ Source code update: U_old mV = V_m integrate_odes() - - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: r -= 1 elif V_m > V_T + 30mV and U_old > V_m: @@ -237,4 +225,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.758646 \ No newline at end of file + Generated at 2022-03-28 19:04:29.349088 \ No newline at end of file diff --git a/doc/models_library/hh_psc_alpha.rst b/doc/models_library/hh_psc_alpha.rst index c3bce0f71..e46db6a37 100644 --- a/doc/models_library/hh_psc_alpha.rst +++ b/doc/models_library/hh_psc_alpha.rst @@ -1,8 +1,8 @@ hh_psc_alpha ############ -hh_psc_alpha - Hodgkin-Huxley neuron model +hh_psc_alpha - Hodgkin-Huxley neuron model Description +++++++++++ @@ -46,6 +46,7 @@ See also hh_cond_exp_traub + Parameters ++++++++++ @@ -56,16 +57,23 @@ Parameters :widths: auto - "t_ref", "ms", "2.0ms", "Refractory period" - "g_Na", "nS", "12000.0nS", "Sodium peak conductance" - "g_K", "nS", "3600.0nS", "Potassium peak conductance" + "t_ref", "ms", "2ms", "Refractory period" + "g_Na", "nS", "12000nS", "Sodium peak conductance" + "g_K", "nS", "3600nS", "Potassium peak conductance" "g_L", "nS", "30nS", "Leak conductance" - "C_m", "pF", "100.0pF", "Membrane Capacitance" + "C_m", "pF", "100pF", "Membrane Capacitance" "E_Na", "mV", "50mV", "Sodium reversal potential" - "E_K", "mV", "-77.0mV", "Potassium reversal potentia" + "E_K", "mV", "-77mV", "Potassium reversal potential" "E_L", "mV", "-54.402mV", "Leak reversal Potential (aka resting potential)" - "tau_syn_ex", "ms", "0.2ms", "Rise time of the excitatory synaptic alpha function i" - "tau_syn_in", "ms", "2.0ms", "Rise time of the inhibitory synaptic alpha function" + "tau_syn_exc", "ms", "0.2ms", "Rise time of the excitatory synaptic alpha function" + "tau_syn_inh", "ms", "2ms", "Rise time of the inhibitory synaptic alpha function" + "V_m_init", "mV", "-65mV", "Initial membrane potential" + "alpha_n_init", "real", "(0.01 * (V_m_init / mV + 55.0)) / (1.0 - exp(-(V_m_init / mV + 55.0) / 10.0))", "" + "beta_n_init", "real", "0.125 * exp(-(V_m_init / mV + 65.0) / 80.0)", "" + "alpha_m_init", "real", "(0.1 * (V_m_init / mV + 40.0)) / (1.0 - exp(-(V_m_init / mV + 40.0) / 10.0))", "" + "beta_m_init", "real", "4.0 * exp(-(V_m_init / mV + 65.0) / 18.0)", "" + "alpha_h_init", "real", "0.07 * exp(-(V_m_init / mV + 65.0) / 20.0)", "" + "beta_h_init", "real", "1.0 / (1.0 + exp(-(V_m_init / mV + 35.0) / 10.0))", "" "I_e", "pA", "0pA", "constant external input current" @@ -79,13 +87,8 @@ State variables :widths: auto - "V_m", "mV", "-65.0mV", "Membrane potential" - "alpha_n_init", "real", "(0.01 * (V_m / mV + 55.0)) / (1.0 - exp(-(V_m / mV + 55.0) / 10.0))", "" - "beta_n_init", "real", "0.125 * exp(-(V_m / mV + 65.0) / 80.0)", "" - "alpha_m_init", "real", "(0.1 * (V_m / mV + 40.0)) / (1.0 - exp(-(V_m / mV + 40.0) / 10.0))", "" - "beta_m_init", "real", "4.0 * exp(-(V_m / mV + 65.0) / 18.0)", "" - "alpha_h_init", "real", "0.07 * exp(-(V_m / mV + 65.0) / 20.0)", "" - "beta_h_init", "real", "1.0 / (1.0 + exp(-(V_m / mV + 35.0) / 10.0))", "" + "r", "integer", "0", "number of steps in the current refractory phase" + "V_m", "mV", "V_m_init", "Membrane potential" "Act_m", "real", "alpha_m_init / (alpha_m_init + beta_m_init)", "Activation variable m for Na" "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "Inactivation variable h for Na" "Act_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "Activation variable n for K" @@ -99,10 +102,6 @@ Equations -.. math:: - \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn,inh} + I_{syn,exc}) } \right) - - .. math:: \frac{ dAct_{n} } { dt }= \frac 1 { \mathrm{ms} } \left( { (\alpha_{n} \cdot (1 - Act_{n}) - \beta_{n} \cdot Act_{n}) } \right) @@ -115,79 +114,81 @@ Equations \frac{ dInact_{h} } { dt }= \frac 1 { \mathrm{ms} } \left( { (\alpha_{h} \cdot (1 - Inact_{h}) - \beta_{h} \cdot Inact_{h}) } \right) +.. math:: + \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn,exc} - I_{syn,inh}) } \right) + + Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron hh_psc_alpha: state: - r integer # number of steps in the current refractory phase - end - initial_values: - V_m mV = -65.0mV # Membrane potential - function alpha_n_init real = (0.01 * (V_m / mV + 55.0)) / (1.0 - exp(-(V_m / mV + 55.0) / 10.0)) - function beta_n_init real = 0.125 * exp(-(V_m / mV + 65.0) / 80.0) - function alpha_m_init real = (0.1 * (V_m / mV + 40.0)) / (1.0 - exp(-(V_m / mV + 40.0) / 10.0)) - function beta_m_init real = 4.0 * exp(-(V_m / mV + 65.0) / 18.0) - function alpha_h_init real = 0.07 * exp(-(V_m / mV + 65.0) / 20.0) - function beta_h_init real = 1.0 / (1.0 + exp(-(V_m / mV + 35.0) / 10.0)) + r integer = 0 # number of steps in the current refractory phase + V_m mV = V_m_init # Membrane potential Act_m real = alpha_m_init / (alpha_m_init + beta_m_init) # Activation variable m for Na Inact_h real = alpha_h_init / (alpha_h_init + beta_h_init) # Inactivation variable h for Na Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) # Activation variable n for K end equations: - - /* synapses: alpha functions*/ - kernel I_syn_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel I_syn_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - function I_syn_exc pA = convolve(I_syn_ex,spikeExc) - function I_syn_inh pA = convolve(I_syn_in,spikeInh) - function I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * (V_m - E_Na) - function I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn_inh + I_syn_exc) / C_m - - /* Act_n*/ - function alpha_n real = (0.01 * (V_m / mV + 55.0)) / (1.0 - exp(-(V_m / mV + 55.0) / 10.0)) - function beta_n real = 0.125 * exp(-(V_m / mV + 65.0) / 80.0) + # synapses: alpha functions + kernel K_syn_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel K_syn_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + inline I_syn_exc pA = convolve(K_syn_exc,exc_spikes) + inline I_syn_inh pA = convolve(K_syn_inh,inh_spikes) + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * (V_m - E_Na) + inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + # Act_n + inline alpha_n real = (0.01 * (V_m / mV + 55.0)) / (1.0 - exp(-(V_m / mV + 55.0) / 10.0)) + inline beta_n real = 0.125 * exp(-(V_m / mV + 65.0) / 80.0) Act_n'=(alpha_n * (1 - Act_n) - beta_n * Act_n) / ms # n-variable + # Act_m - /* Act_m*/ - function alpha_m real = (0.1 * (V_m / mV + 40.0)) / (1.0 - exp(-(V_m / mV + 40.0) / 10.0)) - function beta_m real = 4.0 * exp(-(V_m / mV + 65.0) / 18.0) + # Act_m + inline alpha_m real = (0.1 * (V_m / mV + 40.0)) / (1.0 - exp(-(V_m / mV + 40.0) / 10.0)) + inline beta_m real = 4.0 * exp(-(V_m / mV + 65.0) / 18.0) Act_m'=(alpha_m * (1 - Act_m) - beta_m * Act_m) / ms # m-variable + # Inact_h' - /* Inact_h'*/ - function alpha_h real = 0.07 * exp(-(V_m / mV + 65.0) / 20.0) - function beta_h real = 1.0 / (1.0 + exp(-(V_m / mV + 35.0) / 10.0)) + # Inact_h' + inline alpha_h real = 0.07 * exp(-(V_m / mV + 65.0) / 20.0) + inline beta_h real = 1.0 / (1.0 + exp(-(V_m / mV + 35.0) / 10.0)) Inact_h'=(alpha_h * (1 - Inact_h) - beta_h * Inact_h) / ms # h-variable + V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn_exc - I_syn_inh) / C_m end parameters: - t_ref ms = 2.0ms # Refractory period - g_Na nS = 12000.0nS # Sodium peak conductance - g_K nS = 3600.0nS # Potassium peak conductance + t_ref ms = 2ms # Refractory period + g_Na nS = 12000nS # Sodium peak conductance + g_K nS = 3600nS # Potassium peak conductance g_L nS = 30nS # Leak conductance - C_m pF = 100.0pF # Membrane Capacitance + C_m pF = 100pF # Membrane Capacitance E_Na mV = 50mV # Sodium reversal potential - E_K mV = -77.0mV # Potassium reversal potentia + E_K mV = -77mV # Potassium reversal potential E_L mV = -54.402mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 0.2ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 2.0ms # Rise time of the inhibitory synaptic alpha function - - /* constant external input current*/ + tau_syn_exc ms = 0.2ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 2ms # Rise time of the inhibitory synaptic alpha function + V_m_init mV = -65mV # Initial membrane potential + alpha_n_init real = (0.01 * (V_m_init / mV + 55.0)) / (1.0 - exp(-(V_m_init / mV + 55.0) / 10.0)) + beta_n_init real = 0.125 * exp(-(V_m_init / mV + 65.0) / 80.0) + alpha_m_init real = (0.1 * (V_m_init / mV + 40.0)) / (1.0 - exp(-(V_m_init / mV + 40.0) / 10.0)) + beta_m_init real = 4.0 * exp(-(V_m_init / mV + 65.0) / 18.0) + alpha_h_init real = 0.07 * exp(-(V_m_init / mV + 65.0) / 20.0) + beta_h_init real = 1.0 / (1.0 + exp(-(V_m_init / mV + 35.0) / 10.0)) + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - spikeInh pA <-inhibitory spike - spikeExc pA <-excitatory spike + inh_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike I_stim pA <-current end @@ -196,9 +197,9 @@ Source code update: U_old mV = V_m integrate_odes() - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: # is refractory? r -= 1 elif V_m > 0mV and U_old > V_m: @@ -219,4 +220,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.992474 \ No newline at end of file + Generated at 2022-03-28 19:04:29.257544 \ No newline at end of file diff --git a/doc/models_library/hill_tononi.rst b/doc/models_library/hill_tononi.rst index a8d9a5f4e..6f9d15232 100644 --- a/doc/models_library/hill_tononi.rst +++ b/doc/models_library/hill_tononi.rst @@ -1,8 +1,8 @@ hill_tononi ########### -hill_tononi - Neuron model after Hill & Tononi (2005) +hill_tononi - Neuron model after Hill & Tononi (2005) Description +++++++++++ @@ -36,10 +36,6 @@ References in cortical pyramidal neurons. Journal of Neurophysiology 89:2778-2783. DOI: https://doi.org/10.1152/jn.01038.2002 -Author -++++++ - -Hans Ekkehard Plesser Parameters @@ -101,20 +97,22 @@ State variables :widths: auto + "r_potassium", "integer", "0", "" + "g_spike", "boolean", "false", "" "V_m", "mV", "(g_NaL * E_Na + g_KL * E_K) / (g_NaL + g_KL)", "membrane potential" "Theta", "mV", "Theta_eq", "Threshold" - "g_AMPA", "nS", "0.0nS", "" - "g_NMDA", "nS", "0.0nS", "" - "g_GABAA", "nS", "0.0nS", "" - "g_GABAB", "nS", "0.0nS", "" "IKNa_D", "nS", "0.0nS", "" - "g_AMPA__d", "nS / ms", "0.0nS / ms", "" - "g_NMDA__d", "nS / ms", "0.0nS / ms", "" - "g_GABAA__d", "nS / ms", "0.0nS / ms", "" - "g_GABAB__d", "nS / ms", "0.0nS / ms", "" - "IT_m", "real", "0.0", "" - "IT_h", "real", "0.0", "" - "Ih_m", "real", "0.0", "" + "IT_m", "nS", "0.0nS", "" + "IT_h", "nS", "0.0nS", "" + "Ih_m", "nS", "0.0nS", "" + "g_AMPA", "real", "0", "" + "g_NMDA", "real", "0", "" + "g_GABAA", "real", "0", "" + "g_GABAB", "real", "0", "" + "g_AMPA$", "real", "AMPAInitialValue", "" + "g_NMDA$", "real", "NMDAInitialValue", "" + "g_GABAA$", "real", "GABA_AInitialValue", "" + "g_GABAB$", "real", "GABA_BInitialValue", "" @@ -126,7 +124,7 @@ Equations .. math:: - \frac{ dV_{m} } { dt }= \frac 1 { \mathrm{nF} } \left( { (\frac 1 { \Tau_{m} } \left( { (I_{Na} + I_{K} + I_{syn} + I_{NaP} + I_{KNa} + I_{T} + I_{h} + I_{e} + I_{stim}) } \right) + \frac{ I_{spike} } { (\mathrm{ms} \cdot \mathrm{mV}) }) \cdot \mathrm{s} } \right) + \frac{ dV_{m} } { dt }= \frac 1 { \mathrm{nF} } \left( { (\frac 1 { \Tau_{m} } \left( { (I_{Na} + I_{K} + I_{syn} + I_{NaP} + I_{KNa} + I_{T} + I_{h} + I_{e} + I_{stim}) } \right) + \frac{ I_{spike} \cdot \mathrm{pA} } { (\mathrm{ms} \cdot \mathrm{mV}) }) \cdot \mathrm{s} } \right) .. math:: @@ -138,47 +136,15 @@ Equations .. math:: - \frac{ dIT_{m} } { dt }= \frac{ (m_{\infty,T} - IT_{m}) } { \tau_{m,T} } - - -.. math:: - \frac{ dIT_{h} } { dt }= \frac{ (h_{\infty,T} - IT_{h}) } { \tau_{h,T} } - - -.. math:: - \frac{ dIh_{m} } { dt }= \frac{ (m_{\infty,h} - Ih_{m}) } { \tau_{m,h} } + \frac{ dIT_{m} } { dt }= \frac 1 { \mathrm{ms} } \left( { \frac 1 { \tau_{m,T} } \left( { (m_{\infty,T} \cdot \mathrm{nS} - IT_{m}) } \right) } \right) .. math:: - \frac{ dg_{AMPA,,d} } { dt }= \frac{ -g_{AMPA,,d} } { AMPA_{\Tau,1} } + \frac{ dIT_{h} } { dt }= \frac 1 { \mathrm{ms} } \left( { \frac 1 { \tau_{h,T} } \left( { (h_{\infty,T} \cdot \mathrm{nS} - IT_{h}) } \right) } \right) .. math:: - \frac{ dg_{AMPA} } { dt }= g_{AMPA,,d} - \frac{ g_{AMPA} } { AMPA_{\Tau,2} } - - -.. math:: - \frac{ dg_{NMDA,,d} } { dt }= \frac{ -g_{NMDA,,d} } { NMDA_{\Tau,1} } - - -.. math:: - \frac{ dg_{NMDA} } { dt }= g_{NMDA,,d} - \frac{ g_{NMDA} } { NMDA_{\Tau,2} } - - -.. math:: - \frac{ dg_{GABAA,,d} } { dt }= \frac{ -g_{GABAA,,d} } { GABA_{A,\Tau,1} } - - -.. math:: - \frac{ dg_{GABAA} } { dt }= g_{GABAA,,d} - \frac{ g_{GABAA} } { GABA_{A,\Tau,2} } - - -.. math:: - \frac{ dg_{GABAB,,d} } { dt }= \frac{ -g_{GABAB,,d} } { GABA_{B,\Tau,1} } - - -.. math:: - \frac{ dg_{GABAB} } { dt }= g_{GABAB,,d} - \frac{ g_{GABAB} } { GABA_{B,\Tau,2} } + \frac{ dIh_{m} } { dt }= \frac 1 { \mathrm{ms} } \left( { \frac 1 { \tau_{m,h} } \left( { (m_{\infty,h} \cdot \mathrm{nS} - Ih_{m}) } \right) } \right) @@ -187,93 +153,87 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron hill_tononi: state: - r_potassium integer + r_potassium integer = 0 g_spike boolean = false - end - initial_values: V_m mV = (g_NaL * E_Na + g_KL * E_K) / (g_NaL + g_KL) # membrane potential Theta mV = Theta_eq # Threshold - g_AMPA,g_NMDA,g_GABAA,g_GABAB,IKNa_D nS = 0.0nS - g_AMPA__d,g_NMDA__d,g_GABAA__d,g_GABAB__d nS/ms = 0.0nS / ms - IT_m,IT_h,Ih_m real = 0.0 + IKNa_D,IT_m,IT_h,Ih_m nS = 0.0nS + g_AMPA real = 0 + g_NMDA real = 0 + g_GABAA real = 0 + g_GABAB real = 0 + g_AMPA$ real = AMPAInitialValue + g_NMDA$ real = NMDAInitialValue + g_GABAA$ real = GABA_AInitialValue + g_GABAB$ real = GABA_BInitialValue end equations: - - /**/ - /* V_m*/ - /**/ - function I_syn_ampa pA = -g_AMPA * (V_m - AMPA_E_rev) - function I_syn_nmda pA = -g_NMDA * (V_m - NMDA_E_rev) / (1 + exp((NMDA_Vact - V_m) / NMDA_Sact)) - function I_syn_gaba_a pA = -g_GABAA * (V_m - GABA_A_E_rev) - function I_syn_gaba_b pA = -g_GABAB * (V_m - GABA_B_E_rev) - function I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b - function I_Na pA = -g_NaL * (V_m - E_Na) - function I_K pA = -g_KL * (V_m - E_K) - - /* I_Na(p), m_inf^3 according to Compte et al, J Neurophysiol 2003 89:2707*/ - function INaP_thresh mV = -55.7mV - function INaP_slope mV = 7.7mV - function m_inf_NaP real = 1.0 / (1.0 + exp(-(V_m - INaP_thresh) / INaP_slope)) - function d_half real = 0.25 - function m_inf_KNa real = 1.0 / (1.0 + (d_half / (IKNa_D / nS)) ** 3.5) - - /* Persistent Na current; member only to allow recording*/ - recordable function I_NaP pA = -NaP_g_peak * m_inf_NaP ** 3 * (V_m - NaP_E_rev) - - /* Depol act. K current; member only to allow recording*/ - recordable function I_KNa pA = -KNa_g_peak * m_inf_KNa * (V_m - KNa_E_rev) - - /* Low-thresh Ca current; member only to allow recording*/ - recordable function I_T pA = -T_g_peak * IT_m * IT_m * IT_h * (V_m - T_E_rev) - recordable function I_h pA = -h_g_peak * Ih_m * (V_m - h_E_rev) - - /* The spike current is only activate immediately after a spike.*/ - function I_spike pA = (g_spike)?-(V_m - E_K) / Tau_spike / mV * ms * pA:0pA - V_m'=((I_Na + I_K + I_syn + I_NaP + I_KNa + I_T + I_h + I_e + I_stim) / Tau_m + I_spike / (ms * mV)) * s / nF - - /**/ - /* Intrinsic currents*/ - /**/ - /* I_T*/ - function m_inf_T real = 1.0 / (1.0 + exp(-(V_m / mV + 59.0) / 6.2)) - function h_inf_T real = 1.0 / (1.0 + exp((V_m / mV + 83.0) / 4)) - /* I_KNa*/ - - /* I_KNa*/ - function D_influx_peak real = 0.025 - function tau_D real = 1250.0 # yes, 1.25 s - function D_thresh mV = -10.0mV - function D_slope mV = 5.0mV - function D_influx real = 1.0 / (1.0 + exp(-(V_m - D_thresh) / D_slope)) + inline I_syn_ampa pA = -convolve(g_AMPA,AMPA) * (V_m - AMPA_E_rev) + inline I_syn_nmda pA = -convolve(g_NMDA,NMDA) * (V_m - NMDA_E_rev) / (1 + exp((NMDA_Vact - V_m) / NMDA_Sact)) + inline I_syn_gaba_a pA = -convolve(g_GABAA,GABA_A) * (V_m - GABA_A_E_rev) + inline I_syn_gaba_b pA = -convolve(g_GABAB,GABA_B) * (V_m - GABA_B_E_rev) + inline I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b + inline I_Na pA = -g_NaL * (V_m - E_Na) + inline I_K pA = -g_KL * (V_m - E_K) + # I_Na(p), m_inf^3 according to Compte et al, J Neurophysiol 2003 89:2707 + inline INaP_thresh mV = -55.7mV + inline INaP_slope mV = 7.7mV + inline m_inf_NaP real = 1.0 / (1.0 + exp(-(V_m - INaP_thresh) / INaP_slope)) + # Persistent Na current; member only to allow recording + + # Persistent Na current; member only to allow recording + recordable inline I_NaP pA = -NaP_g_peak * m_inf_NaP ** 3 * (V_m - NaP_E_rev) + inline d_half real = 0.25 + inline m_inf_KNa real = 1.0 / (1.0 + (d_half / (IKNa_D / nS)) ** 3.5) + # Depol act. K current; member only to allow recording + + # Depol act. K current; member only to allow recording + recordable inline I_KNa pA = -KNa_g_peak * m_inf_KNa * (V_m - KNa_E_rev) + # Low-thresh Ca current; member only to allow recording + recordable inline I_T pA = -T_g_peak * IT_m * IT_m * IT_h * (V_m - T_E_rev) + recordable inline I_h pA = -h_g_peak * Ih_m * (V_m - h_E_rev) + # The spike current is only activate immediately after a spike. + + # The spike current is only activate immediately after a spike. + inline I_spike mV = (g_spike)?-(V_m - E_K) / Tau_spike:0 + V_m'=((I_Na + I_K + I_syn + I_NaP + I_KNa + I_T + I_h + I_e + I_stim) / Tau_m + I_spike * pA / (ms * mV)) * s / nF + ############ + # Intrinsic currents + ############ + # I_T + inline m_inf_T real = 1.0 / (1.0 + exp(-(V_m / mV + 59.0) / 6.2)) + inline h_inf_T real = 1.0 / (1.0 + exp((V_m / mV + 83.0) / 4)) + inline tau_m_h real = 1.0 / (exp(-14.59 - 0.086 * V_m / mV) + exp(-1.87 + 0.0701 * V_m / mV)) + # I_KNa + + # I_KNa + inline D_influx_peak real = 0.025 + inline tau_D real = 1250.0 # yes, 1.25 s + inline D_thresh mV = -10.0 + inline D_slope mV = 5.0 + inline D_influx real = 1.0 / (1.0 + exp(-(V_m - D_thresh) / D_slope)) Theta'=-(Theta - Theta_eq) / Tau_theta - - /* equation modified from y[](1-D_eq) to (y[]-D_eq), since we'd not*/ - /* be converging to equilibrium otherwise*/ + # equation modified from y[](1-D_eq) to (y[]-D_eq), since we'd not + # be converging to equilibrium otherwise IKNa_D'=(D_influx_peak * D_influx * nS - (IKNa_D - KNa_D_EQ / mV) / tau_D) / ms - function tau_m_T ms = (0.22 / (exp(-(V_m / mV + 132.0) / 16.7) + exp((V_m / mV + 16.8) / 18.2)) + 0.13) * ms - function tau_h_T ms = (8.2 + (56.6 + 0.27 * exp((V_m / mV + 115.2) / 5.0)) / (1.0 + exp((V_m / mV + 86.0) / 3.2))) * ms - function tau_m_h ms = (1.0 / (exp(-14.59 - 0.086 * V_m / mV) + exp(-1.87 + 0.0701 * V_m / mV))) * ms - function I_h_Vthreshold real = -75.0 - function m_inf_h real = 1.0 / (1.0 + exp((V_m / mV - I_h_Vthreshold) / 5.5)) - IT_m'=(m_inf_T - IT_m) / tau_m_T - IT_h'=(h_inf_T - IT_h) / tau_h_T - Ih_m'=(m_inf_h - Ih_m) / tau_m_h - - /**/ - /* Synapses*/ - /**/ - g_AMPA__d'=-g_AMPA__d / AMPA_Tau_1 - g_AMPA'=g_AMPA__d - g_AMPA / AMPA_Tau_2 - g_NMDA__d'=-g_NMDA__d / NMDA_Tau_1 - g_NMDA'=g_NMDA__d - g_NMDA / NMDA_Tau_2 - g_GABAA__d'=-g_GABAA__d / GABA_A_Tau_1 - g_GABAA'=g_GABAA__d - g_GABAA / GABA_A_Tau_2 - g_GABAB__d'=-g_GABAB__d / GABA_B_Tau_1 - g_GABAB'=g_GABAB__d - g_GABAB / GABA_B_Tau_2 + inline tau_m_T real = 0.22 / (exp(-(V_m / mV + 132.0) / 16.7) + exp((V_m / mV + 16.8) / 18.2)) + 0.13 + inline tau_h_T real = 8.2 + (56.6 + 0.27 * exp((V_m / mV + 115.2) / 5.0)) / (1.0 + exp((V_m / mV + 86.0) / 3.2)) + inline I_h_Vthreshold real = -75.0 + inline m_inf_h real = 1.0 / (1.0 + exp((V_m / mV - I_h_Vthreshold) / 5.5)) + IT_m'=(m_inf_T * nS - IT_m) / tau_m_T / ms + IT_h'=(h_inf_T * nS - IT_h) / tau_h_T / ms + Ih_m'=(m_inf_h * nS - Ih_m) / tau_m_h / ms + ############ + # Synapses + ############ + kernel g_AMPA' = g_AMPA$ - g_AMPA / AMPA_Tau_2, g_AMPA$' = -g_AMPA$ / AMPA_Tau_1 + kernel g_NMDA' = g_NMDA$ - g_NMDA / NMDA_Tau_2, g_NMDA$' = -g_NMDA$ / NMDA_Tau_1 + kernel g_GABAA' = g_GABAA$ - g_GABAA / GABA_A_Tau_2, g_GABAA$' = -g_GABAA$ / GABA_A_Tau_1 + kernel g_GABAB' = g_GABAB$ - g_GABAB / GABA_B_Tau_2, g_GABAB$' = -g_GABAB$ / GABA_B_Tau_1 end parameters: @@ -286,8 +246,9 @@ Source code Tau_theta ms = 2.0ms # time constant Tau_spike ms = 1.75ms # membrane time constant applying to repolarizing K-current t_spike ms = 2.0ms # duration of re-polarizing potassium current + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA - /* Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA*/ + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA AMPA_g_peak nS = 0.1nS # peak conductance AMPA_E_rev mV = 0.0mV # reversal potential AMPA_Tau_1 ms = 0.5ms # rise time @@ -306,8 +267,9 @@ Source code GABA_B_Tau_1 ms = 60.0ms # rise time GABA_B_Tau_2 ms = 200.0ms # decay time, Tau_1 < Tau_2 GABA_B_E_rev mV = -90.0mV # reversal potential for intrinsic current + # parameters for intrinsic currents - /* parameters for intrinsic currents*/ + # parameters for intrinsic currents NaP_g_peak nS = 1.0nS # peak conductance for intrinsic current NaP_E_rev mV = 30.0mV # reversal potential for intrinsic current KNa_g_peak nS = 1.0nS # peak conductance for intrinsic current @@ -317,8 +279,7 @@ Source code h_g_peak nS = 1.0nS # peak conductance for intrinsic current h_E_rev mV = -40.0mV # reversal potential for intrinsic current KNa_D_EQ pA = 0.001pA - - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: @@ -340,25 +301,18 @@ Source code update: integrate_odes() - - /* Deactivate potassium current after spike time have expired*/ + # Deactivate potassium current after spike time have expired if (r_potassium > 0) and (r_potassium - 1 == 0): g_spike = false # Deactivate potassium current. end r_potassium -= 1 - g_AMPA__d += AMPAInitialValue * AMPA / ms - g_NMDA__d += NMDAInitialValue * NMDA / ms - g_GABAA__d += GABA_AInitialValue * GABA_A / ms - g_GABAB__d += GABA_BInitialValue * GABA_B / ms if (not g_spike) and V_m >= Theta: - - /* Set V and Theta to the sodium reversal potential.*/ + # Set V and Theta to the sodium reversal potential. V_m = E_Na Theta = E_Na - - /* Activate fast potassium current. Drives the*/ - /* membrane potential towards the potassium reversal*/ - /* potential (activate only if duration is non-zero).*/ + # Activate fast potassium current. Drives the + # membrane potential towards the potassium reversal + # potential (activate only if duration is non-zero). if PotassiumRefractoryCounts > 0: g_spike = true else: @@ -370,12 +324,11 @@ Source code end function compute_synapse_constant(Tau_1 msTau_2 msg_peak real) real: - - /* Factor used to account for the missing 1/((1/Tau_2)-(1/Tau_1)) term*/ - /* in the ht_neuron_dynamics integration of the synapse terms.*/ - /* See: Exact digital simulation of time-invariant linear systems*/ - /* with applications to neuronal modeling, Rotter and Diesmann,*/ - /* section 3.1.2.*/ + # Factor used to account for the missing 1/((1/Tau_2)-(1/Tau_1)) term + # in the ht_neuron_dynamics integration of the synapse terms. + # See: Exact digital simulation of time-invariant linear systems + # with applications to neuronal modeling, Rotter and Diesmann, + # section 3.1.2. exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms t_peak real = (Tau_2 * Tau_1) * ln(Tau_2 / Tau_1) / (Tau_2 - Tau_1) / ms normalisation_factor real = 1 / (exp(-t_peak / Tau_1) - exp(-t_peak / Tau_2)) @@ -394,4 +347,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.324410 \ No newline at end of file + Generated at 2022-03-28 19:04:29.077699 \ No newline at end of file diff --git a/doc/models_library/iaf_chxk_2008.rst b/doc/models_library/iaf_chxk_2008.rst index ec53863ff..989fdfb24 100644 --- a/doc/models_library/iaf_chxk_2008.rst +++ b/doc/models_library/iaf_chxk_2008.rst @@ -1,8 +1,8 @@ iaf_chxk_2008 ############# -iaf_chxk_2008 - Conductance based leaky integrate-and-fire neuron model used in Casti et al. 2008 +iaf_chxk_2008 - Conductance based leaky integrate-and-fire neuron model used in Casti et al. 2008 Description +++++++++++ @@ -36,6 +36,7 @@ See also iaf_cond_alpha + Parameters ++++++++++ @@ -46,16 +47,16 @@ Parameters :widths: auto - "V_th", "mV", "-45.0mV", "Threshold Potential" - "E_ex", "mV", "20mV", "Excitatory reversal potential" - "E_in", "mV", "-90mV", "Inhibitory reversal potential" - "g_L", "nS", "100nS", "Leak Conductance" - "C_m", "pF", "1000.0pF", "Membrane Capacitance" + "V_th", "mV", "-45.0mV", "Threshold potential" + "E_exc", "mV", "20mV", "Excitatory reversal potential" + "E_inh", "mV", "-90mV", "Inhibitory reversal potential" + "g_L", "nS", "100nS", "Leak conductance" + "C_m", "pF", "1000.0pF", "Membrane capacitance" "E_L", "mV", "-60.0mV", "Leak reversal Potential (aka resting potential)" - "tau_syn_ex", "ms", "1ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "1ms", "Synaptic Time Constant for Inhibitory Synapse" + "tau_syn_exc", "ms", "1ms", "Synaptic time constant of excitatory synapse" + "tau_syn_inh", "ms", "1ms", "Synaptic time constant of inhibitory synapse" "tau_ahp", "ms", "0.5ms", "Afterhyperpolarization (AHP) time constant" - "g_ahp", "nS", "443.8nS", "AHP conductance" + "G_ahp", "nS", "443.8nS", "AHP conductance" "E_ahp", "mV", "-95mV", "AHP potential" "ahp_bug", "boolean", "false", "If true, discard AHP conductance value from previous spikes" "I_e", "pA", "0pA", "constant external input current" @@ -72,8 +73,8 @@ State variables "V_m", "mV", "E_L", "membrane potential" - "G_ahp", "nS", "0nS", "AHP conductance" - "G_ahp__d", "nS / ms", "0nS / ms", "AHP conductance" + "g_ahp", "nS", "0nS", "AHP conductance" + "g_ahp", "nS / ms", "0nS / ms", "AHP conductance" @@ -85,76 +86,66 @@ Equations .. math:: - \frac{ dG_{ahp,,d} } { dt }= (\frac{ -2 } { \tau_{ahp} }) \cdot G_{ahp,,d} - (\frac{ 1 } { { \tau_{ahp} }^{ 2 } }) \cdot G_{ahp} + \frac{ d^2 g_{ahp} } { dt^2 }= \frac{ -2 \cdot g_{ahp}' } { \tau_{ahp} } - \frac{ g_{ahp} } { { \tau_{ahp} }^{ 2 } } .. math:: \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-I_{leak} - I_{syn,exc} - I_{syn,inh} - I_{ahp} + I_{e} + I_{stim}) } \right) -.. math:: - \frac{ dG_{ahp} } { dt }= G_{ahp,,d} - - Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_chxk_2008: - initial_values: + state: V_m mV = E_L # membrane potential - G_ahp nS = 0nS # AHP conductance - G_ahp__d nS/ms = 0nS / ms # AHP conductance - /*G_ahp' nS/ms = e / tau_ahp * nS AHP conductance*/ - + g_ahp nS = 0nS # AHP conductance + g_ahp' nS/ms = 0nS / ms # AHP conductance end equations: - kernel g_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel g_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - G_ahp__d'=(-2 / tau_ahp) * G_ahp__d - (1 / tau_ahp ** 2) * G_ahp - function I_syn_exc pA = convolve(g_ex,spikesExc) * (V_m - E_ex) - function I_syn_inh pA = convolve(g_in,spikesInh) * (V_m - E_in) - function I_ahp pA = G_ahp * (V_m - E_ahp) - function I_leak pA = g_L * (V_m - E_L) + kernel g_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel g_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + g_ahp''=-2 * g_ahp' / tau_ahp - g_ahp / tau_ahp ** 2 + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) + inline I_ahp pA = g_ahp * (V_m - E_ahp) + inline I_leak pA = g_L * (V_m - E_L) V_m'=(-I_leak - I_syn_exc - I_syn_inh - I_ahp + I_e + I_stim) / C_m - G_ahp'=G_ahp__d end parameters: - V_th mV = -45.0mV # Threshold Potential - E_ex mV = 20mV # Excitatory reversal potential - E_in mV = -90mV # Inhibitory reversal potential - g_L nS = 100nS # Leak Conductance - C_m pF = 1000.0pF # Membrane Capacitance + V_th mV = -45.0mV # Threshold potential + E_exc mV = 20mV # Excitatory reversal potential + E_inh mV = -90mV # Inhibitory reversal potential + g_L nS = 100nS # Leak conductance + C_m pF = 1000.0pF # Membrane capacitance E_L mV = -60.0mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 1ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 1ms # Synaptic Time Constant for Inhibitory Synapse + tau_syn_exc ms = 1ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 1ms # Synaptic time constant of inhibitory synapse tau_ahp ms = 0.5ms # Afterhyperpolarization (AHP) time constant - g_ahp nS = 443.8nS # AHP conductance + G_ahp nS = 443.8nS # AHP conductance E_ahp mV = -95mV # AHP potential ahp_bug boolean = false # If true, discard AHP conductance value from previous spikes + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: - - /* Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude*/ - /* conductance excursion.*/ - PSConInit_E nS/ms = nS * e / tau_syn_ex - - /* Impulse to add to DG_INH on spike arrival to evoke unit-amplitude*/ - /* conductance excursion.*/ - PSConInit_I nS/ms = nS * e / tau_syn_in - PSConInit_AHP real = g_ahp * e / tau_ahp * (ms / nS) + # Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude conductance excursion. + PSConInit_E nS/ms = nS * e / tau_syn_exc + # Impulse to add to DG_INH on spike arrival to evoke unit-amplitude conductance excursion. + PSConInit_I nS/ms = nS * e / tau_syn_inh + PSConInit_AHP real = G_ahp * e / tau_ahp * (ms / nS) end input: - spikesInh nS <-inhibitory spike - spikesExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -164,20 +155,19 @@ Source code vm_prev mV = V_m integrate_odes() if vm_prev < V_th and V_m >= V_th: - - /* Find precise spike time using linear interpolation*/ + # Find precise spike time using linear interpolation sigma real = (V_m - V_th) * resolution() / (V_m - vm_prev) / ms alpha real = exp(-sigma / tau_ahp) delta_g_ahp real = PSConInit_AHP * sigma * alpha delta_dg_ahp real = PSConInit_AHP * alpha if ahp_bug == true: - - /* Bug in original code ignores AHP conductance from previous spikes*/ - G_ahp = delta_g_ahp * nS - G_ahp__d = delta_dg_ahp * nS / ms + # Bug in original code ignores AHP conductance from previous spikes + g_ahp = delta_g_ahp * nS + g_ahp' = delta_dg_ahp * nS / ms else: - G_ahp += delta_g_ahp * nS - G_ahp__d += delta_dg_ahp * nS / ms + # Correct implementation adds initial values for new AHP to AHP history + g_ahp += delta_g_ahp * nS + g_ahp' += delta_dg_ahp * nS / ms end emit_spike() end @@ -195,4 +185,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.567160 \ No newline at end of file + Generated at 2022-03-28 19:04:29.728109 \ No newline at end of file diff --git a/doc/models_library/iaf_cond_alpha.rst b/doc/models_library/iaf_cond_alpha.rst index 09eccaee5..8c3e2b641 100644 --- a/doc/models_library/iaf_cond_alpha.rst +++ b/doc/models_library/iaf_cond_alpha.rst @@ -1,8 +1,8 @@ iaf_cond_alpha ############## -iaf_cond_alpha - Simple conductance based leaky integrate-and-fire neuron model +iaf_cond_alpha - Simple conductance based leaky integrate-and-fire neuron model Description +++++++++++ @@ -38,11 +38,6 @@ See also iaf_cond_exp -Authors -+++++++ - -Schrader, Plesser - Parameters ++++++++++ @@ -54,16 +49,16 @@ Parameters :widths: auto - "V_th", "mV", "-55.0mV", "Threshold Potential" - "V_reset", "mV", "-60.0mV", "Reset Potential" - "t_ref", "ms", "2.0ms", "Refractory period" - "g_L", "nS", "16.6667nS", "Leak Conductance" - "C_m", "pF", "250.0pF", "Membrane Capacitance" - "E_ex", "mV", "0mV", "Excitatory reversal Potential" - "E_in", "mV", "-85.0mV", "Inhibitory reversal Potential" - "E_L", "mV", "-70.0mV", "Leak reversal Potential (aka resting potential)" - "tau_syn_ex", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" + "V_th", "mV", "-55mV", "Threshold potential" + "V_reset", "mV", "-60mV", "Reset potential" + "t_ref", "ms", "2ms", "Refractory period" + "g_L", "nS", "16.6667nS", "Leak conductance" + "C_m", "pF", "250pF", "Membrane capacitance" + "E_exc", "mV", "0mV", "Excitatory reversal potential" + "E_inh", "mV", "-85mV", "Inhibitory reversal potential" + "E_L", "mV", "-70mV", "Leak reversal potential (aka resting potential)" + "tau_syn_exc", "ms", "0.2ms", "Synaptic time constant of excitatory synapse" + "tau_syn_inh", "ms", "2ms", "Synaptic time constant of inhibitory synapse" "I_e", "pA", "0pA", "constant external input current" @@ -77,6 +72,7 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" "V_m", "mV", "E_L", "membrane potential" @@ -98,45 +94,44 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_cond_alpha: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # membrane potential end equations: - kernel g_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel g_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - function I_syn_exc pA = convolve(g_ex,spikeExc) * (V_m - E_ex) - function I_syn_inh pA = convolve(g_in,spikeInh) * (V_m - E_in) - function I_leak pA = g_L * (V_m - E_L) + kernel g_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel g_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) + inline I_leak pA = g_L * (V_m - E_L) V_m'=(-I_leak - I_syn_exc - I_syn_inh + I_e + I_stim) / C_m end parameters: - V_th mV = -55.0mV # Threshold Potential - V_reset mV = -60.0mV # Reset Potential - t_ref ms = 2.0ms # Refractory period - g_L nS = 16.6667nS # Leak Conductance - C_m pF = 250.0pF # Membrane Capacitance - E_ex mV = 0mV # Excitatory reversal Potential - E_in mV = -85.0mV # Inhibitory reversal Potential - E_L mV = -70.0mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse - - /* constant external input current*/ + V_th mV = -55mV # Threshold potential + V_reset mV = -60mV # Reset potential + t_ref ms = 2ms # Refractory period + g_L nS = 16.6667nS # Leak conductance + C_m pF = 250pF # Membrane capacitance + E_exc mV = 0mV # Excitatory reversal potential + E_inh mV = -85mV # Inhibitory reversal potential + E_L mV = -70mV # Leak reversal potential (aka resting potential) + tau_syn_exc ms = 0.2ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 2ms # Synaptic time constant of inhibitory synapse + # constant external input current + + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -166,4 +161,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.357595 \ No newline at end of file + Generated at 2022-03-28 19:04:28.988795 \ No newline at end of file diff --git a/doc/models_library/iaf_cond_beta.rst b/doc/models_library/iaf_cond_beta.rst index 67040498c..5031a6610 100644 --- a/doc/models_library/iaf_cond_beta.rst +++ b/doc/models_library/iaf_cond_beta.rst @@ -1,8 +1,8 @@ iaf_cond_beta ############# -iaf_cond_beta - Simple conductance based leaky integrate-and-fire neuron model +iaf_cond_beta - Simple conductance based leaky integrate-and-fire neuron model Description +++++++++++ @@ -46,6 +46,7 @@ See also iaf_cond_exp, iaf_cond_alpha + Parameters ++++++++++ @@ -56,20 +57,20 @@ Parameters :widths: auto - "E_L", "mV", "-85.0mV", "Leak reversal Potential (aka resting potential)" - "C_m", "pF", "250.0pF", "Capacity of the membrane" - "t_ref", "ms", "2.0ms", "Refractory period" - "V_th", "mV", "-55.0mV", "Threshold Potential" - "V_reset", "mV", "-60.0mV", "Reset Potential" - "E_ex", "mV", "0mV", "Excitatory reversal Potential" - "E_in", "mV", "-85.0mV", "Inhibitory reversal Potential" - "g_L", "nS", "16.6667nS", "Leak Conductance" - "tau_syn_rise_I", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_decay_I", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" - "tau_syn_rise_E", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_decay_E", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" - "F_E", "nS", "0nS", "Constant External input conductance (excitatory)." - "F_I", "nS", "0nS", "Constant External input conductance (inhibitory)." + "E_L", "mV", "-70mV", "Leak reversal potential (aka resting potential)" + "C_m", "pF", "250pF", "Capacitance of the membrane" + "t_ref", "ms", "2ms", "Refractory period" + "V_th", "mV", "-55mV", "Threshold potential" + "V_reset", "mV", "-60mV", "Reset potential" + "E_ex", "mV", "0mV", "Excitatory reversal potential" + "E_in", "mV", "-85mV", "Inhibitory reversal potential" + "g_L", "nS", "16.6667nS", "Leak conductance" + "tau_syn_rise_I", "ms", "0.2ms", "Synaptic time constant excitatory synapse" + "tau_syn_decay_I", "ms", "2ms", "Synaptic time constant for inhibitory synapse" + "tau_syn_rise_E", "ms", "0.2ms", "Synaptic time constant excitatory synapse" + "tau_syn_decay_E", "ms", "2ms", "Synaptic time constant for inhibitory synapse" + "F_E", "nS", "0nS", "Constant external input conductance (excitatory)." + "F_I", "nS", "0nS", "Constant external input conductance (inhibitory)." "I_e", "pA", "0pA", "constant external input current" @@ -83,11 +84,12 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" "V_m", "mV", "E_L", "membrane potential" - "g_in", "nS", "0nS", "inputs from the inh conductance" - "g_in__d", "nS / ms", "0nS / ms", "inputs from the inh conductance" - "g_ex", "nS", "0nS", "inputs from the exc conductance" - "g_ex__d", "nS / ms", "0nS / ms", "inputs from the exc conductance" + "g_in", "real", "0", "inputs from the inhibitory conductance" + "g_in$", "real", "g_I_const * (1 / tau_syn_rise_I - 1 / tau_syn_decay_I)", "" + "g_ex", "real", "0", "inputs from the excitatory conductance" + "g_ex$", "real", "g_E_const * (1 / tau_syn_rise_E - 1 / tau_syn_decay_E)", "" @@ -98,22 +100,6 @@ Equations -.. math:: - \frac{ dg_{in,,d} } { dt }= \frac{ -g_{in,,d} } { \tau_{syn,rise,I} } - - -.. math:: - \frac{ dg_{in} } { dt }= g_{in,,d} - \frac{ g_{in} } { \tau_{syn,decay,I} } - - -.. math:: - \frac{ dg_{ex,,d} } { dt }= \frac{ -g_{ex,,d} } { \tau_{syn,rise,E} } - - -.. math:: - \frac{ dg_{ex} } { dt }= g_{ex,,d} - \frac{ g_{ex} } { \tau_{syn,decay,E} } - - .. math:: \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-I_{leak} - I_{syn,exc} - I_{syn,inh} + I_{e} + I_{stim}) } \right) @@ -124,62 +110,62 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_cond_beta: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # membrane potential - g_in nS = 0nS # inputs from the inh conductance - g_in__d nS/ms = 0nS / ms # inputs from the inh conductance - g_ex nS = 0nS # inputs from the exc conductance - g_ex__d nS/ms = 0nS / ms # inputs from the exc conductance + # inputs from the inhibitory conductance + + # inputs from the inhibitory conductance + g_in real = 0 + g_in$ real = g_I_const * (1 / tau_syn_rise_I - 1 / tau_syn_decay_I) + # inputs from the excitatory conductance + g_ex real = 0 + g_ex$ real = g_E_const * (1 / tau_syn_rise_E - 1 / tau_syn_decay_E) end equations: - g_in__d'=-g_in__d / tau_syn_rise_I - g_in'=g_in__d - g_in / tau_syn_decay_I - g_ex__d'=-g_ex__d / tau_syn_rise_E - g_ex'=g_ex__d - g_ex / tau_syn_decay_E - function I_syn_exc pA = (F_E + convolve(g_ex,spikeExc)) * (V_m - E_ex) - function I_syn_inh pA = (F_I + convolve(g_in,spikeInh)) * (V_m - E_in) - function I_leak pA = g_L * (V_m - E_L) # pa = nS * mV + kernel g_in' = g_in$ - g_in / tau_syn_rise_I, g_in$' = -g_in$ / tau_syn_decay_I + kernel g_ex' = g_ex$ - g_ex / tau_syn_rise_E, g_ex$' = -g_ex$ / tau_syn_decay_E + inline I_syn_exc pA = (F_E + convolve(g_ex,exc_spikes)) * (V_m - E_ex) + inline I_syn_inh pA = (F_I + convolve(g_in,inh_spikes)) * (V_m - E_in) + inline I_leak pA = g_L * (V_m - E_L) # pA = nS * mV V_m'=(-I_leak - I_syn_exc - I_syn_inh + I_e + I_stim) / C_m end parameters: - E_L mV = -85.0mV # Leak reversal Potential (aka resting potential) - C_m pF = 250.0pF # Capacity of the membrane - t_ref ms = 2.0ms # Refractory period - V_th mV = -55.0mV # Threshold Potential - V_reset mV = -60.0mV # Reset Potential - E_ex mV = 0mV # Excitatory reversal Potential - E_in mV = -85.0mV # Inhibitory reversal Potential - g_L nS = 16.6667nS # Leak Conductance - tau_syn_rise_I ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - tau_syn_decay_I ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse - tau_syn_rise_E ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - tau_syn_decay_E ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse - F_E nS = 0nS # Constant External input conductance (excitatory). - F_I nS = 0nS # Constant External input conductance (inhibitory). - - /* constant external input current*/ + E_L mV = -70mV # Leak reversal potential (aka resting potential) + C_m pF = 250pF # Capacitance of the membrane + t_ref ms = 2ms # Refractory period + V_th mV = -55mV # Threshold potential + V_reset mV = -60mV # Reset potential + E_ex mV = 0mV # Excitatory reversal potential + E_in mV = -85mV # Inhibitory reversal potential + g_L nS = 16.6667nS # Leak conductance + tau_syn_rise_I ms = 0.2ms # Synaptic time constant excitatory synapse + tau_syn_decay_I ms = 2ms # Synaptic time constant for inhibitory synapse + tau_syn_rise_E ms = 0.2ms # Synaptic time constant excitatory synapse + tau_syn_decay_E ms = 2ms # Synaptic time constant for inhibitory synapse + F_E nS = 0nS # Constant external input conductance (excitatory). + F_I nS = 0nS # Constant external input conductance (inhibitory). + # constant external input current + + # constant external input current I_e pA = 0pA end internals: - - /* conductance excursion.*/ - PSConInit_E 1/ms = e / tau_syn_rise_E - - /* Impulse to add to g_in' on spike arrival to evoke unit-amplitude*/ - /* conductance excursion.*/ - PSConInit_I 1/ms = e / tau_syn_rise_I + # time of peak conductance excursion after spike arrival at t = 0 + t_peak_E real = tau_syn_decay_E * tau_syn_rise_E * ln(tau_syn_decay_E / tau_syn_rise_E) / (tau_syn_decay_E - tau_syn_rise_E) + t_peak_I real = tau_syn_decay_I * tau_syn_rise_I * ln(tau_syn_decay_I / tau_syn_rise_I) / (tau_syn_decay_I - tau_syn_rise_I) + # normalisation constants to ensure arriving spike yields peak conductance of 1 nS + g_E_const real = 1 / (exp(-t_peak_E / tau_syn_decay_E) - exp(-t_peak_E / tau_syn_rise_E)) + g_I_const real = 1 / (exp(-t_peak_I / tau_syn_decay_I) - exp(-t_peak_I / tau_syn_rise_I)) RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -195,8 +181,6 @@ Source code V_m = V_reset # clamp potential emit_spike() end - g_ex__d += spikeExc * PSConInit_E - g_in__d += spikeInh * PSConInit_I end end @@ -211,4 +195,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.858817 \ No newline at end of file + Generated at 2022-03-28 19:04:29.689632 \ No newline at end of file diff --git a/doc/models_library/iaf_cond_exp.rst b/doc/models_library/iaf_cond_exp.rst index 07ba00bda..d6c4bf0c7 100644 --- a/doc/models_library/iaf_cond_exp.rst +++ b/doc/models_library/iaf_cond_exp.rst @@ -1,8 +1,8 @@ iaf_cond_exp ############ -iaf_cond_exp - Simple conductance based leaky integrate-and-fire neuron model +iaf_cond_exp - Simple conductance based leaky integrate-and-fire neuron model Description +++++++++++ @@ -27,10 +27,6 @@ See also iaf_psc_delta, iaf_psc_exp, iaf_cond_exp -Author -++++++ - -Sven Schrader Parameters @@ -43,16 +39,16 @@ Parameters :widths: auto - "V_th", "mV", "-55.0mV", "Threshold Potential" - "V_reset", "mV", "-60.0mV", "Reset Potential" - "t_ref", "ms", "2.0ms", "Refractory period" - "g_L", "nS", "16.6667nS", "Leak Conductance" - "C_m", "pF", "250.0pF", "Membrane Capacitance" - "E_ex", "mV", "0mV", "Excitatory reversal Potential" - "E_in", "mV", "-85.0mV", "Inhibitory reversal Potential" - "E_L", "mV", "-70.0mV", "Leak reversal Potential (aka resting potential)" - "tau_syn_ex", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" + "V_th", "mV", "-55mV", "Threshold potential" + "V_reset", "mV", "-60mV", "Reset potential" + "t_ref", "ms", "2ms", "Refractory period" + "g_L", "nS", "16.6667nS", "Leak conductance" + "C_m", "pF", "250pF", "Membrane capacitance" + "E_exc", "mV", "0mV", "Excitatory reversal potential" + "E_inh", "mV", "-85mV", "Inhibitory reversal potential" + "E_L", "mV", "-70mV", "Leak reversal potential (aka resting potential)" + "tau_syn_exc", "ms", "0.2ms", "Synaptic time constant of excitatory synapse" + "tau_syn_inh", "ms", "2ms", "Synaptic time constant of inhibitory synapse" "I_e", "pA", "0pA", "constant external input current" @@ -66,6 +62,7 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" "V_m", "mV", "E_L", "membrane potential" @@ -87,45 +84,44 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_cond_exp: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # membrane potential end equations: - kernel g_in = exp(-t / tau_syn_in) # inputs from the inh conductance - kernel g_ex = exp(-t / tau_syn_ex) # inputs from the exc conductance - function I_syn_exc pA = convolve(g_ex,spikeExc) * (V_m - E_ex) - function I_syn_inh pA = convolve(g_in,spikeInh) * (V_m - E_in) - function I_leak pA = g_L * (V_m - E_L) + kernel g_inh = exp(-t / tau_syn_inh) # inputs from the inh conductance + kernel g_exc = exp(-t / tau_syn_exc) # inputs from the exc conductance + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) + inline I_leak pA = g_L * (V_m - E_L) V_m'=(-I_leak - I_syn_exc - I_syn_inh + I_e + I_stim) / C_m end parameters: - V_th mV = -55.0mV # Threshold Potential - V_reset mV = -60.0mV # Reset Potential - t_ref ms = 2.0ms # Refractory period - g_L nS = 16.6667nS # Leak Conductance - C_m pF = 250.0pF # Membrane Capacitance - E_ex mV = 0mV # Excitatory reversal Potential - E_in mV = -85.0mV # Inhibitory reversal Potential - E_L mV = -70.0mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse - - /* constant external input current*/ + V_th mV = -55mV # Threshold potential + V_reset mV = -60mV # Reset potential + t_ref ms = 2ms # Refractory period + g_L nS = 16.6667nS # Leak conductance + C_m pF = 250pF # Membrane capacitance + E_exc mV = 0mV # Excitatory reversal potential + E_inh mV = -85mV # Inhibitory reversal potential + E_L mV = -70mV # Leak reversal potential (aka resting potential) + tau_syn_exc ms = 0.2ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 2ms # Synaptic time constant of inhibitory synapse + # constant external input current + + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -155,4 +151,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.909333 \ No newline at end of file + Generated at 2022-03-28 19:04:30.212547 \ No newline at end of file diff --git a/doc/models_library/iaf_cond_exp_sfa_rr.rst b/doc/models_library/iaf_cond_exp_sfa_rr.rst index 9b41b9a51..fe117f869 100644 --- a/doc/models_library/iaf_cond_exp_sfa_rr.rst +++ b/doc/models_library/iaf_cond_exp_sfa_rr.rst @@ -1,8 +1,8 @@ iaf_cond_exp_sfa_rr ################### -iaf_cond_exp_sfa_rr - Conductance based leaky integrate-and-fire model with spike-frequency adaptation and relative refractory mechanisms +iaf_cond_exp_sfa_rr - Conductance based leaky integrate-and-fire model with spike-frequency adaptation and relative refractory mechanisms Description +++++++++++ @@ -36,6 +36,7 @@ See also aeif_cond_alpha, aeif_cond_exp, iaf_chxk_2008 + Parameters ++++++++++ @@ -46,20 +47,20 @@ Parameters :widths: auto - "V_th", "mV", "-57.0mV", "Threshold Potential" - "V_reset", "mV", "-70.0mV", "Reset Potential" + "V_th", "mV", "-57.0mV", "Threshold potential" + "V_reset", "mV", "-70.0mV", "Reset potential" "t_ref", "ms", "0.5ms", "Refractory period" - "g_L", "nS", "28.95nS", "Leak Conductance" - "C_m", "pF", "289.5pF", "Membrane Capacitance" - "E_ex", "mV", "0mV", "Excitatory reversal Potential" - "E_in", "mV", "-75.0mV", "Inhibitory reversal Potential" - "E_L", "mV", "-70.0mV", "Leak reversal Potential (aka resting potential)" - "tau_syn_ex", "ms", "1.5ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "10.0ms", "Synaptic Time Constant for Inhibitory Synapse" + "g_L", "nS", "28.95nS", "Leak conductance" + "C_m", "pF", "289.5pF", "Membrane capacitance" + "E_exc", "mV", "0mV", "Excitatory reversal potential" + "E_inh", "mV", "-75.0mV", "Inhibitory reversal potential" + "E_L", "mV", "-70.0mV", "Leak reversal potential (aka resting potential)" + "tau_syn_exc", "ms", "1.5ms", "Synaptic time constant of excitatory synapse" + "tau_syn_inh", "ms", "10.0ms", "Synaptic time constant of inhibitory synapse" "q_sfa", "nS", "14.48nS", "Outgoing spike activated quantal spike-frequency adaptation conductance increase" - "q_rr", "nS", "3214.0nS", "Outgoing spike activated quantal relative refractory conductance increase." - "tau_sfa", "ms", "110.0ms", "Time constant of spike-frequency adaptation." - "tau_rr", "ms", "1.97ms", "Time constant of the relative refractory mechanism." + "q_rr", "nS", "3214.0nS", "Outgoing spike activated quantal relative refractory conductance increase" + "tau_sfa", "ms", "110.0ms", "Time constant of spike-frequency adaptation" + "tau_rr", "ms", "1.97ms", "Time constant of the relative refractory mechanism" "E_sfa", "mV", "-70.0mV", "spike-frequency adaptation conductance reversal potential" "E_rr", "mV", "-70.0mV", "relative refractory mechanism conductance reversal potential" "I_e", "pA", "0pA", "constant external input current" @@ -75,6 +76,7 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" "V_m", "mV", "E_L", "membrane potential" "g_sfa", "nS", "0nS", "inputs from the sfa conductance" "g_rr", "nS", "0nS", "inputs from the rr conductance" @@ -106,57 +108,56 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_cond_exp_sfa_rr: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # membrane potential g_sfa nS = 0nS # inputs from the sfa conductance g_rr nS = 0nS # inputs from the rr conductance end equations: - kernel g_in = exp(-t / tau_syn_in) # inputs from the inh conductance - kernel g_ex = exp(-t / tau_syn_ex) # inputs from the exc conductance + kernel g_inh = exp(-t / tau_syn_inh) # inputs from the inh conductance + kernel g_exc = exp(-t / tau_syn_exc) # inputs from the exc conductance g_sfa'=-g_sfa / tau_sfa g_rr'=-g_rr / tau_rr - function I_syn_exc pA = convolve(g_ex,spikesExc) * (V_m - E_ex) - function I_syn_inh pA = convolve(g_in,spikesInh) * (V_m - E_in) - function I_L pA = g_L * (V_m - E_L) - function I_sfa pA = g_sfa * (V_m - E_sfa) - function I_rr pA = g_rr * (V_m - E_rr) + inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) + inline I_L pA = g_L * (V_m - E_L) + inline I_sfa pA = g_sfa * (V_m - E_sfa) + inline I_rr pA = g_rr * (V_m - E_rr) V_m'=(-I_L + I_e + I_stim - I_syn_exc - I_syn_inh - I_sfa - I_rr) / C_m end parameters: - V_th mV = -57.0mV # Threshold Potential - V_reset mV = -70.0mV # Reset Potential + V_th mV = -57.0mV # Threshold potential + V_reset mV = -70.0mV # Reset potential t_ref ms = 0.5ms # Refractory period - g_L nS = 28.95nS # Leak Conductance - C_m pF = 289.5pF # Membrane Capacitance - E_ex mV = 0mV # Excitatory reversal Potential - E_in mV = -75.0mV # Inhibitory reversal Potential - E_L mV = -70.0mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 1.5ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 10.0ms # Synaptic Time Constant for Inhibitory Synapse + g_L nS = 28.95nS # Leak conductance + C_m pF = 289.5pF # Membrane capacitance + E_exc mV = 0mV # Excitatory reversal potential + E_inh mV = -75.0mV # Inhibitory reversal potential + E_L mV = -70.0mV # Leak reversal potential (aka resting potential) + tau_syn_exc ms = 1.5ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 10.0ms # Synaptic time constant of inhibitory synapse q_sfa nS = 14.48nS # Outgoing spike activated quantal spike-frequency adaptation conductance increase - q_rr nS = 3214.0nS # Outgoing spike activated quantal relative refractory conductance increase. - tau_sfa ms = 110.0ms # Time constant of spike-frequency adaptation. - tau_rr ms = 1.97ms # Time constant of the relative refractory mechanism. + q_rr nS = 3214.0nS # Outgoing spike activated quantal relative refractory conductance increase + tau_sfa ms = 110.0ms # Time constant of spike-frequency adaptation + tau_rr ms = 1.97ms # Time constant of the relative refractory mechanism E_sfa mV = -70.0mV # spike-frequency adaptation conductance reversal potential E_rr mV = -70.0mV # relative refractory mechanism conductance reversal potential + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - spikesInh nS <-inhibitory spike - spikesExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -188,4 +189,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.821174 \ No newline at end of file + Generated at 2022-03-28 19:04:29.555731 \ No newline at end of file diff --git a/doc/models_library/iaf_psc_alpha.rst b/doc/models_library/iaf_psc_alpha.rst index 041e5fd42..89a602aae 100644 --- a/doc/models_library/iaf_psc_alpha.rst +++ b/doc/models_library/iaf_psc_alpha.rst @@ -1,15 +1,15 @@ iaf_psc_alpha ############# -iaf_psc_alpha - Leaky integrate-and-fire neuron model +iaf_psc_alpha - Leaky integrate-and-fire neuron model Description +++++++++++ iaf_psc_alpha is an implementation of a leaky integrate-and-fire model -with alpha-kernel synaptic currents. Thus, synaptic currents and the -resulting post-synaptic potentials have a finite rise time. +with alpha-function kernel synaptic currents. Thus, synaptic currents +and the resulting post-synaptic potentials have a finite rise time. The threshold crossing is followed by an absolute refractory period during which the membrane potential is clamped to the resting potential. @@ -28,7 +28,7 @@ enough to exhibit non-trivial dynamics and simple enough compute relevant measures analytically. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -36,26 +36,6 @@ relevant measures analytically. the NEST source code (``docs/model_details``). -Parameters -++++++++++ - -The following parameters can be set in the status dictionary. - -=========== ====== ========================================================== - V_m mV Membrane potential - E_L mV Resting membrane potential - C_m pF Capacity of the membrane - tau_m ms Membrane time constant - t_ref ms Duration of refractory period - V_th mV Spike threshold - V_reset mV Reset potential of the membrane - tau_syn_ex ms Rise time of the excitatory synaptic alpha function - tau_syn_in ms Rise time of the inhibitory synaptic alpha function - I_e pA Constant input current - V_min mV Absolute lower value for the membrane potenial -=========== ====== ========================================================== - - References ++++++++++ @@ -79,11 +59,6 @@ See also iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha -Authors -+++++++ - -Diesmann, Gewaltig - Parameters ++++++++++ @@ -95,14 +70,14 @@ Parameters :widths: auto - "C_m", "pF", "250pF", "Capacity of the membrane" - "Tau", "ms", "10ms", "Membrane time constant." - "tau_syn_in", "ms", "2ms", "Time constant of synaptic current." - "tau_syn_ex", "ms", "2ms", "Time constant of synaptic current." - "t_ref", "ms", "2ms", "Duration of refractory period." - "E_L", "mV", "-70mV", "Resting potential." - "V_reset", "mV", "-70mV - E_L", "Reset potential of the membrane." - "Theta", "mV", "-55mV - E_L", "Spike threshold." + "C_m", "pF", "250pF", "Capacitance of the membrane" + "tau_m", "ms", "10ms", "Membrane time constant" + "tau_syn_inh", "ms", "2ms", "Time constant of synaptic current" + "tau_syn_exc", "ms", "2ms", "Time constant of synaptic current" + "t_ref", "ms", "2ms", "Duration of refractory period" + "E_L", "mV", "-70mV", "Resting potential" + "V_reset", "mV", "-70mV - E_L", "Reset potential of the membrane" + "V_th", "mV", "-55mV - E_L", "Spike threshold" "I_e", "pA", "0pA", "constant external input current" @@ -116,8 +91,8 @@ State variables :widths: auto - "V_abs", "mV", "0mV", "" - "V_m", "mV", "V_abs + E_L", "Membrane potential." + "r", "integer", "0", "counts number of tick during the refractory period" + "V_abs", "mV", "0mV", "" @@ -129,7 +104,7 @@ Equations .. math:: - \frac{ dV_{abs} } { dt }= \frac{ -1 } { \Tau } \cdot V_{abs} + \frac{ 1 } { C_{m} } \cdot I + \frac{ dV_{abs} } { dt }= \frac{ -V_{abs} } { \tau_{m} } + \frac{ I } { C_{m} } @@ -138,42 +113,41 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_psc_alpha: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0mV - function V_m mV = V_abs + E_L # Membrane potential. end equations: - kernel I_kernel_in = pA * (e / tau_syn_in) * t * exp(-1 / tau_syn_in * t) - kernel I_kernel_ex = pA * (e / tau_syn_ex) * t * exp(-1 / tau_syn_ex * t) - function I pA = convolve(I_kernel_in,in_spikes) + convolve(I_kernel_ex,ex_spikes) + I_e + I_stim - V_abs'=-1 / Tau * V_abs + 1 / C_m * I + kernel I_kernel_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel I_kernel_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential + inline I pA = convolve(I_kernel_exc,exc_spikes) - convolve(I_kernel_inh,inh_spikes) + I_e + I_stim + V_abs'=-V_abs / tau_m + I / C_m end parameters: - C_m pF = 250pF # Capacity of the membrane - Tau ms = 10ms # Membrane time constant. - tau_syn_in ms = 2ms # Time constant of synaptic current. - tau_syn_ex ms = 2ms # Time constant of synaptic current. - t_ref ms = 2ms # Duration of refractory period. - E_L mV = -70mV # Resting potential. - function V_reset mV = -70mV - E_L # Reset potential of the membrane. - function Theta mV = -55mV - E_L # Spike threshold. - - /* constant external input current*/ + C_m pF = 250pF # Capacitance of the membrane + tau_m ms = 10ms # Membrane time constant + tau_syn_inh ms = 2ms # Time constant of synaptic current + tau_syn_exc ms = 2ms # Time constant of synaptic current + t_ref ms = 2ms # Duration of refractory period + E_L mV = -70mV # Resting potential + V_reset mV = -70mV - E_L # Reset potential of the membrane + V_th mV = -55mV - E_L # Spike threshold + # constant external input current + + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - ex_spikes pA <-excitatory spike - in_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike + inh_spikes pA <-inhibitory spike I_stim pA <-current end @@ -185,12 +159,11 @@ Source code else: r = r - 1 end - if V_abs >= Theta: # threshold crossing - - /* A supra-threshold membrane potential should never be observable.*/ - /* The reset at the time of threshold crossing enables accurate*/ - /* integration independent of the computation step size, see [2,3] for*/ - /* details.*/ + if V_abs >= V_th: # threshold crossing + # A supra-threshold membrane potential should never be observable. + # The reset at the time of threshold crossing enables accurate + # integration independent of the computation step size, see [2,3] for + # details. r = RefractoryCounts V_abs = V_reset emit_spike() @@ -209,4 +182,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.061053 + Generated at 2022-03-28 19:04:29.478484 \ No newline at end of file diff --git a/doc/models_library/iaf_psc_delta.rst b/doc/models_library/iaf_psc_delta.rst index 266ac3d80..0d20ced75 100644 --- a/doc/models_library/iaf_psc_delta.rst +++ b/doc/models_library/iaf_psc_delta.rst @@ -1,8 +1,8 @@ iaf_psc_delta ############# -iaf_psc_delta - Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents +iaf_psc_delta - Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents Description +++++++++++ @@ -52,11 +52,6 @@ See also iaf_psc_alpha, iaf_psc_exp -Authors -+++++++ - -Diesmann, Gewaltig (September 1999) - Parameters ++++++++++ @@ -90,8 +85,9 @@ State variables :widths: auto - "V_abs", "mV", "0mV", "" - "V_m", "mV", "V_abs + E_L", "Membrane potential." + "refr_spikes_buffer", "mV", "0mV", "" + "r", "integer", "0", "counts number of tick during the refractory period" + "V_abs", "mV", "0mV", "" @@ -103,7 +99,7 @@ Equations .. math:: - \frac{ dV_{abs} } { dt }= \frac{ -1 } { \tau_{m} } \cdot V_{abs} + \frac{ 1 } { C_{m} } \cdot (\text{convolve}(G, spikes) + I_{e} + I_{stim}) + \frac{ dV_{abs} } { dt }= \frac{ -V_{abs} } { \tau_{m} } + (\frac 1 { \mathrm{ms} } \left( { \frac{ \mathrm{mV} } { \mathrm{pA} } } \right) ) \cdot \text{convolve}(G, spikes) + \frac 1 { C_{m} } \left( { (I_{e} + I_{stim}) } \right) @@ -112,20 +108,18 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_psc_delta: state: refr_spikes_buffer mV = 0mV - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0mV - function V_m mV = V_abs + E_L # Membrane potential. end equations: - kernel G = delta(t,tau_m) - V_abs'=-1 / tau_m * V_abs + 1 / C_m * (convolve(G,spikes) + I_e + I_stim) + kernel G = delta(t) + recordable inline V_m mV = V_abs + E_L # Membrane potential. + V_abs'=-V_abs / tau_m + (mV / pA / ms) * convolve(G,spikes) + (I_e + I_stim) / C_m end parameters: @@ -134,12 +128,13 @@ Source code t_ref ms = 2ms # Duration of refractory period. tau_syn ms = 2ms # Time constant of synaptic current. E_L mV = -70mV # Resting membrane potential. - function V_reset mV = -70mV - E_L # Reset potential of the membrane. - function Theta mV = -55mV - E_L # Spike threshold. + V_reset mV = -70mV - E_L # Reset potential of the membrane. + Theta mV = -55mV - E_L # Spike threshold. V_min mV = -inf * 1mV # Absolute lower value for the membrane potential with_refr_input boolean = false # If true, do not discard input during refractory period. Default: false. + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: @@ -156,21 +151,18 @@ Source code update: if r == 0: # neuron not refractory integrate_odes() - - /* if we have accumulated spikes from refractory period,*/ - /* add and reset accumulator*/ + # if we have accumulated spikes from refractory period, + # add and reset accumulator if with_refr_input and refr_spikes_buffer != 0.0mV: V_abs += refr_spikes_buffer refr_spikes_buffer = 0.0mV end - - /* lower bound of membrane potential*/ + # lower bound of membrane potential V_abs = V_abs < V_min?V_min:V_abs else: - - /* read spikes from buffer and accumulate them, discounting*/ - /* for decay until end of refractory period*/ - /* the buffer is clear automatically*/ + # read spikes from buffer and accumulate them, discounting + # for decay until end of refractory period + # the buffer is clear automatically if with_refr_input: refr_spikes_buffer += spikes * exp(-r * h / tau_m) * mV / pA end @@ -195,4 +187,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.171065 + Generated at 2022-03-28 19:04:29.888326 \ No newline at end of file diff --git a/doc/models_library/iaf_psc_exp.rst b/doc/models_library/iaf_psc_exp.rst index 1de2c1407..0d0024fcd 100644 --- a/doc/models_library/iaf_psc_exp.rst +++ b/doc/models_library/iaf_psc_exp.rst @@ -1,8 +1,8 @@ iaf_psc_exp ########### -iaf_psc_exp - Leaky integrate-and-fire neuron model with exponential PSCs +iaf_psc_exp - Leaky integrate-and-fire neuron model with exponential PSCs Description +++++++++++ @@ -16,7 +16,7 @@ during which the membrane potential is clamped to the resting potential and spiking is prohibited. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -38,11 +38,6 @@ See also iaf_cond_exp -Author -++++++ - -Moritz Helias - Parameters ++++++++++ @@ -54,14 +49,14 @@ Parameters :widths: auto - "C_m", "pF", "250pF", "Capacity of the membrane" - "tau_m", "ms", "10ms", "Membrane time constant." - "tau_syn_in", "ms", "2ms", "Time constant of synaptic current." - "tau_syn_ex", "ms", "2ms", "Time constant of synaptic current." + "C_m", "pF", "250pF", "Capacitance of the membrane" + "tau_m", "ms", "10ms", "Membrane time constant" + "tau_syn_inh", "ms", "2ms", "Time constant of inhibitory synaptic current" + "tau_syn_exc", "ms", "2ms", "Time constant of excitatory synaptic current" "t_ref", "ms", "2ms", "Duration of refractory period" - "E_L", "mV", "-70mV", "Resting potential." - "V_reset", "mV", "-70mV - E_L", "reset value of the membrane potential" - "Theta", "mV", "-55mV - E_L", "Threshold, RELATIVE TO RESTING POTENTIAL(!)." + "E_L", "mV", "-70mV", "Resting potential" + "V_reset", "mV", "-70mV - E_L", "Reset value of the membrane potential" + "Theta", "mV", "-55mV - E_L", "Threshold, RELATIVE TO RESTING POTENTIAL (!)" "I_e", "pA", "0pA", "constant external input current" @@ -75,8 +70,8 @@ State variables :widths: auto - "V_abs", "mV", "0mV", "" - "V_m", "mV", "V_abs + E_L", "Membrane potential." + "r", "integer", "0", "counts number of tick during the refractory period" + "V_abs", "mV", "0mV", "" @@ -97,43 +92,41 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_psc_exp: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0mV - function V_m mV = V_abs + E_L # Membrane potential. end equations: - kernel I_kernel_in = exp(-t / tau_syn_in) - kernel I_kernel_ex = exp(-t / tau_syn_ex) - function I_syn pA = convolve(I_kernel_in,in_spikes) + convolve(I_kernel_ex,ex_spikes) + kernel I_kernel_inh = exp(-t / tau_syn_inh) + kernel I_kernel_exc = exp(-t / tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential + inline I_syn pA = convolve(I_kernel_exc,exc_spikes) - convolve(I_kernel_inh,inh_spikes) V_abs'=-V_abs / tau_m + (I_syn + I_e + I_stim) / C_m end parameters: - C_m pF = 250pF # Capacity of the membrane - tau_m ms = 10ms # Membrane time constant. - tau_syn_in ms = 2ms # Time constant of synaptic current. - tau_syn_ex ms = 2ms # Time constant of synaptic current. + C_m pF = 250pF # Capacitance of the membrane + tau_m ms = 10ms # Membrane time constant + tau_syn_inh ms = 2ms # Time constant of inhibitory synaptic current + tau_syn_exc ms = 2ms # Time constant of excitatory synaptic current t_ref ms = 2ms # Duration of refractory period - E_L mV = -70mV # Resting potential. - function V_reset mV = -70mV - E_L # reset value of the membrane potential - function Theta mV = -55mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL(!). - /* I.e. the real threshold is (E_L_+V_th_)*/ + E_L mV = -70mV # Resting potential + V_reset mV = -70mV - E_L # Reset value of the membrane potential + Theta mV = -55mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!) + # I.e. the real threshold is (E_L + Theta) - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - ex_spikes pA <-excitatory spike - in_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike + inh_spikes pA <-inhibitory spike I_stim pA <-current end @@ -164,4 +157,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.688938 + Generated at 2022-03-28 19:16:43.533857 \ No newline at end of file diff --git a/doc/models_library/iaf_psc_exp_dend.rst b/doc/models_library/iaf_psc_exp_dend.rst new file mode 100644 index 000000000..85392b2e7 --- /dev/null +++ b/doc/models_library/iaf_psc_exp_dend.rst @@ -0,0 +1,163 @@ +iaf_psc_exp_dend +################ + + +iaf_psc_exp_dend - Leaky integrate-and-fire neuron model with exponential PSCs + +Description ++++++++++++ + +iaf_psc_exp is an implementation of a leaky integrate-and-fire model +with exponential-kernel postsynaptic currents (PSCs) according to [1]_. +Thus, postsynaptic currents have an infinitely short rise time. + +The threshold crossing is followed by an absolute refractory period (t_ref) +during which the membrane potential is clamped to the resting potential +and spiking is prohibited. + +.. note:: + If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + may arise due to singularities in the propagator matrics. If this is + the case, replace equal-valued parameters by a single parameter. + + For details, please see ``IAF_neurons_singularity.ipynb`` in + the NEST source code (``docs/model_details``). + + +References +++++++++++ + +.. [1] Tsodyks M, Uziel A, Markram H (2000). Synchrony generation in recurrent + networks with frequency-dependent synapses. The Journal of Neuroscience, + 20,RC50:1-5. URL: https://infoscience.epfl.ch/record/183402 + + +See also +++++++++ + +iaf_cond_exp + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "C_m", "pF", "250pF", "Capacity of the membrane" + "tau_m", "ms", "10ms", "Membrane time constant" + "tau_syn_inh", "ms", "2ms", "Time constant of inhibitory synaptic current" + "tau_syn_exc", "ms", "2ms", "Time constant of excitatory synaptic current" + "t_ref", "ms", "2ms", "Duration of refractory period" + "E_L", "mV", "-70mV", "Resting potential" + "V_reset", "mV", "-70mV - E_L", "reset value of the membrane potential" + "Theta", "mV", "-55mV - E_L", "Threshold, RELATIVE TO RESTING POTENTIAL (!)." + "I_e", "pA", "0pA", "constant external input current" + + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "r", "integer", "0", "counts number of tick during the refractory period" + "V_abs", "mV", "0mV", "" + "I_dend", "pA", "0pA", "third factor, to be read out by synapse during weight update" + + + + +Equations ++++++++++ + + + + +.. math:: + \frac{ dV_{abs} } { dt }= \frac{ -V_{abs} } { \tau_{m} } + \frac 1 { C_{m} } \left( { (I_{syn} + I_{e} + I_{stim}) } \right) + + + + + +Source code ++++++++++++ + +.. code-block:: nestml + + neuron iaf_psc_exp_dend: + state: + r integer = 0 # counts number of tick during the refractory period + V_abs mV = 0mV + I_dend pA = 0pA # third factor, to be read out by synapse during weight update + end + equations: + kernel I_kernel_inh = exp(-t / tau_syn_inh) + kernel I_kernel_exc = exp(-t / tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential. + inline I_syn pA = convolve(I_kernel_exc,exc_spikes) - convolve(I_kernel_inh,inh_spikes) + V_abs'=-V_abs / tau_m + (I_syn + I_e + I_stim) / C_m + end + + parameters: + C_m pF = 250pF # Capacity of the membrane + tau_m ms = 10ms # Membrane time constant + tau_syn_inh ms = 2ms # Time constant of inhibitory synaptic current + tau_syn_exc ms = 2ms # Time constant of excitatory synaptic current + t_ref ms = 2ms # Duration of refractory period + E_L mV = -70mV # Resting potential + V_reset mV = -70mV - E_L # reset value of the membrane potential + Theta mV = -55mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!). + # I.e. the real threshold is (E_L_+V_th_) + + # constant external input current + I_e pA = 0pA + end + internals: + RefractoryCounts integer = steps(t_ref) # refractory time in steps + end + input: + exc_spikes pA <-excitatory spike + inh_spikes pA <-inhibitory spike + I_stim pA <-current + end + + output: spike + + update: + I_dend *= 0.95 + if r == 0: # neuron not refractory, so evolve V + integrate_odes() + else: + r = r - 1 # neuron is absolute refractory + end + if V_abs >= Theta: # threshold crossing + r = RefractoryCounts + V_abs = V_reset + emit_spike() + end + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: iaf_psc_exp_dend_characterisation.rst + + +.. footer:: + + Generated at 2022-03-28 19:04:29.801538 \ No newline at end of file diff --git a/doc/models_library/iaf_psc_exp_htum.rst b/doc/models_library/iaf_psc_exp_htum.rst index 3559451b2..093613630 100644 --- a/doc/models_library/iaf_psc_exp_htum.rst +++ b/doc/models_library/iaf_psc_exp_htum.rst @@ -1,8 +1,8 @@ iaf_psc_exp_htum ################ -iaf_psc_exp_htum - Leaky integrate-and-fire model with separate relative and absolute refractory period +iaf_psc_exp_htum - Leaky integrate-and-fire model with separate relative and absolute refractory period Description +++++++++++ @@ -22,7 +22,7 @@ larger or equal to the absolute refractory time. If equal, the refractoriness of the model if equivalent to the other models of NEST. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -48,10 +48,6 @@ References networks. Neurocomputing 38-40:565-571. DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -Author -++++++ - -Moritz Helias (March 2006) Parameters @@ -64,15 +60,15 @@ Parameters :widths: auto - "C_m", "pF", "250pF", "Capacity of the membrane" - "tau_m", "ms", "10ms", "Membrane time constant." - "tau_syn_in", "ms", "2ms", "Time constant of synaptic current." - "tau_syn_ex", "ms", "2ms", "Time constant of synaptic current." - "t_ref_abs", "ms", "2ms", "absolute refractory period." - "t_ref_tot", "ms", "2ms", "total refractory periodif t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_exp" - "E_L", "mV", "-70mV", "Resting potential." + "C_m", "pF", "250pF", "Capacitance of the membrane" + "tau_m", "ms", "10ms", "Membrane time constant" + "tau_syn_inh", "ms", "2ms", "Time constant of inhibitory synaptic current" + "tau_syn_exc", "ms", "2ms", "Time constant of excitatory synaptic current" + "t_ref_abs", "ms", "2ms", "Absolute refractory period" + "t_ref_tot", "ms", "2ms", "total refractory period" + "E_L", "mV", "-70mV", "if t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_expResting potential" "V_reset", "mV", "-70.0mV - E_L", "Reset value of the membrane potential" - "V_th", "mV", "-55.0mV - E_L", "RELATIVE TO RESTING POTENTIAL(!).I.e. the real threshold is (V_reset + E_L).Threshold, RELATIVE TO RESTING POTENTIAL(!)." + "V_th", "mV", "-55.0mV - E_L", "RELATIVE TO RESTING POTENTIAL(!)I.e. the real threshold is (V_reset + E_L).Threshold, RELATIVE TO RESTING POTENTIAL(!)" "I_e", "pA", "0pA", "constant external input current" @@ -86,6 +82,8 @@ State variables :widths: auto + "r_tot", "integer", "0", "" + "r_abs", "integer", "0", "" "V_m", "mV", "0.0mV", "Membrane potential" @@ -107,70 +105,66 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron iaf_psc_exp_htum: state: r_tot integer = 0 r_abs integer = 0 - end - initial_values: V_m mV = 0.0mV # Membrane potential end equations: - kernel I_kernel_in = exp(-1 / tau_syn_in * t) - kernel I_kernel_ex = exp(-1 / tau_syn_ex * t) - function I_syn pA = convolve(I_kernel_in,in_spikes) + convolve(I_kernel_ex,ex_spikes) + kernel I_kernel_inh = exp(-t / tau_syn_inh) + kernel I_kernel_exc = exp(-t / tau_syn_exc) + inline I_syn pA = convolve(I_kernel_exc,exc_spikes) - convolve(I_kernel_inh,inh_spikes) V_m'=-V_m / tau_m + (I_syn + I_e + I_stim) / C_m end parameters: - C_m pF = 250pF # Capacity of the membrane - tau_m ms = 10ms # Membrane time constant. - tau_syn_in ms = 2ms # Time constant of synaptic current. - tau_syn_ex ms = 2ms # Time constant of synaptic current. - t_ref_abs ms = 2ms # absolute refractory period. - /* total refractory period*/ - - /* total refractory period*/ - t_ref_tot ms = 2ms [[t_ref_tot >= t_ref_abs]] # if t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_exp - E_L mV = -70mV # Resting potential. - function V_reset mV = -70.0mV - E_L # Reset value of the membrane potential - /* RELATIVE TO RESTING POTENTIAL(!).*/ - /* I.e. the real threshold is (V_reset + E_L).*/ - - /* RELATIVE TO RESTING POTENTIAL(!).*/ - /* I.e. the real threshold is (V_reset + E_L).*/ - function V_th mV = -55.0mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL(!). - /* I.e. the real threshold is (E_L+V_th).*/ - - /* constant external input current*/ + C_m pF = 250pF # Capacitance of the membrane + tau_m ms = 10ms # Membrane time constant + tau_syn_inh ms = 2ms # Time constant of inhibitory synaptic current + tau_syn_exc ms = 2ms # Time constant of excitatory synaptic current + t_ref_abs ms = 2ms # Absolute refractory period + t_ref_tot ms = 2ms [[t_ref_tot >= t_ref_abs]] # total refractory period + # if t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_exp + + # if t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_exp + E_L mV = -70mV # Resting potential + V_reset mV = -70.0mV - E_L # Reset value of the membrane potential + # RELATIVE TO RESTING POTENTIAL(!) + # I.e. the real threshold is (V_reset + E_L). + + # RELATIVE TO RESTING POTENTIAL(!) + # I.e. the real threshold is (V_reset + E_L). + V_th mV = -55.0mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL(!) + # I.e. the real threshold is (E_L + V_th) + + # constant external input current I_e pA = 0pA end internals: - - /* TauR specifies the length of the absolute refractory period as*/ - /* a double_t in ms. The grid based iaf_psc_exp_htum can only handle refractory*/ - /* periods that are integer multiples of the computation step size (h).*/ - /* To ensure consistency with the overall simulation scheme such conversion*/ - /* should be carried out via objects of class nest::Time. The conversion*/ - /* requires 2 steps:*/ - /* 1. A time object r is constructed defining representation of*/ - /* TauR in tics. This representation is then converted to computation*/ - /* time steps again by a strategy defined by class nest::Time.*/ - /* 2. The refractory time in units of steps is read out get_steps(), a*/ - /* member function of class nest::Time.*/ - /**/ - /* Choosing a TauR that is not an integer multiple of the computation time*/ - /* step h will leed to accurate (up to the resolution h) and self-consistent*/ - /* results. However, a neuron model capable of operating with real valued*/ - /* spike time may exhibit a different effective refractory time.*/ + # TauR specifies the length of the absolute refractory period as + # a double_t in ms. The grid based iaf_psc_exp_htum can only handle refractory + # periods that are integer multiples of the computation step size (h). + # To ensure consistency with the overall simulation scheme such conversion + # should be carried out via objects of class nest::Time. The conversion + # requires 2 steps: + # 1. A time object r is constructed defining representation of + # TauR in tics. This representation is then converted to computation + # time steps again by a strategy defined by class nest::Time. + # 2. The refractory time in units of steps is read out get_steps(), a + # member function of class nest::Time. + # Choosing a TauR that is not an integer multiple of the computation time + # step h will leed to accurate (up to the resolution h) and self-consistent + # results. However, a neuron model capable of operating with real valued + # spike time may exhibit a different effective refractory time. RefractoryCountsAbs integer = steps(t_ref_abs) [[RefractoryCountsAbs > 0]] RefractoryCountsTot integer = steps(t_ref_tot) [[RefractoryCountsTot > 0]] end input: - ex_spikes pA <-excitatory spike - in_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike + inh_spikes pA <-inhibitory spike I_stim pA <-current end @@ -206,4 +200,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.972470 + Generated at 2022-03-28 19:04:30.127400 \ No newline at end of file diff --git a/doc/models_library/index.rst b/doc/models_library/index.rst index 183319238..c95819a56 100644 --- a/doc/models_library/index.rst +++ b/doc/models_library/index.rst @@ -1,11 +1,16 @@ Models library ============== +Neuron models +~~~~~~~~~~~~~ + :doc:`iaf_psc_delta ` ------------------------------------ -Source file: `iaf_psc_delta.nestml `_ +Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents + +Source file: `iaf_psc_delta.nestml `_ .. list-table:: @@ -19,7 +24,9 @@ Source file: `iaf_psc_delta.nestml ` -------------------------------- -Source file: `iaf_psc_exp.nestml `_ +Leaky integrate-and-fire neuron model with exponential PSCs + +Source file: `iaf_psc_exp.nestml `_ .. list-table:: @@ -33,7 +40,9 @@ Source file: `iaf_psc_exp.nestml ` ------------------------------------ -Source file: `iaf_psc_alpha.nestml `_ +Leaky integrate-and-fire neuron model + +Source file: `iaf_psc_alpha.nestml `_ .. list-table:: @@ -47,7 +56,9 @@ Source file: `iaf_psc_alpha.nestml ` ---------------------------------- -Source file: `iaf_cond_exp.nestml `_ +Simple conductance based leaky integrate-and-fire neuron model + +Source file: `iaf_cond_exp.nestml `_ .. list-table:: @@ -61,7 +72,9 @@ Source file: `iaf_cond_exp.nestml ` -------------------------------------- -Source file: `iaf_cond_alpha.nestml `_ +Simple conductance based leaky integrate-and-fire neuron model + +Source file: `iaf_cond_alpha.nestml `_ .. list-table:: @@ -75,7 +88,9 @@ Source file: `iaf_cond_alpha.nestml ` ------------------------------------ -Source file: `iaf_cond_beta.nestml `_ +Simple conductance based leaky integrate-and-fire neuron model + +Source file: `iaf_cond_beta.nestml `_ .. list-table:: @@ -89,7 +104,9 @@ Source file: `iaf_cond_beta.nestml ` ------------------------------ -Source file: `izhikevich.nestml `_ +Izhikevich neuron model + +Source file: `izhikevich.nestml `_ .. list-table:: @@ -103,7 +120,9 @@ Source file: `izhikevich.nestml ` ---------------------------------- -Source file: `hh_psc_alpha.nestml `_ +Hodgkin-Huxley neuron model + +Source file: `hh_psc_alpha.nestml `_ .. list-table:: @@ -117,7 +136,9 @@ Source file: `hh_psc_alpha.nestml ` ------------------------------------ -Source file: `iaf_chxk_2008.nestml `_ +Conductance based leaky integrate-and-fire neuron model used in Casti et al. 2008 + +Source file: `iaf_chxk_2008.nestml `_ .. list-table:: @@ -128,91 +149,229 @@ Source file: `iaf_chxk_2008.nestml ` --------------------------------------------------- +:doc:`aeif_cond_exp ` +------------------------------------ + +Conductance based exponential integrate-and-fire neuron model + +Source file: `aeif_cond_exp.nestml `_ -Source file: `hh_cond_exp_destexhe.nestml `_ +.. list-table:: + + * - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response_small.png + :alt: aeif_cond_exp + + - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve_small.png + :alt: aeif_cond_exp :doc:`aeif_cond_alpha ` ---------------------------------------- -Source file: `aeif_cond_alpha.nestml `_ +Conductance based exponential integrate-and-fire neuron model +Source file: `aeif_cond_alpha.nestml `_ -:doc:`izhikevich_psc_alpha ` --------------------------------------------------- +.. list-table:: -Source file: `izhikevich_psc_alpha.nestml `_ + * - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response_small.png + :alt: aeif_cond_alpha + - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve_small.png + :alt: aeif_cond_alpha -:doc:`hh_cond_exp_traub ` --------------------------------------------- -Source file: `hh_cond_exp_traub.nestml `_ +:doc:`terub_gpe ` +---------------------------- +Terman Rubin neuron model -:doc:`iaf_psc_exp_htum ` +Source file: `terub_gpe.nestml `_ + + +:doc:`traub_cond_multisyn ` +------------------------------------------------ + +Traub model according to Borgers 2017 + +Source file: `traub_cond_multisyn.nestml `_ + + +:doc:`mat2_psc_exp ` ---------------------------------- -Source file: `iaf_psc_exp_htum.nestml `_ +Non-resetting leaky integrate-and-fire neuron model with exponential PSCs and adaptive threshold + +Source file: `mat2_psc_exp.nestml `_ + + +:doc:`hill_tononi ` +-------------------------------- + +Neuron model after Hill & Tononi (2005) + +Source file: `hill_tononi.nestml `_ + + +:doc:`hh_cond_exp_traub ` +-------------------------------------------- + +Hodgkin-Huxley model for Brette et al (2007) review + +Source file: `hh_cond_exp_traub.nestml `_ :doc:`iaf_cond_exp_sfa_rr ` ------------------------------------------------ -Source file: `iaf_cond_exp_sfa_rr.nestml `_ +Conductance based leaky integrate-and-fire model with spike-frequency adaptation and relative refractory mechanisms +Source file: `iaf_cond_exp_sfa_rr.nestml `_ -:doc:`terub_gpe ` ----------------------------- -Source file: `terub_gpe.nestml `_ +:doc:`traub_psc_alpha ` +---------------------------------------- + +Traub model according to Borgers 2017 +Source file: `traub_psc_alpha.nestml `_ -:doc:`aeif_cond_exp ` ------------------------------------- -Source file: `aeif_cond_exp.nestml `_ +:doc:`iaf_psc_exp_dend ` +------------------------------------------ + +Leaky integrate-and-fire neuron model with exponential PSCs + +Source file: `iaf_psc_exp_dend.nestml `_ + + +:doc:`wb_cond_exp ` +-------------------------------- + +Wang-Buzsaki model + +Source file: `wb_cond_exp.nestml `_ + + +:doc:`hh_cond_exp_destexhe ` +-------------------------------------------------- + +Hodgin Huxley based model, Traub, Destexhe and Mainen modified + +Source file: `hh_cond_exp_destexhe.nestml `_ :doc:`terub_stn ` ---------------------------- -Source file: `terub_stn.nestml `_ +Terman Rubin neuron model +Source file: `terub_stn.nestml `_ -:doc:`hill_tononi ` --------------------------------- -Source file: `hill_tononi.nestml `_ +:doc:`iaf_psc_exp_htum ` +------------------------------------------ +Leaky integrate-and-fire model with separate relative and absolute refractory period -:doc:`mat2_psc_exp ` ----------------------------------- +Source file: `iaf_psc_exp_htum.nestml `_ -Source file: `mat2_psc_exp.nestml `_ +:doc:`izhikevich_psc_alpha ` +-------------------------------------------------- -:doc:`traub_cond_multisyn ` ----------------------------------- +Detailed Izhikevich neuron model with alpha-kernel post-synaptic current -Source file: `traub_cond_multisyn.nestml `_ +Source file: `izhikevich_psc_alpha.nestml `_ -:doc:`traub_psc_alpha ` ----------------------------------- +:doc:`wb_cond_multisyn ` +------------------------------------------ -Source file: `traub_psc_alpha.nestml `_ +Wang-Buzsaki model with multiple synapses +Source file: `wb_cond_multisyn.nestml `_ -:doc:`wb_cond_exp ` +Synapse models +~~~~~~~~~~~~~~ + + +:doc:`static ` +---------------------- + +Static synapse + +Source file: `static_synapse.nestml `_ + + +:doc:`noisy_synapse ` +------------------------------------ + +Static synapse with Gaussian noise + +Source file: `noisy_synapse.nestml `_ + + +:doc:`stdp ` +------------------ + +Synapse model for spike-timing dependent plasticity + +Source file: `stdp_synapse.nestml `_ + + +:doc:`stdp_nn_pre_centered ` +-------------------------------------------------- + +Synapse type for spike-timing dependent plasticity, with nearest-neighbour spike pairing + +Source file: `stdp_nn_pre_centered.nestml `_ + + +:doc:`stdp_nn_restr_symm ` +---------------------------------------------- + +Synapse type for spike-timing dependent plasticity with restricted symmetric nearest-neighbour spike pairing scheme + +Source file: `stdp_nn_restr_symm.nestml `_ + + +:doc:`stdp_nn_symm ` ---------------------------------- -Source file: `wb_cond_exp.nestml `_ +Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing scheme +Source file: `stdp_nn_symm.nestml `_ -:doc:`wb_cond_multisyn ` + +:doc:`stdp_triplet_nn ` +---------------------------------------- + +Synapse type with triplet spike-timing dependent plasticity + +Source file: `triplet_stdp_synapse.nestml `_ + + +:doc:`stdp_triplet ` ---------------------------------- -Source file: `wb_cond_multisyn.nestml `_ +Synapse type with triplet spike-timing dependent plasticity + +Source file: `stdp_triplet_naive.nestml `_ + + +:doc:`third_factor_stdp ` +-------------------------------------------- + +Synapse model for spike-timing dependent plasticity with postsynaptic third-factor modulation + +Source file: `third_factor_stdp_synapse.nestml `_ + + +:doc:`neuromodulated_stdp ` +------------------------------------------------ + +Synapse model for spike-timing dependent plasticity modulated by a neurotransmitter such as dopamine + +Source file: `neuromodulated_stdp.nestml `_ + diff --git a/doc/models_library/izhikevich.rst b/doc/models_library/izhikevich.rst index f57c3e6b2..e1e5ceb3e 100644 --- a/doc/models_library/izhikevich.rst +++ b/doc/models_library/izhikevich.rst @@ -1,8 +1,8 @@ izhikevich ########## -izhikevich - Izhikevich neuron model +izhikevich - Izhikevich neuron model Description +++++++++++ @@ -31,18 +31,13 @@ As published in [1]_, the numerics differs from the standard forward Euler techn This model will instead be simulated using the numerical solver that is recommended by ODE-toolbox during code generation. -Authors -+++++++ - -Hanuschkin, Morrison, Kunkel - - References ++++++++++ .. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 + Parameters ++++++++++ @@ -57,7 +52,7 @@ Parameters "b", "real", "0.2", "sensitivity of recovery variable" "c", "mV", "-65mV", "after-spike reset value of V_m" "d", "real", "8.0", "after-spike reset value of U_m" - "V_m_init", "mV", "-70mV", "initial membrane potential" + "V_m_init", "mV", "-65mV", "initial membrane potential" "V_min", "mV", "-inf * mV", "Absolute lower value for the membrane potential." "I_e", "pA", "0pA", "constant external input current" @@ -98,10 +93,10 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron izhikevich: - initial_values: + state: V_m mV = V_m_init # Membrane potential U_m real = b * V_m_init # Membrane potential recovery variable end @@ -115,10 +110,11 @@ Source code b real = 0.2 # sensitivity of recovery variable c mV = -65mV # after-spike reset value of V_m d real = 8.0 # after-spike reset value of U_m - V_m_init mV = -70mV # initial membrane potential + V_m_init mV = -65mV # initial membrane potential V_min mV = -inf * mV # Absolute lower value for the membrane potential. + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end input: @@ -130,15 +126,13 @@ Source code update: integrate_odes() - /* Add synaptic current*/ + # Add synaptic current - /* Add synaptic current*/ + # Add synaptic current V_m += spikes - - /* lower bound of membrane potential*/ + # lower bound of membrane potential V_m = (V_m < V_min)?V_min:V_m - - /* threshold crossing*/ + # threshold crossing if V_m >= 30mV: V_m = c U_m += d @@ -158,4 +152,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.928927 \ No newline at end of file + Generated at 2022-03-28 19:04:28.623142 \ No newline at end of file diff --git a/doc/models_library/izhikevich_psc_alpha.rst b/doc/models_library/izhikevich_psc_alpha.rst index cc477ba72..843d20237 100644 --- a/doc/models_library/izhikevich_psc_alpha.rst +++ b/doc/models_library/izhikevich_psc_alpha.rst @@ -1,49 +1,8 @@ izhikevich_psc_alpha #################### -izhikevich_psc_alpha - Detailed Izhikevich neuron model with alpha-kernel post-synaptic current -Description -+++++++++++ - -Implementation of the simple spiking neuron model introduced by Izhikevich [1]_, with membrane potential in (milli)volt -and current-based synapses. - -The dynamics are given by: - -.. math:: - - C_m \frac{dV_m}{dt} = k (V - V_t)(V - V_t) - u + I + I_{syn,ex} + I_{syn,in} - \frac{dU_m}{dt} = a(b(V_m - E_L) - U_m) - - &\text{if}\;\;\; V_m \geq V_{th}:\\ - &\;\;\;\; V_m \text{ is set to } c - &\;\;\;\; U_m \text{ is incremented by } d - -On each spike arrival, the membrane potential is subject to an alpha-kernel current of the form: - -.. math:: - - I_syn = I_0 \cdot t \cdot \exp\left(-t/\tau_{syn}\right) / \tau_{syn} - -See also -++++++++ - -izhikevich, iaf_psc_alpha - - -References -++++++++++ - -.. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 - - -Authors -+++++++ - -Hanuschkin, Morrison, Kunkel - Parameters ++++++++++ @@ -55,18 +14,18 @@ Parameters :widths: auto - "C_m", "pF", "200.0pF", "Membrane capacitance" - "k", "pF / (ms mV)", "8.0pF / mV / ms", "Spiking slope" - "V_r", "mV", "-65.0mV", "resting potential" - "V_t", "mV", "-45.0mV", "threshold potential" - "a", "1 / ms", "0.01 / ms", "describes time scale of recovery variable" - "b", "nS", "9.0nS", "sensitivity of recovery variable" - "c", "mV", "-65mV", "after-spike reset value of V_m" - "d", "pA", "60.0pA", "after-spike reset value of U_m" - "V_peak", "mV", "0.0mV", "Spike detection threashold (reset condition)" - "tau_syn_ex", "ms", "0.2ms", "Synaptic Time Constant Excitatory Synapse" - "tau_syn_in", "ms", "2.0ms", "Synaptic Time Constant for Inhibitory Synapse" - "t_ref", "ms", "2.0ms", "Refractory period" + "C_m", "pF", "200pF", "Membrane capacitance" + "k", "pF / (ms mV)", "8pF / mV / ms", "Spiking slope" + "V_r", "mV", "-65mV", "Resting potential" + "V_t", "mV", "-45mV", "Threshold potential" + "a", "1 / ms", "0.01 / ms", "Time scale of recovery variable" + "b", "nS", "9nS", "Sensitivity of recovery variable" + "c", "mV", "-65mV", "After-spike reset value of V_m" + "d", "pA", "60pA", "After-spike reset value of U_m" + "V_peak", "mV", "0mV", "Spike detection threshold (reset condition)" + "tau_syn_exc", "ms", "0.2ms", "Synaptic time constant of excitatory synapse" + "tau_syn_inh", "ms", "2ms", "Synaptic time constant of inhibitory synapse" + "t_ref", "ms", "2ms", "Refractory period" "I_e", "pA", "0pA", "constant external input current" @@ -80,6 +39,7 @@ State variables :widths: auto + "r", "integer", "0", "Number of steps in the current refractory phase" "V_m", "mV", "-65mV", "Membrane potential" "U_m", "pA", "0pA", "Membrane potential recovery variable" @@ -93,7 +53,7 @@ Equations .. math:: - \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (k \cdot (V_{m} - V_{r}) \cdot (V_{m} - V_{t}) - U_{m} + I_{e} + I_{stim} + I_{syn,inh} + I_{syn,exc}) } \right) + \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (k \cdot (V_{m} - V_{r}) \cdot (V_{m} - V_{t}) - U_{m} + I_{e} + I_{stim} + I_{syn,exc} - I_{syn,inh}) } \right) .. math:: @@ -106,50 +66,48 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron izhikevich_psc_alpha: state: - r integer # number of steps in the current refractory phase - end - initial_values: + r integer = 0 # Number of steps in the current refractory phase V_m mV = -65mV # Membrane potential U_m pA = 0pA # Membrane potential recovery variable end equations: - - /* synapses: alpha functions*/ - kernel I_syn_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel I_syn_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - function I_syn_exc pA = convolve(I_syn_ex,spikesExc) - function I_syn_inh pA = convolve(I_syn_in,spikesInh) - V_m'=(k * (V_m - V_r) * (V_m - V_t) - U_m + I_e + I_stim + I_syn_inh + I_syn_exc) / C_m + # synapses: alpha functions + kernel K_syn_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel K_syn_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + inline I_syn_exc pA = convolve(K_syn_exc,exc_spikes) + inline I_syn_inh pA = convolve(K_syn_inh,inh_spikes) + V_m'=(k * (V_m - V_r) * (V_m - V_t) - U_m + I_e + I_stim + I_syn_exc - I_syn_inh) / C_m U_m'=a * (b * (V_m - V_r) - U_m) end parameters: - C_m pF = 200.0pF # Membrane capacitance - k pF/mV/ms = 8.0pF / mV / ms # Spiking slope - V_r mV = -65.0mV # resting potential - V_t mV = -45.0mV # threshold potential - a 1/ms = 0.01 / ms # describes time scale of recovery variable - b nS = 9.0nS # sensitivity of recovery variable - c mV = -65mV # after-spike reset value of V_m - d pA = 60.0pA # after-spike reset value of U_m - V_peak mV = 0.0mV # Spike detection threashold (reset condition) - tau_syn_ex ms = 0.2ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 2.0ms # Synaptic Time Constant for Inhibitory Synapse - t_ref ms = 2.0ms # Refractory period - - /* constant external input current*/ + C_m pF = 200pF # Membrane capacitance + k pF/mV/ms = 8pF / mV / ms # Spiking slope + V_r mV = -65mV # Resting potential + V_t mV = -45mV # Threshold potential + a 1/ms = 0.01 / ms # Time scale of recovery variable + b nS = 9nS # Sensitivity of recovery variable + c mV = -65mV # After-spike reset value of V_m + d pA = 60pA # After-spike reset value of U_m + V_peak mV = 0mV # Spike detection threshold (reset condition) + tau_syn_exc ms = 0.2ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 2ms # Synaptic time constant of inhibitory synapse + t_ref ms = 2ms # Refractory period + # constant external input current + + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - spikesInh pA <-inhibitory spike - spikesExc pA <-excitatory spike + inh_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike I_stim pA <-current end @@ -157,8 +115,7 @@ Source code update: integrate_odes() - - /* refractoriness and threshold crossing*/ + # refractoriness and threshold crossing if r > 0: # is refractory? r -= 1 elif V_m >= V_peak: @@ -181,4 +138,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.646052 + Generated at 2022-03-28 19:04:30.156838 \ No newline at end of file diff --git a/doc/models_library/lorenz_attractor.rst b/doc/models_library/lorenz_attractor.rst new file mode 100644 index 000000000..35748aec0 --- /dev/null +++ b/doc/models_library/lorenz_attractor.rst @@ -0,0 +1,98 @@ +lorenz_attractor +################ + + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "sigma", "real", "10", "" + "beta", "real", "8 / 3", "" + "rho", "real", "28", "" + + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "x", "real", "1", "" + "y", "real", "1", "" + "z", "real", "1", "" + + + + +Equations ++++++++++ + + + + +.. math:: + \frac{ dx } { dt }= \frac{ \sigma \cdot (y - x) } { \mathrm{s} } + + +.. math:: + \frac{ dy } { dt }= \frac{ (x \cdot (\rho - z) - y) } { \mathrm{s} } + + +.. math:: + \frac{ dz } { dt }= \frac{ (x \cdot y - \beta \cdot z) } { \mathrm{s} } + + + + + +Source code ++++++++++++ + +.. code-block:: nestml + + neuron lorenz_attractor: + state: + x real = 1 + y real = 1 + z real = 1 + end + equations: + x'=sigma * (y - x) / s + y'=(x * (rho - z) - y) / s + z'=(x * y - beta * z) / s + end + + update: + integrate_odes() + end + + parameters: + sigma real = 10 + beta real = 8 / 3 + rho real = 28 + end + end + + + +Characterisation +++++++++++++++++ + +.. include:: lorenz_attractor_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:32.491153 \ No newline at end of file diff --git a/doc/models_library/mat2_psc_exp.rst b/doc/models_library/mat2_psc_exp.rst index c063715ab..e4a91bbce 100644 --- a/doc/models_library/mat2_psc_exp.rst +++ b/doc/models_library/mat2_psc_exp.rst @@ -1,8 +1,8 @@ mat2_psc_exp ############ -mat2_psc_exp - Non-resetting leaky integrate-and-fire neuron model with exponential PSCs and adaptive threshold +mat2_psc_exp - Non-resetting leaky integrate-and-fire neuron model with exponential PSCs and adaptive threshold Description +++++++++++ @@ -20,7 +20,7 @@ potential exceeds the threshold. The membrane potential is NOT reset, but continuously integrated. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -44,10 +44,6 @@ References threshold. Frontiers in Computuational Neuroscience 3:9. DOI: https://doi.org/10.3389/neuro.10.009.2009 -Author -++++++ - -Thomas Pfeil (modified iaf_psc_exp model of Moritz Helias) Parameters @@ -61,16 +57,16 @@ Parameters "tau_m", "ms", "5ms", "Membrane time constant" - "C_m", "pF", "100pF", "Capacity of the membrane" + "C_m", "pF", "100pF", "Capacitance of the membrane" "t_ref", "ms", "2ms", "Duration of absolute refractory period (no spiking)" - "E_L", "mV", "-70.0mV", "Resting potential" - "tau_syn_ex", "ms", "1ms", "Time constant of postsynaptic excitatory currents" - "tau_syn_in", "ms", "3ms", "Time constant of postsynaptic inhibitory currents" + "E_L", "mV", "-70mV", "Resting potential" + "tau_syn_exc", "ms", "1ms", "Time constant of postsynaptic excitatory currents" + "tau_syn_inh", "ms", "3ms", "Time constant of postsynaptic inhibitory currents" "tau_1", "ms", "10ms", "Short time constant of adaptive threshold" "tau_2", "ms", "200ms", "Long time constant of adaptive threshold" - "alpha_1", "mV", "37.0mV", "Amplitude of short time threshold adaption [3]" - "alpha_2", "mV", "2.0mV", "Amplitude of long time threshold adaption [3]" - "omega", "mV", "19.0mV", "Resting spike threshold (absolute value, not relative to E_L)" + "alpha_1", "mV", "37mV", "Amplitude of short time threshold adaption [3]" + "alpha_2", "mV", "2mV", "Amplitude of long time threshold adaption [3]" + "omega", "mV", "19mV", "Resting spike threshold (absolute value, not relative to E_L)" "I_e", "pA", "0pA", "constant external input current" @@ -84,6 +80,9 @@ State variables :widths: auto + "V_th_alpha_1", "mV", "0mV", "Two-timescale adaptive threshold" + "V_th_alpha_2", "mV", "0mV", "Two-timescale adaptive threshold" + "r", "integer", "0", "counts number of tick during the refractory period" "V_abs", "mV", "0mV", "Membrane potential" "V_m", "mV", "V_abs + E_L", "Relative membrane potential." @@ -106,44 +105,40 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron mat2_psc_exp: state: - V_th_alpha_1 mV # Two-timescale adaptive threshold - V_th_alpha_2 mV # Two-timescale adaptive threshold - r integer # counts number of tick during the refractory period - end - initial_values: + V_th_alpha_1 mV = 0mV # Two-timescale adaptive threshold + V_th_alpha_2 mV = 0mV # Two-timescale adaptive threshold + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0mV # Membrane potential - function V_m mV = V_abs + E_L # Relative membrane potential. - /* I.e. the real threshold is (V_m-E_L).*/ + V_m mV = V_abs + E_L # Relative membrane potential. + # I.e. the real threshold is (V_m-E_L). end equations: - kernel I_kernel_in = exp(-1 / tau_syn_in * t) - kernel I_kernel_ex = exp(-1 / tau_syn_ex * t) - - /* V_th_alpha_1' = -V_th_alpha_1/tau_1*/ - /* V_th_alpha_2' = -V_th_alpha_2/tau_2*/ - function I_syn pA = convolve(I_kernel_in,in_spikes) + convolve(I_kernel_ex,ex_spikes) + kernel I_kernel_inh = exp(-t / tau_syn_inh) + kernel I_kernel_exc = exp(-t / tau_syn_exc) + inline I_syn pA = convolve(I_kernel_exc,exc_spikes) - convolve(I_kernel_inh,inh_spikes) V_abs'=-V_abs / tau_m + (I_syn + I_e + I_stim) / C_m end parameters: tau_m ms = 5ms # Membrane time constant - C_m pF = 100pF # Capacity of the membrane + C_m pF = 100pF # Capacitance of the membrane t_ref ms = 2ms # Duration of absolute refractory period (no spiking) - E_L mV = -70.0mV # Resting potential - tau_syn_ex ms = 1ms # Time constant of postsynaptic excitatory currents - tau_syn_in ms = 3ms # Time constant of postsynaptic inhibitory currents + E_L mV = -70mV # Resting potential + tau_syn_exc ms = 1ms # Time constant of postsynaptic excitatory currents + tau_syn_inh ms = 3ms # Time constant of postsynaptic inhibitory currents tau_1 ms = 10ms # Short time constant of adaptive threshold tau_2 ms = 200ms # Long time constant of adaptive threshold - alpha_1 mV = 37.0mV # Amplitude of short time threshold adaption [3] - alpha_2 mV = 2.0mV # Amplitude of long time threshold adaption [3] - omega mV = 19.0mV # Resting spike threshold (absolute value, not relative to E_L) + alpha_1 mV = 37mV # Amplitude of short time threshold adaption [3] + alpha_2 mV = 2mV # Amplitude of long time threshold adaption [3] + omega mV = 19mV # Resting spike threshold (absolute value, not relative to E_L) + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: @@ -153,26 +148,23 @@ Source code RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - ex_spikes pA <-excitatory spike - in_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike + inh_spikes pA <-inhibitory spike I_stim pA <-current end output: spike update: - - /* evolve membrane potential*/ + # evolve membrane potential integrate_odes() - - /* evolve adaptive threshold*/ + # evolve adaptive threshold V_th_alpha_1 = V_th_alpha_1 * P11th V_th_alpha_2 = V_th_alpha_2 * P22th if r == 0: # not refractory if V_abs >= omega + V_th_alpha_1 + V_th_alpha_2: # threshold crossing r = RefractoryCounts - - /* procedure for adaptive potential*/ + # procedure for adaptive potential V_th_alpha_1 += alpha_1 # short time V_th_alpha_2 += alpha_2 # long time emit_spike() @@ -194,4 +186,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.498666 + Generated at 2022-03-28 19:04:29.030654 \ No newline at end of file diff --git a/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve.png b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve.png new file mode 100644 index 000000000..4f340d10a Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve_small.png b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve_small.png new file mode 100644 index 000000000..ff62c8609 Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_f-I_curve_small.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response.png b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response.png new file mode 100644 index 000000000..e7e73e5ff Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response_small.png b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response_small.png new file mode 100644 index 000000000..eeb2ca3f7 Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_alpha]_synaptic_response_small.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve.png b/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve.png new file mode 100644 index 000000000..4f340d10a Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve_small.png b/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve_small.png new file mode 100644 index 000000000..ff62c8609 Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_exp]_f-I_curve_small.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response.png b/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response.png new file mode 100644 index 000000000..f8a9737d1 Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response.png differ diff --git a/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response_small.png b/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response_small.png new file mode 100644 index 000000000..4772de0f7 Binary files /dev/null and b/doc/models_library/nestml_models_library_[aeif_cond_exp]_synaptic_response_small.png differ diff --git a/doc/models_library/neuromodulated_stdp.rst b/doc/models_library/neuromodulated_stdp.rst new file mode 100644 index 000000000..301783b62 --- /dev/null +++ b/doc/models_library/neuromodulated_stdp.rst @@ -0,0 +1,135 @@ +neuromodulated_stdp +################### + + +neuromodulated_stdp - Synapse model for spike-timing dependent plasticity modulated by a neurotransmitter such as dopamine + +Description ++++++++++++ +stdp_dopamine_synapse is a connection to create synapses with +dopamine-modulated spike-timing dependent plasticity (used as a +benchmark model in [1]_, based on [2]_). The dopaminergic signal is a +low-pass filtered version of the spike rate of a user-specific pool +of neurons. The spikes emitted by the pool of dopamine neurons are +delivered to the synapse via the assigned volume transmitter. The +dopaminergic dynamics is calculated in the synapse itself. + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "tau_tr_pre", "ms", "20ms", "STDP time constant for weight changes caused by pre-before-post spike pairings." + "tau_tr_post", "ms", "20ms", "STDP time constant for weight changes caused by post-before-pre spike pairings." + "tau_c", "ms", "1000ms", "Time constant of eligibility trace" + "tau_n", "ms", "200ms", "Time constant of dopaminergic trace" + "b", "real", "0.0", "Dopaminergic baseline concentration" + "Wmax", "real", "200.0", "Maximal synaptic weight" + "Wmin", "real", "0.0", "Minimal synaptic weight" + "A_plus", "real", "1.0", "Multiplier applied to weight changes caused by pre-before-post spike pairings. If b (dopamine baseline concentration) is zero, then A_plus is simply the multiplier for facilitation (as in the stdp_synapse model). If b is not zero, then A_plus will be the multiplier for facilitation only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_plus will be the multiplier for depression." + "A_minus", "real", "1.5", "Multiplier applied to weight changes caused by post-before-pre spike pairings. If b (dopamine baseline concentration) is zero, then A_minus is simply the multiplier for depression (as in the stdp_synapse model). If b is not zero, then A_minus will be the multiplier for depression only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_minus will be the multiplier for facilitation." + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "1.0", "" + "n", "real", "0.0", "Neuromodulator concentration" + "c", "real", "0.0", "Eligibility trace" + "pre_tr", "real", "0.0", "" + "post_tr", "real", "0.0", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse neuromodulated_stdp: + state: + w real = 1.0 + n real = 0.0 # Neuromodulator concentration + c real = 0.0 # Eligibility trace + pre_tr real = 0.0 + post_tr real = 0.0 + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + tau_tr_pre ms = 20ms # STDP time constant for weight changes caused by pre-before-post spike pairings. + tau_tr_post ms = 20ms # STDP time constant for weight changes caused by post-before-pre spike pairings. + tau_c ms = 1000ms # Time constant of eligibility trace + tau_n ms = 200ms # Time constant of dopaminergic trace + b real = 0.0 # Dopaminergic baseline concentration + Wmax real = 200.0 # Maximal synaptic weight + Wmin real = 0.0 # Minimal synaptic weight + A_plus real = 1.0 # Multiplier applied to weight changes caused by pre-before-post spike pairings. If b (dopamine baseline concentration) is zero, then A_plus is simply the multiplier for facilitation (as in the stdp_synapse model). If b is not zero, then A_plus will be the multiplier for facilitation only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_plus will be the multiplier for depression. + A_minus real = 1.5 # Multiplier applied to weight changes caused by post-before-pre spike pairings. If b (dopamine baseline concentration) is zero, then A_minus is simply the multiplier for depression (as in the stdp_synapse model). If b is not zero, then A_minus will be the multiplier for depression only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_minus will be the multiplier for facilitation. + end + equations: + pre_tr'=-pre_tr / tau_tr_pre + post_tr'=-post_tr / tau_tr_post + end + + internals: + tau_s 1/ms = (tau_c + tau_n) / (tau_c * tau_n) + end + input: + pre_spikes nS <-spike + post_spikes nS <-spike + mod_spikes real <-spike + end + + output: spike + + onReceive(mod_spikes): + n += 1.0 / tau_n + end + + onReceive(post_spikes): + post_tr += 1.0 + # facilitation + c += A_plus * pre_tr + end + + onReceive(pre_spikes): + pre_tr += 1.0 + # depression + c -= A_minus * post_tr + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + # update from time t to t + resolution() + update: + # resolution() returns the timestep to be made (in units of time) + # the sequence here matters: the update step for w requires the "old" values of c and n + w -= c * (n / tau_s * expm1(-tau_s * resolution()) - b * tau_c * expm1(-resolution() / tau_c)) + c = c * exp(-resolution() / tau_c) + n = n * exp(-resolution() / tau_n) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: neuromodulated_stdp_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.046196 \ No newline at end of file diff --git a/doc/models_library/noisy_synapse.rst b/doc/models_library/noisy_synapse.rst new file mode 100644 index 000000000..7b375e1f4 --- /dev/null +++ b/doc/models_library/noisy_synapse.rst @@ -0,0 +1,70 @@ +noisy_synapse +############# + + + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "A_noise", "real", "0.4", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "nS", "1nS", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse noisy_synapse: + state: + w nS = 1nS + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + A_noise real = 0.4 + end + input: + pre_spikes nS <-spike + end + + output: spike + + onReceive(pre_spikes): + # temporary variable for the "weight" that will be transmitted + w_ nS = w + A_noise * random_normal(0,1) + # deliver spike to postsynaptic partner + deliver_spike(w_,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: noisy_synapse_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.025794 \ No newline at end of file diff --git a/doc/models_library/static.rst b/doc/models_library/static.rst new file mode 100644 index 000000000..715bc5ddf --- /dev/null +++ b/doc/models_library/static.rst @@ -0,0 +1,54 @@ +static +###### + + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "900", "" + "d", "ms", "0.9ms", "" + "a", "real", "3.141592653589793", "" + "b", "real", "100.0", "" + +Source code ++++++++++++ + +.. code-block:: nestml + + synapse static: + parameters: + w real = 900 + d ms = 0.9ms + a real = 3.141592653589793 + b real = 100.0 + end + input: + pre_spikes mV <-spike + end + + onReceive(pre_spikes): + deliver_spike(0.00318 * a * b * w,d) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: static_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.027750 \ No newline at end of file diff --git a/doc/models_library/stdp.rst b/doc/models_library/stdp.rst new file mode 100644 index 000000000..c04cc5fd6 --- /dev/null +++ b/doc/models_library/stdp.rst @@ -0,0 +1,135 @@ +stdp +#### + + +stdp - Synapse model for spike-timing dependent plasticity + +Description ++++++++++++ + +stdp_synapse is a synapse with spike time dependent plasticity (as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. Examples: + +=================== ==== ============================= +Multiplicative STDP [2]_ mu_plus = mu_minus = 1 +Additive STDP [3]_ mu_plus = mu_minus = 0 +Guetig STDP [1]_ mu_plus, mu_minus in [0, 1] +Van Rossum STDP [4]_ mu_plus = 0 mu_minus = 1 +=================== ==== ============================= + + +References +++++++++++ + +.. [1] Guetig et al. (2003) Learning Input Correlations through Nonlinear + Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience + +.. [2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium + properties of temporally asymmetric Hebbian plasticity, PRL + 86,364-367 + +.. [3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive + Hebbian learning through spike-timing-dependent synaptic + plasticity,Nature Neuroscience 3:9,919--926 + +.. [4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). + Stable Hebbian learning from spike timing-dependent + plasticity, Journal of Neuroscience, 20:23,8812--8821 + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "lambda", "real", "0.01", "" + "tau_tr_pre", "ms", "20ms", "" + "tau_tr_post", "ms", "20ms", "" + "alpha", "real", "1", "" + "mu_plus", "real", "1", "" + "mu_minus", "real", "1", "" + "Wmax", "real", "100.0", "" + "Wmin", "real", "0.0", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "1.0", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse stdp: + state: + w real = 1.0 + #pre_trace real = 0. + #post_trace real = 0. + + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + lambda real = 0.01 + tau_tr_pre ms = 20ms + tau_tr_post ms = 20ms + alpha real = 1 + mu_plus real = 1 + mu_minus real = 1 + Wmax real = 100.0 + Wmin real = 0.0 + end + equations: + kernel pre_trace_kernel = exp(-t / tau_tr_pre) + inline pre_trace real = convolve(pre_trace_kernel,pre_spikes) + # all-to-all trace of postsynaptic neuron + kernel post_trace_kernel = exp(-t / tau_tr_post) + inline post_trace real = convolve(post_trace_kernel,post_spikes) + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + end + + output: spike + + onReceive(post_spikes): + # potentiate synapse + w_ real = Wmax * (w / Wmax + (lambda * (1.0 - (w / Wmax)) ** mu_plus * pre_trace)) + w = min(Wmax,w_) + end + + onReceive(pre_spikes): + # depress synapse + w_ real = Wmax * (w / Wmax - (alpha * lambda * (w / Wmax) ** mu_minus * post_trace)) + w = max(Wmin,w_) + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: stdp_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 18:53:45.369969 \ No newline at end of file diff --git a/doc/models_library/stdp_nn_pre_centered.rst b/doc/models_library/stdp_nn_pre_centered.rst new file mode 100644 index 000000000..7eefd3e2a --- /dev/null +++ b/doc/models_library/stdp_nn_pre_centered.rst @@ -0,0 +1,155 @@ +stdp_nn_pre_centered +#################### + + +stdp_nn_pre_centered - Synapse type for spike-timing dependent plasticity, with nearest-neighbour spike pairing + +Description ++++++++++++ + +stdp_nn_pre_centered_synapse is a connector to create synapses with spike +time dependent plasticity with the presynaptic-centered nearest-neighbour +spike pairing scheme, as described in [1]_. + +Each presynaptic spike is taken into account in the STDP weight change rule +with the nearest preceding postsynaptic one and the nearest succeeding +postsynaptic one (instead of pairing with all spikes, like in stdp_synapse). +So, when a presynaptic spike occurs, it is accounted in the depression rule +with the nearest preceding postsynaptic one; and when a postsynaptic spike +occurs, it is accounted in the facilitation rule with all preceding +presynaptic spikes that were not earlier than the previous postsynaptic +spike. For a clear illustration of this scheme see fig. 7B in [2]_. + +The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike ++ dendritic_delay), leading to zero delta_t, are discarded. In this case the +concerned pre/postsynaptic spike is paired with the second latest preceding +post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +result in a potentiation pair 20-to-10). + +The implementation involves two additional variables - presynaptic and +postsynaptic traces [2]_. The presynaptic trace decays exponentially over +time with the time constant tau_plus, increases by 1 on a pre-spike +occurrence, and is reset to 0 on a post-spike occurrence. The postsynaptic +trace (implemented on the postsynaptic neuron side) decays with the time +constant tau_minus and increases to 1 on a post-spike occurrence. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner + + Original caption: + + Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) + + +References +++++++++++ + +.. [1] Izhikevich E. M., Desai N. S. (2003) Relating STDP to BCM, + Neural Comput. 15, 1511--1523 + +.. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "lambda", "real", "0.01", "" + "tau_tr_pre", "ms", "20ms", "" + "tau_tr_post", "ms", "20ms", "" + "alpha", "real", "1.0", "" + "mu_plus", "real", "1.0", "" + "mu_minus", "real", "1.0", "" + "Wmax", "real", "100.0", "" + "Wmin", "real", "0.0", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "1", "" + "pre_trace", "real", "0.0", "" + "post_trace", "real", "0.0", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse stdp_nn_pre_centered: + state: + w real = 1 + pre_trace real = 0.0 + post_trace real = 0.0 + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + lambda real = 0.01 + tau_tr_pre ms = 20ms + tau_tr_post ms = 20ms + alpha real = 1.0 + mu_plus real = 1.0 + mu_minus real = 1.0 + Wmax real = 100.0 + Wmin real = 0.0 + end + equations: + # nearest-neighbour trace of presynaptic neuron + pre_trace'=-pre_trace / tau_tr_pre + # nearest-neighbour trace of postsynaptic neuron + post_trace'=-post_trace / tau_tr_post + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + end + + output: spike + + onReceive(post_spikes): + post_trace = 1 + # potentiate synapse + w_ real = Wmax * (w / Wmax + (lambda * (1.0 - (w / Wmax)) ** mu_plus * pre_trace)) + w = min(Wmax,w_) + pre_trace = 0 + end + + onReceive(pre_spikes): + pre_trace += 1 + # depress synapse + w_ real = Wmax * (w / Wmax - (alpha * lambda * (w / Wmax) ** mu_minus * post_trace)) + w = max(Wmin,w_) + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: stdp_nn_pre_centered_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.070198 diff --git a/doc/models_library/stdp_nn_restr_symm.rst b/doc/models_library/stdp_nn_restr_symm.rst new file mode 100644 index 000000000..a6bc72f15 --- /dev/null +++ b/doc/models_library/stdp_nn_restr_symm.rst @@ -0,0 +1,154 @@ +stdp_nn_restr_symm +################## + + +Synapse type for spike-timing dependent plasticity with restricted symmetric nearest-neighbour spike pairing scheme + +Description ++++++++++++ + +stdp_nn_restr_synapse is a connector to create synapses with spike time +dependent plasticity with the restricted symmetric nearest-neighbour spike +pairing scheme (fig. 7C in [1]_). + +When a presynaptic spike occurs, it is taken into account in the depression +part of the STDP weight change rule with the nearest preceding postsynaptic +one, but only if the latter occured not earlier than the previous presynaptic +one. When a postsynaptic spike occurs, it is accounted in the facilitation +rule with the nearest preceding presynaptic one, but only if the latter +occured not earlier than the previous postsynaptic one. So, a spike can +participate neither in two depression pairs nor in two potentiation pairs. +The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike ++ dendritic_delay), leading to zero delta_t, are discarded. In this case the +concerned pre/postsynaptic spike is paired with the second latest preceding +post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +result in a potentiation pair 20-to-10). + +The implementation relies on an additional variable - the postsynaptic +eligibility trace [1]_ (implemented on the postsynaptic neuron side). It +decays exponentially with the time constant tau_minus and increases to 1 on +a post-spike occurrence (instead of increasing by 1 as in stdp_synapse). + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner + + Original caption: + + Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) + +References +++++++++++ + +.. [1] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "lambda", "real", "0.01", "" + "tau_tr_pre", "ms", "20ms", "" + "tau_tr_post", "ms", "20ms", "" + "alpha", "real", "1.0", "" + "mu_plus", "real", "1.0", "" + "mu_minus", "real", "1.0", "" + "Wmax", "real", "100.0", "" + "Wmin", "real", "0.0", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "1.0", "" + "pre_trace", "real", "0.0", "" + "post_trace", "real", "0.0", "" + "pre_handled", "boolean", "true", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse stdp_nn_restr_symm: + state: + w real = 1.0 + pre_trace real = 0.0 + post_trace real = 0.0 + pre_handled boolean = true + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + lambda real = 0.01 + tau_tr_pre ms = 20ms + tau_tr_post ms = 20ms + alpha real = 1.0 + mu_plus real = 1.0 + mu_minus real = 1.0 + Wmax real = 100.0 + Wmin real = 0.0 + end + equations: + # nearest-neighbour trace of presynaptic neuron + pre_trace'=-pre_trace / tau_tr_pre + # nearest-neighbour trace of postsynaptic neuron + post_trace'=-post_trace / tau_tr_post + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + end + + output: spike + + onReceive(post_spikes): + post_trace = 1 + # potentiate synapse + if not pre_handled: + w_ real = Wmax * (w / Wmax + (lambda * (1.0 - (w / Wmax)) ** mu_plus * pre_trace)) + w = min(Wmax,w_) + pre_handled = true + end + end + + onReceive(pre_spikes): + pre_trace = 1 + # depress synapse + if pre_handled: + w_ real = Wmax * (w / Wmax - (alpha * lambda * (w / Wmax) ** mu_minus * post_trace)) + w = max(Wmin,w_) + end + pre_handled = false + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: stdp_nn_restr_symm_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.039457 diff --git a/doc/models_library/stdp_nn_symm.rst b/doc/models_library/stdp_nn_symm.rst new file mode 100644 index 000000000..de51766fb --- /dev/null +++ b/doc/models_library/stdp_nn_symm.rst @@ -0,0 +1,151 @@ +stdp_nn_symm +############ + + +Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing scheme + +Description ++++++++++++ + +stdp_nn_symm_synapse is a connector to create synapses with spike time +dependent plasticity with the symmetric nearest-neighbour spike pairing +scheme [1]_. + +When a presynaptic spike occurs, it is taken into account in the depression +part of the STDP weight change rule with the nearest preceding postsynaptic +one, and when a postsynaptic spike occurs, it is accounted in the +facilitation rule with the nearest preceding presynaptic one (instead of +pairing with all spikes, like in stdp_synapse). For a clear illustration of +this scheme see fig. 7A in [2]_. + +The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike ++ dendritic_delay), leading to zero delta_t, are discarded. In this case the +concerned pre/postsynaptic spike is paired with the second latest preceding +post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +result in a potentiation pair 20-to-10). + +The implementation involves two additional variables - presynaptic and +postsynaptic traces [2]_. The presynaptic trace decays exponentially over +time with the time constant tau_plus and increases to 1 on a pre-spike +occurrence. The postsynaptic trace (implemented on the postsynaptic neuron +side) decays with the time constant tau_minus and increases to 1 on a +post-spike occurrence. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner + + Original caption: + + Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) + +References +++++++++++ + +.. [1] Morrison A., Aertsen A., Diesmann M. (2007) Spike-timing dependent + plasticity in balanced random networks, Neural Comput. 19:1437--1467 + +.. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "lambda", "real", "0.01", "" + "tau_tr_pre", "ms", "20ms", "" + "tau_tr_post", "ms", "20ms", "" + "alpha", "real", "1.0", "" + "mu_plus", "real", "1.0", "" + "mu_minus", "real", "1.0", "" + "Wmax", "real", "100.0", "" + "Wmin", "real", "0.0", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "1.0", "" + "pre_trace", "real", "0.0", "" + "post_trace", "real", "0.0", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse stdp_nn_symm: + state: + w real = 1.0 + pre_trace real = 0.0 + post_trace real = 0.0 + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + lambda real = 0.01 + tau_tr_pre ms = 20ms + tau_tr_post ms = 20ms + alpha real = 1.0 + mu_plus real = 1.0 + mu_minus real = 1.0 + Wmax real = 100.0 + Wmin real = 0.0 + end + equations: + # nearest-neighbour trace of presynaptic neuron + pre_trace'=-pre_trace / tau_tr_pre + # nearest-neighbour trace of postsynaptic neuron + post_trace'=-post_trace / tau_tr_post + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + end + + output: spike + + onReceive(post_spikes): + post_trace = 1 + # potentiate synapse + w_ real = Wmax * (w / Wmax + (lambda * (1.0 - (w / Wmax)) ** mu_plus * pre_trace)) + w = min(Wmax,w_) + end + + onReceive(pre_spikes): + pre_trace = 1 + # depress synapse + w_ real = Wmax * (w / Wmax - (alpha * lambda * (w / Wmax) ** mu_minus * post_trace)) + w = max(Wmin,w_) + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: stdp_nn_symm_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.029274 diff --git a/doc/models_library/stdp_triplet.rst b/doc/models_library/stdp_triplet.rst new file mode 100644 index 000000000..7b412a270 --- /dev/null +++ b/doc/models_library/stdp_triplet.rst @@ -0,0 +1,110 @@ +stdp_triplet +############ + + +XXX: NAIVE VERSION: unclear about relative timing of pre and post trace updates due to incoming pre and post spikes + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "tau_plus", "ms", "16.8ms", "time constant for tr_r1" + "tau_x", "ms", "101ms", "time constant for tr_r2" + "tau_minus", "ms", "33.7ms", "time constant for tr_o1" + "tau_y", "ms", "125ms", "time constant for tr_o2" + "A2_plus", "real", "7.5e-10", "" + "A3_plus", "real", "0.0093", "" + "A2_minus", "real", "0.007", "" + "A3_minus", "real", "0.00023", "" + "Wmax", "nS", "100nS", "" + "Wmin", "nS", "0nS", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "nS", "1nS", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse stdp_triplet: + state: + w nS = 1nS + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + tau_plus ms = 16.8ms # time constant for tr_r1 + tau_x ms = 101ms # time constant for tr_r2 + tau_minus ms = 33.7ms # time constant for tr_o1 + tau_y ms = 125ms # time constant for tr_o2 + A2_plus real = 7.5e-10 + A3_plus real = 0.0093 + A2_minus real = 0.007 + A3_minus real = 0.00023 + Wmax nS = 100nS + Wmin nS = 0nS + end + equations: + kernel tr_r1_kernel = exp(-t / tau_plus) + inline tr_r1 real = convolve(tr_r1_kernel,pre_spikes) + kernel tr_r2_kernel = exp(-t / tau_x) + inline tr_r2 real = convolve(tr_r2_kernel,pre_spikes) + kernel tr_o1_kernel = exp(-t / tau_minus) + inline tr_o1 real = convolve(tr_o1_kernel,post_spikes) + kernel tr_o2_kernel = exp(-t / tau_y) + inline tr_o2 real = convolve(tr_o2_kernel,post_spikes) + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + end + + output: spike + + onReceive(post_spikes): + # potentiate synapse + #w_ nS = Wmax * ( w / Wmax + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) ) + w_ nS = w + tr_r1 * (A2_plus + A3_plus * tr_o2) + w = min(Wmax,w_) + end + + onReceive(pre_spikes): + # depress synapse + #w_ nS = Wmax * ( w / Wmax - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) ) + w_ nS = w - tr_o1 * (A2_minus + A3_minus * tr_r2) + w = max(Wmin,w_) + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: stdp_triplet_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.021181 \ No newline at end of file diff --git a/doc/models_library/stdp_triplet_nn.rst b/doc/models_library/stdp_triplet_nn.rst new file mode 100644 index 000000000..d8aad2413 --- /dev/null +++ b/doc/models_library/stdp_triplet_nn.rst @@ -0,0 +1,119 @@ +stdp_triplet_nn +############### + + + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "tau_plus", "ms", "16.8ms", "time constant for tr_r1" + "tau_x", "ms", "101ms", "time constant for tr_r2" + "tau_minus", "ms", "33.7ms", "time constant for tr_o1" + "tau_y", "ms", "125ms", "time constant for tr_o2" + "A2_plus", "real", "7.5e-10", "" + "A3_plus", "real", "0.0093", "" + "A2_minus", "real", "0.007", "" + "A3_minus", "real", "0.00023", "" + "Wmax", "nS", "100nS", "" + "Wmin", "nS", "0nS", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "nS", "1nS", "" + "tr_r1", "real", "0.0", "" + "tr_r2", "real", "0.0", "" + "tr_o1", "real", "0.0", "" + "tr_o2", "real", "0.0", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse stdp_triplet_nn: + state: + w nS = 1nS + tr_r1 real = 0.0 + tr_r2 real = 0.0 + tr_o1 real = 0.0 + tr_o2 real = 0.0 + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + tau_plus ms = 16.8ms # time constant for tr_r1 + tau_x ms = 101ms # time constant for tr_r2 + tau_minus ms = 33.7ms # time constant for tr_o1 + tau_y ms = 125ms # time constant for tr_o2 + A2_plus real = 7.5e-10 + A3_plus real = 0.0093 + A2_minus real = 0.007 + A3_minus real = 0.00023 + Wmax nS = 100nS + Wmin nS = 0nS + end + equations: + tr_r1'=-tr_r1 / tau_plus + tr_r2'=-tr_r2 / tau_x + tr_o1'=-tr_o1 / tau_minus + tr_o2'=-tr_o2 / tau_y + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + end + + output: spike + + onReceive(post_spikes): + # increment post trace values + tr_o1 += 1 + tr_o2 += 1 + # potentiate synapse + #w_ nS = Wmax * ( w / Wmax + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) ) + w_ nS = w + tr_r1 * (A2_plus + A3_plus * tr_o2) + w = min(Wmax,w_) + end + + onReceive(pre_spikes): + # increment pre trace values + tr_r1 += 1 + tr_r2 += 1 + # depress synapse + #w_ nS = Wmax * ( w / Wmax - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) ) + w_ nS = w - tr_o1 * (A2_minus + A3_minus * tr_r2) + w = max(Wmin,w_) + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: stdp_triplet_nn_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.056175 \ No newline at end of file diff --git a/doc/models_library/terub_gpe.rst b/doc/models_library/terub_gpe.rst index e3da57fb1..4ed5143b5 100644 --- a/doc/models_library/terub_gpe.rst +++ b/doc/models_library/terub_gpe.rst @@ -1,8 +1,8 @@ terub_gpe ######### -terub_gpe - Terman Rubin neuron model +terub_gpe - Terman Rubin neuron model Description +++++++++++ @@ -30,10 +30,6 @@ References Pathological Thalamic Rhythmicity in a Computational Model Journal of Computational Neuroscience, 16, 211-235 (2004) -Author -++++++ - -Martin Ebert Parameters @@ -46,21 +42,21 @@ Parameters :widths: auto - "E_L", "mV", "-55mV", "Resting membrane potential." - "g_L", "nS", "0.1nS", "Leak conductance." - "C_m", "pF", "1.0pF", "Capacity of the membrane." - "E_Na", "mV", "55mV", "Sodium reversal potential." - "g_Na", "nS", "120nS", "Sodium peak conductance." - "E_K", "mV", "-80.0mV", "Potassium reversal potential." - "g_K", "nS", "30.0nS", "Potassium peak conductance." - "E_Ca", "mV", "120mV", "Calcium reversal potential." - "g_Ca", "nS", "0.15nS", "Calcium peak conductance." - "g_T", "nS", "0.5nS", "T-type Calcium channel peak conductance." - "g_ahp", "nS", "30nS", "afterpolarization current peak conductance." - "tau_syn_ex", "ms", "1.0ms", "Rise time of the excitatory synaptic alpha function." - "tau_syn_in", "ms", "12.5ms", "Rise time of the inhibitory synaptic alpha function." - "E_gg", "mV", "-100mV", "reversal potential for inhibitory input (from GPe)" - "t_ref", "ms", "2ms", "refractory time" + "E_L", "mV", "-55mV", "Resting membrane potential" + "g_L", "nS", "0.1nS", "Leak conductance" + "C_m", "pF", "1pF", "Capacitance of the membrane" + "E_Na", "mV", "55mV", "Sodium reversal potential" + "g_Na", "nS", "120nS", "Sodium peak conductance" + "E_K", "mV", "-80.0mV", "Potassium reversal potential" + "g_K", "nS", "30.0nS", "Potassium peak conductance" + "E_Ca", "mV", "120mV", "Calcium reversal potential" + "g_Ca", "nS", "0.15nS", "Calcium peak conductance" + "g_T", "nS", "0.5nS", "T-type Calcium channel peak conductance" + "g_ahp", "nS", "30nS", "Afterpolarization current peak conductance" + "tau_syn_exc", "ms", "1ms", "Rise time of the excitatory synaptic alpha function" + "tau_syn_inh", "ms", "12.5ms", "Rise time of the inhibitory synaptic alpha function" + "E_gg", "mV", "-100mV", "Reversal potential for inhibitory input (from GPe)" + "t_ref", "ms", "2ms", "Refractory time" "I_e", "pA", "0pA", "constant external input current" @@ -74,6 +70,7 @@ State variables :widths: auto + "r", "integer", "0", "counts number of ticks during the refractory period" "V_m", "mV", "E_L", "Membrane potential" "gate_h", "real", "0.0", "gating variable h" "gate_n", "real", "0.0", "gating variable n" @@ -90,7 +87,7 @@ Equations .. math:: - \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L} + I_{T} + I_{Ca} + I_{ahp}) \cdot \mathrm{pA} + I_{e} + I_{stim} + I_{ex,mod} \cdot \mathrm{pA} + I_{in,mod} \cdot \mathrm{pA}) } \right) + \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L} + I_{T} + I_{Ca} + I_{ahp}) \cdot \mathrm{pA} + I_{e} + I_{stim} + I_{exc,mod} \cdot \mathrm{pA} + I_{inh,mod} \cdot \mathrm{pA}) } \right) .. math:: @@ -115,13 +112,11 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron terub_gpe: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of ticks during the refractory period V_m mV = E_L # Membrane potential gate_h real = 0.0 # gating variable h gate_n real = 0.0 # gating variable n @@ -129,105 +124,100 @@ Source code Ca_con real = 0.0 # gating variable r end equations: - - /* Parameters for Terman Rubin GPe Neuron*/ - function g_tau_n_0 ms = 0.05ms - function g_tau_n_1 ms = 0.27ms - function g_theta_n_tau mV = -40.0mV - function g_sigma_n_tau mV = -12.0mV - function g_tau_h_0 ms = 0.05ms - function g_tau_h_1 ms = 0.27ms - function g_theta_h_tau mV = -40.0mV - function g_sigma_h_tau mV = -12.0mV - function g_tau_r ms = 30.0ms - - /* steady state values for gating variables*/ - function g_theta_a mV = -57.0mV - function g_sigma_a mV = 2.0mV - function g_theta_h mV = -58.0mV - function g_sigma_h mV = -12.0mV - function g_theta_m mV = -37.0mV - function g_sigma_m mV = 10.0mV - function g_theta_n mV = -50.0mV - function g_sigma_n mV = 14.0mV - function g_theta_r mV = -70.0mV - function g_sigma_r mV = -2.0mV - function g_theta_s mV = -35.0mV - function g_sigma_s mV = 2.0mV - - /* time evolvement of gating variables*/ - function g_phi_h real = 0.05 - function g_phi_n real = 0.1 # Report: 0.1, Terman Rubin 2002: 0.05 - function g_phi_r real = 1.0 - - /* Calcium concentration and afterhyperpolarization current*/ - function g_epsilon 1/ms = 0.0001 / ms - function g_k_Ca real = 15.0 # Report:15, Terman Rubin 2002: 20.0 - function g_k1 real = 30.0 - function I_ex_mod real = -convolve(g_ex,spikeExc) * V_m - function I_in_mod real = convolve(g_in,spikeInh) * (V_m - E_gg) - function tau_n real = g_tau_n_0 + g_tau_n_1 / (1.0 + exp(-(V_m - g_theta_n_tau) / g_sigma_n_tau)) - function tau_h real = g_tau_h_0 + g_tau_h_1 / (1.0 + exp(-(V_m - g_theta_h_tau) / g_sigma_h_tau)) - function tau_r real = g_tau_r - function a_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_a) / g_sigma_a)) - function h_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_h) / g_sigma_h)) - function m_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_m) / g_sigma_m)) - function n_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_n) / g_sigma_n)) - function r_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_r) / g_sigma_r)) - function s_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_s) / g_sigma_s)) - function I_Na real = g_Na * m_inf * m_inf * m_inf * gate_h * (V_m - E_Na) - function I_K real = g_K * gate_n * gate_n * gate_n * gate_n * (V_m - E_K) - function I_L real = g_L * (V_m - E_L) - function I_T real = g_T * a_inf * a_inf * a_inf * gate_r * (V_m - E_Ca) - function I_Ca real = g_Ca * s_inf * s_inf * (V_m - E_Ca) - function I_ahp real = g_ahp * (Ca_con / (Ca_con + g_k1)) * (V_m - E_K) - - /* synapses: alpha functions*/ - /* alpha function for the g_in*/ - kernel g_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - /* alpha function for the g_ex*/ - - /* alpha function for the g_ex*/ - kernel g_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - - /* V dot -- synaptic input are currents, inhib current is negative*/ - V_m'=(-(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) * pA + I_e + I_stim + I_ex_mod * pA + I_in_mod * pA) / C_m - - /* channel dynamics*/ + # Parameters for Terman Rubin GPe Neuron + inline g_tau_n_0 ms = 0.05ms + inline g_tau_n_1 ms = 0.27ms + inline g_theta_n_tau mV = -40.0mV + inline g_sigma_n_tau mV = -12.0mV + inline g_tau_h_0 ms = 0.05ms + inline g_tau_h_1 ms = 0.27ms + inline g_theta_h_tau mV = -40.0mV + inline g_sigma_h_tau mV = -12.0mV + inline g_tau_r ms = 30.0ms + # steady state values for gating variables + inline g_theta_a mV = -57.0mV + inline g_sigma_a mV = 2.0mV + inline g_theta_h mV = -58.0mV + inline g_sigma_h mV = -12.0mV + inline g_theta_m mV = -37.0mV + inline g_sigma_m mV = 10.0mV + inline g_theta_n mV = -50.0mV + inline g_sigma_n mV = 14.0mV + inline g_theta_r mV = -70.0mV + inline g_sigma_r mV = -2.0mV + inline g_theta_s mV = -35.0mV + inline g_sigma_s mV = 2.0mV + # time evolvement of gating variables + inline g_phi_h real = 0.05 + inline g_phi_n real = 0.1 # Report: 0.1, Terman Rubin 2002: 0.05 + inline g_phi_r real = 1.0 + # Calcium concentration and afterhyperpolarization current + inline g_epsilon 1/ms = 0.0001 / ms + inline g_k_Ca real = 15.0 # Report:15, Terman Rubin 2002: 20.0 + inline g_k1 real = 30.0 + inline I_exc_mod real = -convolve(g_exc,exc_spikes) * V_m + inline I_inh_mod real = convolve(g_inh,inh_spikes) * (V_m - E_gg) + inline tau_n real = g_tau_n_0 + g_tau_n_1 / (1.0 + exp(-(V_m - g_theta_n_tau) / g_sigma_n_tau)) + inline tau_h real = g_tau_h_0 + g_tau_h_1 / (1.0 + exp(-(V_m - g_theta_h_tau) / g_sigma_h_tau)) + inline tau_r real = g_tau_r + inline a_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_a) / g_sigma_a)) + inline h_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_h) / g_sigma_h)) + inline m_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_m) / g_sigma_m)) + inline n_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_n) / g_sigma_n)) + inline r_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_r) / g_sigma_r)) + inline s_inf real = 1.0 / (1.0 + exp(-(V_m - g_theta_s) / g_sigma_s)) + inline I_Na real = g_Na * m_inf * m_inf * m_inf * gate_h * (V_m - E_Na) + inline I_K real = g_K * gate_n * gate_n * gate_n * gate_n * (V_m - E_K) + inline I_L real = g_L * (V_m - E_L) + inline I_T real = g_T * a_inf * a_inf * a_inf * gate_r * (V_m - E_Ca) + inline I_Ca real = g_Ca * s_inf * s_inf * (V_m - E_Ca) + inline I_ahp real = g_ahp * (Ca_con / (Ca_con + g_k1)) * (V_m - E_K) + # synapses: alpha functions + # alpha function for the g_inh + kernel g_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + # alpha function for the g_exc + + # alpha function for the g_exc + kernel g_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + # V dot -- synaptic input are currents, inhib current is negative + V_m'=(-(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) * pA + I_e + I_stim + I_exc_mod * pA + I_inh_mod * pA) / C_m + # channel dynamics gate_h'=g_phi_h * ((h_inf - gate_h) / tau_h) / ms # h-variable gate_n'=g_phi_n * ((n_inf - gate_n) / tau_n) / ms # n-variable gate_r'=g_phi_r * ((r_inf - gate_r) / tau_r) / ms # r-variable + # Calcium concentration - /* Calcium concentration*/ + # Calcium concentration Ca_con'=g_epsilon * (-I_Ca - I_T - g_k_Ca * Ca_con) end parameters: - E_L mV = -55mV # Resting membrane potential. - g_L nS = 0.1nS # Leak conductance. - C_m pF = 1.0pF # Capacity of the membrane. - E_Na mV = 55mV # Sodium reversal potential. - g_Na nS = 120nS # Sodium peak conductance. - E_K mV = -80.0mV # Potassium reversal potential. - g_K nS = 30.0nS # Potassium peak conductance. - E_Ca mV = 120mV # Calcium reversal potential. - g_Ca nS = 0.15nS # Calcium peak conductance. - g_T nS = 0.5nS # T-type Calcium channel peak conductance. - g_ahp nS = 30nS # afterpolarization current peak conductance. - tau_syn_ex ms = 1.0ms # Rise time of the excitatory synaptic alpha function. - tau_syn_in ms = 12.5ms # Rise time of the inhibitory synaptic alpha function. - E_gg mV = -100mV # reversal potential for inhibitory input (from GPe) - t_ref ms = 2ms # refractory time - - /* constant external input current*/ + E_L mV = -55mV # Resting membrane potential + g_L nS = 0.1nS # Leak conductance + C_m pF = 1pF # Capacitance of the membrane + E_Na mV = 55mV # Sodium reversal potential + g_Na nS = 120nS # Sodium peak conductance + E_K mV = -80.0mV # Potassium reversal potential + g_K nS = 30.0nS # Potassium peak conductance + E_Ca mV = 120mV # Calcium reversal potential + g_Ca nS = 0.15nS # Calcium peak conductance + g_T nS = 0.5nS # T-type Calcium channel peak conductance + g_ahp nS = 30nS # Afterpolarization current peak conductance + tau_syn_exc ms = 1ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 12.5ms # Rise time of the inhibitory synaptic alpha function + E_gg mV = -100mV # Reversal potential for inhibitory input (from GPe) + t_ref ms = 2ms # Refractory time + # constant external input current + + # constant external input current I_e pA = 0pA end internals: refractory_counts integer = steps(t_ref) end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -236,8 +226,7 @@ Source code update: U_old mV = V_m integrate_odes() - - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: r -= 1 elif V_m > 0mV and U_old > V_m: @@ -258,4 +247,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.076686 \ No newline at end of file + Generated at 2022-03-28 19:04:28.746026 \ No newline at end of file diff --git a/doc/models_library/terub_stn.rst b/doc/models_library/terub_stn.rst index 575689423..b70d2c0e3 100644 --- a/doc/models_library/terub_stn.rst +++ b/doc/models_library/terub_stn.rst @@ -1,8 +1,8 @@ terub_stn ######### -terub_stn - Terman Rubin neuron model +terub_stn - Terman Rubin neuron model Description +++++++++++ @@ -28,11 +28,6 @@ References Pathological Thalamic Rhythmicity in a Computational Model Journal of Computational Neuroscience, 16, 211-235 (2004) -Author -++++++ - -Martin Ebert - Parameters ++++++++++ @@ -44,21 +39,21 @@ Parameters :widths: auto - "E_L", "mV", "-60mV", "Resting membrane potential." - "g_L", "nS", "2.25nS", "Leak conductance." - "C_m", "pF", "1.0pF", "Capacity of the membrane." - "E_Na", "mV", "55mV", "Sodium reversal potential." - "g_Na", "nS", "37.5nS", "Sodium peak conductance." - "E_K", "mV", "-80.0mV", "Potassium reversal potential." - "g_K", "nS", "45.0nS", "Potassium peak conductance." - "E_Ca", "mV", "120mV", "Calcium reversal potential." - "g_Ca", "nS", "140nS", "Calcium peak conductance." - "g_T", "nS", "0.5nS", "T-type Calcium channel peak conductance." - "g_ahp", "nS", "9nS", "afterpolarization current peak conductance." - "tau_syn_ex", "ms", "1.0ms", "Rise time of the excitatory synaptic alpha function." - "tau_syn_in", "ms", "0.08ms", "Rise time of the inhibitory synaptic alpha function." - "E_gs", "mV", "-85.0mV", "reversal potential for inhibitory input (from GPe)" - "t_ref", "ms", "2ms", "refractory time" + "E_L", "mV", "-60mV", "Resting membrane potential" + "g_L", "nS", "2.25nS", "Leak conductance" + "C_m", "pF", "1pF", "Capacity of the membrane" + "E_Na", "mV", "55mV", "Sodium reversal potential" + "g_Na", "nS", "37.5nS", "Sodium peak conductance" + "E_K", "mV", "-80mV", "Potassium reversal potential" + "g_K", "nS", "45nS", "Potassium peak conductance" + "E_Ca", "mV", "140mV", "Calcium reversal potential" + "g_Ca", "nS", "0.5nS", "Calcium peak conductance" + "g_T", "nS", "0.5nS", "T-type Calcium channel peak conductance" + "g_ahp", "nS", "9nS", "Afterpolarization current peak conductance" + "tau_syn_exc", "ms", "1ms", "Rise time of the excitatory synaptic alpha function" + "tau_syn_inh", "ms", "0.08ms", "Rise time of the inhibitory synaptic alpha function" + "E_gs", "mV", "-85mV", "Reversal potential for inhibitory input (from GPe)" + "t_ref", "ms", "2ms", "Refractory time" "I_e", "pA", "0pA", "constant external input current" @@ -72,6 +67,7 @@ State variables :widths: auto + "r", "integer", "0", "counts number of tick during the refractory period" "V_m", "mV", "E_L", "Membrane potential" "gate_h", "real", "0.0", "gating variable h" "gate_n", "real", "0.0", "gating variable n" @@ -88,7 +84,7 @@ Equations .. math:: - \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L} + I_{T} + I_{Ca} + I_{ahp}) + I_{e} + I_{stim} + I_{ex,mod} + I_{in,mod}) } \right) + \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L} + I_{T} + I_{Ca} + I_{ahp}) + I_{e} + I_{stim} + I_{exc,mod} + I_{inh,mod}) } \right) .. math:: @@ -113,13 +109,11 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron terub_stn: state: - r integer # counts number of tick during the refractory period - end - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # Membrane potential gate_h real = 0.0 # gating variable h gate_n real = 0.0 # gating variable n @@ -127,111 +121,110 @@ Source code Ca_con real = 0.0 # gating variable r end equations: - - /*time constants for slow gating variables*/ - function tau_n_0 ms = 1.0ms - function tau_n_1 ms = 100.0ms - function theta_n_tau mV = -80.0mV - function sigma_n_tau mV = -26.0mV - function tau_h_0 ms = 1.0ms - function tau_h_1 ms = 500.0ms - function theta_h_tau mV = -57.0mV - function sigma_h_tau mV = -3.0mV - function tau_r_0 ms = 7.1ms # Guo 7.1 Terman02 40.0 - function tau_r_1 ms = 17.5ms - function theta_r_tau mV = 68.0mV - function sigma_r_tau mV = -2.2mV - - /*steady state values for gating variables*/ - function theta_a mV = -63.0mV - function sigma_a mV = 7.8mV - function theta_h mV = -39.0mV - function sigma_h mV = -3.1mV - function theta_m mV = -30.0mV - function sigma_m mV = 15.0mV - function theta_n mV = -32.0mV - function sigma_n mV = 8.0mV - function theta_r mV = -67.0mV - function sigma_r mV = -2.0mV - function theta_s mV = -39.0mV - function sigma_s mV = 8.0mV - function theta_b real = 0.25 # Guo 0.25 Terman02 0.4 - function sigma_b real = 0.07 # Guo 0.07 Terman02 -0.1 - - /*time evolvement of gating variables*/ - function phi_h real = 0.75 - function phi_n real = 0.75 - function phi_r real = 0.5 # Guo 0.5 Terman02 0.2 - - /* Calcium concentration and afterhyperpolarization current*/ - function epsilon 1/ms = 5e-05 / ms # 1/ms Guo 0.00005 Terman02 0.0000375 - function k_Ca real = 22.5 - function k1 real = 15.0 - function I_ex_mod pA = -convolve(g_ex,spikeExc) * V_m - function I_in_mod pA = convolve(g_in,spikeInh) * (V_m - E_gs) - function tau_n ms = tau_n_0 + tau_n_1 / (1.0 + exp(-(V_m - theta_n_tau) / sigma_n_tau)) - function tau_h ms = tau_h_0 + tau_h_1 / (1.0 + exp(-(V_m - theta_h_tau) / sigma_h_tau)) - function tau_r ms = tau_r_0 + tau_r_1 / (1.0 + exp(-(V_m - theta_r_tau) / sigma_r_tau)) - function a_inf real = 1.0 / (1.0 + exp(-(V_m - theta_a) / sigma_a)) - function h_inf real = 1.0 / (1.0 + exp(-(V_m - theta_h) / sigma_h)) - function m_inf real = 1.0 / (1.0 + exp(-(V_m - theta_m) / sigma_m)) - function n_inf real = 1.0 / (1.0 + exp(-(V_m - theta_n) / sigma_n)) - function r_inf real = 1.0 / (1.0 + exp(-(V_m - theta_r) / sigma_r)) - function s_inf real = 1.0 / (1.0 + exp(-(V_m - theta_s) / sigma_s)) - function b_inf real = 1.0 / (1.0 + exp((gate_r - theta_b) / sigma_b)) - 1.0 / (1.0 + exp(-theta_b / sigma_b)) - function I_Na pA = g_Na * m_inf * m_inf * m_inf * gate_h * (V_m - E_Na) - function I_K pA = g_K * gate_n * gate_n * gate_n * gate_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - function I_T pA = g_T * a_inf * a_inf * a_inf * b_inf * b_inf * (V_m - E_Ca) - function I_Ca pA = g_Ca * s_inf * s_inf * (V_m - E_Ca) - function I_ahp pA = g_ahp * (Ca_con / (Ca_con + k1)) * (V_m - E_K) - - /* V dot -- synaptic input are currents, inhib current is negative*/ - V_m'=(-(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) + I_e + I_stim + I_ex_mod + I_in_mod) / C_m - - /*channel dynamics*/ + #time constants for slow gating variables + inline tau_n_0 ms = 1.0ms + inline tau_n_1 ms = 100.0ms + inline theta_n_tau mV = -80.0mV + inline sigma_n_tau mV = -26.0mV + inline tau_h_0 ms = 1.0ms + inline tau_h_1 ms = 500.0ms + inline theta_h_tau mV = -57.0mV + inline sigma_h_tau mV = -3.0mV + inline tau_r_0 ms = 7.1ms # Guo 7.1 Terman02 40.0 + inline tau_r_1 ms = 17.5ms + inline theta_r_tau mV = 68.0mV + inline sigma_r_tau mV = -2.2mV + #steady state values for gating variables + inline theta_a mV = -63.0mV + inline sigma_a mV = 7.8mV + inline theta_h mV = -39.0mV + inline sigma_h mV = -3.1mV + inline theta_m mV = -30.0mV + inline sigma_m mV = 15.0mV + inline theta_n mV = -32.0mV + inline sigma_n mV = 8.0mV + inline theta_r mV = -67.0mV + inline sigma_r mV = -2.0mV + inline theta_s mV = -39.0mV + inline sigma_s mV = 8.0mV + inline theta_b real = 0.25 # Guo 0.25 Terman02 0.4 + inline sigma_b real = 0.07 # Guo 0.07 Terman02 -0.1 + #time evolvement of gating variables + + #time evolvement of gating variables + inline phi_h real = 0.75 + inline phi_n real = 0.75 + inline phi_r real = 0.5 # Guo 0.5 Terman02 0.2 + # Calcium concentration and afterhyperpolarization current + + # Calcium concentration and afterhyperpolarization current + inline epsilon 1/ms = 5e-05 / ms # 1/ms Guo 0.00005 Terman02 0.0000375 + inline k_Ca real = 22.5 + inline k1 real = 15.0 + inline I_exc_mod pA = -convolve(g_exc,exc_spikes) * V_m + inline I_inh_mod pA = convolve(g_inh,inh_spikes) * (V_m - E_gs) + inline tau_n ms = tau_n_0 + tau_n_1 / (1.0 + exp(-(V_m - theta_n_tau) / sigma_n_tau)) + inline tau_h ms = tau_h_0 + tau_h_1 / (1.0 + exp(-(V_m - theta_h_tau) / sigma_h_tau)) + inline tau_r ms = tau_r_0 + tau_r_1 / (1.0 + exp(-(V_m - theta_r_tau) / sigma_r_tau)) + inline a_inf real = 1.0 / (1.0 + exp(-(V_m - theta_a) / sigma_a)) + inline h_inf real = 1.0 / (1.0 + exp(-(V_m - theta_h) / sigma_h)) + inline m_inf real = 1.0 / (1.0 + exp(-(V_m - theta_m) / sigma_m)) + inline n_inf real = 1.0 / (1.0 + exp(-(V_m - theta_n) / sigma_n)) + inline r_inf real = 1.0 / (1.0 + exp(-(V_m - theta_r) / sigma_r)) + inline s_inf real = 1.0 / (1.0 + exp(-(V_m - theta_s) / sigma_s)) + inline b_inf real = 1.0 / (1.0 + exp((gate_r - theta_b) / sigma_b)) - 1.0 / (1.0 + exp(-theta_b / sigma_b)) + inline I_Na pA = g_Na * m_inf * m_inf * m_inf * gate_h * (V_m - E_Na) + inline I_K pA = g_K * gate_n * gate_n * gate_n * gate_n * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + inline I_T pA = g_T * a_inf * a_inf * a_inf * b_inf * b_inf * (V_m - E_Ca) + inline I_Ca pA = g_Ca * s_inf * s_inf * (V_m - E_Ca) + inline I_ahp pA = g_ahp * (Ca_con / (Ca_con + k1)) * (V_m - E_K) + # V dot -- synaptic input are currents, inhib current is negative + V_m'=(-(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) + I_e + I_stim + I_exc_mod + I_inh_mod) / C_m + #channel dynamics gate_h'=phi_h * ((h_inf - gate_h) / tau_h) # h-variable gate_n'=phi_n * ((n_inf - gate_n) / tau_n) # n-variable gate_r'=phi_r * ((r_inf - gate_r) / tau_r) # r-variable + #Calcium concentration - /*Calcium concentration*/ + #Calcium concentration Ca_con'=epsilon * ((-I_Ca - I_T) / pA - k_Ca * Ca_con) + # synapses: alpha functions + # alpha function for the g_inh + kernel g_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + # alpha function for the g_exc - /* synapses: alpha functions*/ - /* alpha function for the g_in*/ - kernel g_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - /* alpha function for the g_ex*/ - - /* alpha function for the g_ex*/ - kernel g_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) + # alpha function for the g_exc + kernel g_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) end parameters: - E_L mV = -60mV # Resting membrane potential. - g_L nS = 2.25nS # Leak conductance. - C_m pF = 1.0pF # Capacity of the membrane. - E_Na mV = 55mV # Sodium reversal potential. - g_Na nS = 37.5nS # Sodium peak conductance. - E_K mV = -80.0mV # Potassium reversal potential. - g_K nS = 45.0nS # Potassium peak conductance. - E_Ca mV = 120mV # Calcium reversal potential. - g_Ca nS = 140nS # Calcium peak conductance. - g_T nS = 0.5nS # T-type Calcium channel peak conductance. - g_ahp nS = 9nS # afterpolarization current peak conductance. - tau_syn_ex ms = 1.0ms # Rise time of the excitatory synaptic alpha function. - tau_syn_in ms = 0.08ms # Rise time of the inhibitory synaptic alpha function. - E_gs mV = -85.0mV # reversal potential for inhibitory input (from GPe) - t_ref ms = 2ms # refractory time - - /* constant external input current*/ + E_L mV = -60mV # Resting membrane potential + g_L nS = 2.25nS # Leak conductance + C_m pF = 1pF # Capacity of the membrane + E_Na mV = 55mV # Sodium reversal potential + g_Na nS = 37.5nS # Sodium peak conductance + E_K mV = -80mV # Potassium reversal potential + g_K nS = 45nS # Potassium peak conductance + E_Ca mV = 140mV # Calcium reversal potential + g_Ca nS = 0.5nS # Calcium peak conductance + g_T nS = 0.5nS # T-type Calcium channel peak conductance + g_ahp nS = 9nS # Afterpolarization current peak conductance + tau_syn_exc ms = 1ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 0.08ms # Rise time of the inhibitory synaptic alpha function + E_gs mV = -85mV # Reversal potential for inhibitory input (from GPe) + t_ref ms = 2ms # Refractory time + # constant external input current + + # constant external input current I_e pA = 0pA end internals: refractory_counts integer = steps(t_ref) end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike I_stim pA <-current end @@ -240,8 +233,7 @@ Source code update: U_old mV = V_m integrate_odes() - - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: r -= 1 elif V_m > 0mV and U_old > V_m: @@ -262,4 +254,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.236576 \ No newline at end of file + Generated at 2022-03-28 19:04:30.033141 \ No newline at end of file diff --git a/doc/models_library/third_factor_stdp.rst b/doc/models_library/third_factor_stdp.rst new file mode 100644 index 000000000..879d2ff73 --- /dev/null +++ b/doc/models_library/third_factor_stdp.rst @@ -0,0 +1,142 @@ +third_factor_stdp +################# + + +third_factor_stdp - Synapse model for spike-timing dependent plasticity with postsynaptic third-factor modulation + +Description ++++++++++++ + +third_factor_stdp is a synapse with spike time dependent plasticity (as defined in [1]). Here the weight dependence exponent can be set separately for potentiation and depression. Examples:: + +Multiplicative STDP [2] mu_plus = mu_minus = 1 +Additive STDP [3] mu_plus = mu_minus = 0 +Guetig STDP [1] mu_plus, mu_minus in [0, 1] +Van Rossum STDP [4] mu_plus = 0 mu_minus = 1 + +The weight changes are modulated by a "third factor", in this case the postsynaptic dendritic current ``I_post_dend``. + +``I_post_dend`` "gates" the weight update, so that if the current is 0, the weight is constant, whereas for a current of 1 pA, the weight change is maximal. + +Do not use values of ``I_post_dend`` larger than 1 pA! + +References +++++++++++ + +[1] Guetig et al. (2003) Learning Input Correlations through Nonlinear + Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience + +[2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium + properties of temporally asymmetric Hebbian plasticity, PRL + 86,364-367 + +[3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive + Hebbian learning through spike-timing-dependent synaptic + plasticity,Nature Neuroscience 3:9,919--926 + +[4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). + Stable Hebbian learning from spike timing-dependent + plasticity, Journal of Neuroscience, 20:23,8812--8821 + + + +Parameters +++++++++++ + + + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "the_delay", "ms", "1ms", "!!! cannot have a variable called ""delay""" + "lambda", "real", "0.01", "" + "tau_tr_pre", "ms", "20ms", "" + "tau_tr_post", "ms", "20ms", "" + "alpha", "real", "1.0", "" + "mu_plus", "real", "1.0", "" + "mu_minus", "real", "1.0", "" + "Wmax", "real", "100.0", "" + "Wmin", "real", "0.0", "" + + + +State variables ++++++++++++++++ + +.. csv-table:: + :header: "Name", "Physical unit", "Default value", "Description" + :widths: auto + + + "w", "real", "1.0", "" +Source code ++++++++++++ + +.. code-block:: nestml + + synapse third_factor_stdp: + state: + w real = 1.0 + end + parameters: + the_delay ms = 1ms # !!! cannot have a variable called "delay" + lambda real = 0.01 + tau_tr_pre ms = 20ms + tau_tr_post ms = 20ms + alpha real = 1.0 + mu_plus real = 1.0 + mu_minus real = 1.0 + Wmax real = 100.0 + Wmin real = 0.0 + end + equations: + kernel pre_trace_kernel = exp(-t / tau_tr_pre) + inline pre_trace real = convolve(pre_trace_kernel,pre_spikes) + # all-to-all trace of postsynaptic neuron + kernel post_trace_kernel = exp(-t / tau_tr_post) + inline post_trace real = convolve(post_trace_kernel,post_spikes) + end + + input: + pre_spikes nS <-spike + post_spikes nS <-spike + I_post_dend pA <-current + end + + output: spike + + onReceive(post_spikes): + # potentiate synapse + w_ real = Wmax * (w / Wmax + (lambda * (1.0 - (w / Wmax)) ** mu_plus * pre_trace)) + if I_post_dend <= 1pA: + w_ = (I_post_dend / pA) * w_ + (1 - I_post_dend / pA) * w # "gating" of the weight update + end + w = min(Wmax,w_) + end + + onReceive(pre_spikes): + # depress synapse + w_ real = Wmax * (w / Wmax - (alpha * lambda * (w / Wmax) ** mu_minus * post_trace)) + if I_post_dend <= 1pA: + w_ = (I_post_dend / pA) * w_ + (1 - I_post_dend / pA) * w # "gating" of the weight update + end + w = max(Wmin,w_) + # deliver spike to postsynaptic partner + deliver_spike(w,the_delay) + end + + end + + + +Characterisation +++++++++++++++++ + +.. include:: third_factor_stdp_characterisation.rst + + +.. footer:: + + Generated at 2021-12-09 08:22:33.033176 \ No newline at end of file diff --git a/doc/models_library/traub_cond_multisyn.rst b/doc/models_library/traub_cond_multisyn.rst index b46d182ac..389d4b756 100644 --- a/doc/models_library/traub_cond_multisyn.rst +++ b/doc/models_library/traub_cond_multisyn.rst @@ -1,29 +1,32 @@ traub_cond_multisyn ################### -Name: traub_cond_multisyn - Traub model according to Borgers 2017. -Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus[1]. -parameters got from reference [2] chapter 5. +traub_cond_multisyn - Traub model according to Borgers 2017 +Description ++++++++++++ + +Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. +parameters got from reference [2]_ chapter 5. -Spike Detection - Spike detection is done by a combined threshold-and-local-maximum search: if - there is a local maximum above a certain threshold of the membrane potential, - it is considered a spike. +AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with +beta-function (difference of two exponentials) time course corresponding +to "hill_tononi" model. -- AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with - beta-function (difference of two exponentials) time course corresponding - to "hill_tononi" model. +References +++++++++++ + +.. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. +.. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. -References: -[1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. -[2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. +See also +++++++++ +hh_cond_exp_traub -SeeAlso: hh_cond_exp_traub Parameters @@ -47,21 +50,21 @@ Parameters "V_Tr", "mV", "-20.0mV", "Spike Threshold" "AMPA_g_peak", "nS", "0.1nS", "Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDApeak conductance" "AMPA_E_rev", "mV", "0.0mV", "reversal potential" - "AMPA_Tau_1", "ms", "0.5ms", "rise time" - "AMPA_Tau_2", "ms", "2.4ms", "decay time, Tau_1 < Tau_2" + "tau_AMPA_1", "ms", "0.5ms", "rise time" + "tau_AMPA_2", "ms", "2.4ms", "decay time, Tau_1 < Tau_2" "NMDA_g_peak", "nS", "0.075nS", "peak conductance" - "NMDA_Tau_1", "ms", "4.0ms", "rise time" - "NMDA_Tau_2", "ms", "40.0ms", "decay time, Tau_1 < Tau_2" + "tau_NMDA_1", "ms", "4.0ms", "rise time" + "tau_NMDA_2", "ms", "40.0ms", "decay time, Tau_1 < Tau_2" "NMDA_E_rev", "mV", "0.0mV", "reversal potential" "NMDA_Vact", "mV", "-58.0mV", "inactive for V << Vact, inflection of sigmoid" "NMDA_Sact", "mV", "2.5mV", "scale of inactivation" "GABA_A_g_peak", "nS", "0.33nS", "peak conductance" - "GABA_A_Tau_1", "ms", "1.0ms", "rise time" - "GABA_A_Tau_2", "ms", "7.0ms", "decay time, Tau_1 < Tau_2" + "tau_GABAA_1", "ms", "1.0ms", "rise time" + "tau_GABAA_2", "ms", "7.0ms", "decay time, Tau_1 < Tau_2" "GABA_A_E_rev", "mV", "-70.0mV", "reversal potential" "GABA_B_g_peak", "nS", "0.0132nS", "peak conductance" - "GABA_B_Tau_1", "ms", "60.0ms", "rise time" - "GABA_B_Tau_2", "ms", "200.0ms", "decay time, Tau_1 < Tau_2" + "tau_GABAB_1", "ms", "60.0ms", "rise time" + "tau_GABAB_2", "ms", "200.0ms", "decay time, Tau_1 < Tau_2" "GABA_B_E_rev", "mV", "-90.0mV", "reversal potential for intrinsic current" "I_e", "pA", "0pA", "constant external input current" @@ -76,24 +79,19 @@ State variables :widths: auto + "r", "integer", "0", "number of steps in the current refractory phase" "V_m", "mV", "-70.0mV", "Membrane potential" - "alpha_n_init", "real", "0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0))", "" - "beta_n_init", "real", "0.5 * exp(-(V_m / mV + 57.0) / 40.0)", "" - "alpha_m_init", "real", "0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0))", "" - "beta_m_init", "real", "0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0)", "" - "alpha_h_init", "real", "0.128 * exp(-(V_m / mV + 50.0) / 18.0)", "" - "beta_h_init", "real", "4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0))", "" "Act_m", "real", "alpha_m_init / (alpha_m_init + beta_m_init)", "Activation variable m for Na" "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "Inactivation variable h for Na" "Act_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "Activation variable n for K" - "g_AMPA", "nS", "0.0nS", "" - "g_AMPA__d", "nS / ms", "0.0nS / ms", "" - "g_NMDA", "nS", "0.0nS", "" - "g_NMDA__d", "nS / ms", "0.0nS / ms", "" - "g_GABAA", "nS", "0.0nS", "" - "g_GABAA__d", "nS / ms", "0.0nS / ms", "" - "g_GABAB", "nS", "0.0nS", "" - "g_GABAB__d", "nS / ms", "0.0nS / ms", "" + "g_AMPA", "real", "0", "" + "g_NMDA", "real", "0", "" + "g_GABAA", "real", "0", "" + "g_GABAB", "real", "0", "" + "g_AMPA$", "real", "AMPAInitialValue", "" + "g_NMDA$", "real", "NMDAInitialValue", "" + "g_GABAA$", "real", "GABA_AInitialValue", "" + "g_GABAB$", "real", "GABA_BInitialValue", "" @@ -120,103 +118,64 @@ Equations \frac{ dInact_{h} } { dt }= \frac 1 { \mathrm{ms} } \left( { (\alpha_{h} \cdot (1 - Inact_{h}) - \beta_{h} \cdot Inact_{h}) } \right) -.. math:: - \frac{ dg_{AMPA,,d} } { dt }= \frac{ -g_{AMPA,,d} } { AMPA_{\Tau,1} } - - -.. math:: - \frac{ dg_{AMPA} } { dt }= g_{AMPA,,d} - \frac{ g_{AMPA} } { AMPA_{\Tau,2} } - - -.. math:: - \frac{ dg_{NMDA,,d} } { dt }= \frac{ -g_{NMDA,,d} } { NMDA_{\Tau,1} } - - -.. math:: - \frac{ dg_{NMDA} } { dt }= g_{NMDA,,d} - \frac{ g_{NMDA} } { NMDA_{\Tau,2} } - - -.. math:: - \frac{ dg_{GABAA,,d} } { dt }= \frac{ -g_{GABAA,,d} } { GABA_{A,\Tau,1} } - - -.. math:: - \frac{ dg_{GABAA} } { dt }= g_{GABAA,,d} - \frac{ g_{GABAA} } { GABA_{A,\Tau,2} } - - -.. math:: - \frac{ dg_{GABAB,,d} } { dt }= \frac{ -g_{GABAB,,d} } { GABA_{B,\Tau,1} } - - -.. math:: - \frac{ dg_{GABAB} } { dt }= g_{GABAB,,d} - \frac{ g_{GABAB} } { GABA_{B,\Tau,2} } - - Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron traub_cond_multisyn: state: - r integer # number of steps in the current refractory phase - end - initial_values: + r integer = 0 # number of steps in the current refractory phase V_m mV = -70.0mV # Membrane potential - function alpha_n_init real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) - function beta_n_init real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) - function alpha_m_init real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) - function beta_m_init real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) - function alpha_h_init real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) - function beta_h_init real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) Act_m real = alpha_m_init / (alpha_m_init + beta_m_init) # Activation variable m for Na Inact_h real = alpha_h_init / (alpha_h_init + beta_h_init) # Inactivation variable h for Na Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) # Activation variable n for K - g_AMPA nS = 0.0nS - g_AMPA__d nS/ms = 0.0nS / ms - g_NMDA nS = 0.0nS - g_NMDA__d nS/ms = 0.0nS / ms - g_GABAA nS = 0.0nS - g_GABAA__d nS/ms = 0.0nS / ms - g_GABAB nS = 0.0nS - g_GABAB__d nS/ms = 0.0nS / ms + g_AMPA real = 0 + g_NMDA real = 0 + g_GABAA real = 0 + g_GABAB real = 0 + g_AMPA$ real = AMPAInitialValue + g_NMDA$ real = NMDAInitialValue + g_GABAA$ real = GABA_AInitialValue + g_GABAB$ real = GABA_BInitialValue end equations: - recordable function I_syn_ampa pA = -g_AMPA * (V_m - AMPA_E_rev) - recordable function I_syn_nmda pA = -g_NMDA * (V_m - NMDA_E_rev) / (1 + exp((NMDA_Vact - V_m) / NMDA_Sact)) - recordable function I_syn_gaba_a pA = -g_GABAA * (V_m - GABA_A_E_rev) - recordable function I_syn_gaba_b pA = -g_GABAB * (V_m - GABA_B_E_rev) - recordable function I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b - function I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * (V_m - E_Na) - function I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) + recordable inline I_syn_ampa pA = -convolve(g_AMPA,AMPA) * (V_m - AMPA_E_rev) + recordable inline I_syn_nmda pA = -convolve(g_NMDA,NMDA) * (V_m - NMDA_E_rev) / (1 + exp((NMDA_Vact - V_m) / NMDA_Sact)) + recordable inline I_syn_gaba_a pA = -convolve(g_GABAA,GABA_A) * (V_m - GABA_A_E_rev) + recordable inline I_syn_gaba_b pA = -convolve(g_GABAB,GABA_B) * (V_m - GABA_B_E_rev) + recordable inline I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * (V_m - E_Na) + inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn) / C_m - - /* Act_n*/ - function alpha_n real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) - function beta_n real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) + # Act_n + inline alpha_n real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) + inline beta_n real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) Act_n'=(alpha_n * (1 - Act_n) - beta_n * Act_n) / ms # n-variable + # Act_m - /* Act_m*/ - function alpha_m real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) - function beta_m real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) + # Act_m + inline alpha_m real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) + inline beta_m real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) Act_m'=(alpha_m * (1 - Act_m) - beta_m * Act_m) / ms # m-variable + # Inact_h' - /* Inact_h'*/ - function alpha_h real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) - function beta_h real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) + # Inact_h' + inline alpha_h real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) + inline beta_h real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) Inact_h'=(alpha_h * (1 - Inact_h) - beta_h * Inact_h) / ms # h-variable - g_AMPA__d'=-g_AMPA__d / AMPA_Tau_1 - g_AMPA'=g_AMPA__d - g_AMPA / AMPA_Tau_2 - g_NMDA__d'=-g_NMDA__d / NMDA_Tau_1 - g_NMDA'=g_NMDA__d - g_NMDA / NMDA_Tau_2 - g_GABAA__d'=-g_GABAA__d / GABA_A_Tau_1 - g_GABAA'=g_GABAA__d - g_GABAA / GABA_A_Tau_2 - g_GABAB__d'=-g_GABAB__d / GABA_B_Tau_1 - g_GABAB'=g_GABAB__d - g_GABAB / GABA_B_Tau_2 + ############ + # Synapses + ############ + + kernel g_AMPA' = g_AMPA$ - g_AMPA / tau_AMPA_2, g_AMPA$' = -g_AMPA$ / tau_AMPA_1 + kernel g_NMDA' = g_NMDA$ - g_NMDA / tau_NMDA_2, g_NMDA$' = -g_NMDA$ / tau_NMDA_1 + kernel g_GABAA' = g_GABAA$ - g_GABAA / tau_GABAA_2, g_GABAA$' = -g_GABAA$ / tau_GABAA_1 + kernel g_GABAB' = g_GABAB$ - g_GABAB / tau_GABAB_2, g_GABAB$' = -g_GABAB$ / tau_GABAB_1 end parameters: @@ -229,36 +188,44 @@ Source code E_K mV = -100.0mV # Potassium reversal potentia E_L mV = -67.0mV # Leak reversal Potential (aka resting potential) V_Tr mV = -20.0mV # Spike Threshold + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA - /* Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA*/ + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA AMPA_g_peak nS = 0.1nS # peak conductance AMPA_E_rev mV = 0.0mV # reversal potential - AMPA_Tau_1 ms = 0.5ms # rise time - AMPA_Tau_2 ms = 2.4ms # decay time, Tau_1 < Tau_2 + tau_AMPA_1 ms = 0.5ms # rise time + tau_AMPA_2 ms = 2.4ms # decay time, Tau_1 < Tau_2 NMDA_g_peak nS = 0.075nS # peak conductance - NMDA_Tau_1 ms = 4.0ms # rise time - NMDA_Tau_2 ms = 40.0ms # decay time, Tau_1 < Tau_2 + tau_NMDA_1 ms = 4.0ms # rise time + tau_NMDA_2 ms = 40.0ms # decay time, Tau_1 < Tau_2 NMDA_E_rev mV = 0.0mV # reversal potential NMDA_Vact mV = -58.0mV # inactive for V << Vact, inflection of sigmoid NMDA_Sact mV = 2.5mV # scale of inactivation GABA_A_g_peak nS = 0.33nS # peak conductance - GABA_A_Tau_1 ms = 1.0ms # rise time - GABA_A_Tau_2 ms = 7.0ms # decay time, Tau_1 < Tau_2 + tau_GABAA_1 ms = 1.0ms # rise time + tau_GABAA_2 ms = 7.0ms # decay time, Tau_1 < Tau_2 GABA_A_E_rev mV = -70.0mV # reversal potential GABA_B_g_peak nS = 0.0132nS # peak conductance - GABA_B_Tau_1 ms = 60.0ms # rise time - GABA_B_Tau_2 ms = 200.0ms # decay time, Tau_1 < Tau_2 + tau_GABAB_1 ms = 60.0ms # rise time + tau_GABAB_2 ms = 200.0ms # decay time, Tau_1 < Tau_2 GABA_B_E_rev mV = -90.0mV # reversal potential for intrinsic current + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: - AMPAInitialValue real = compute_synapse_constant(AMPA_Tau_1,AMPA_Tau_2,AMPA_g_peak) - NMDAInitialValue real = compute_synapse_constant(NMDA_Tau_1,NMDA_Tau_2,NMDA_g_peak) - GABA_AInitialValue real = compute_synapse_constant(GABA_A_Tau_1,GABA_A_Tau_2,GABA_A_g_peak) - GABA_BInitialValue real = compute_synapse_constant(GABA_B_Tau_1,GABA_B_Tau_2,GABA_B_g_peak) + AMPAInitialValue real = compute_synapse_constant(tau_AMPA_1,tau_AMPA_2,AMPA_g_peak) + NMDAInitialValue real = compute_synapse_constant(tau_NMDA_1,tau_NMDA_2,NMDA_g_peak) + GABA_AInitialValue real = compute_synapse_constant(tau_GABAA_1,tau_GABAA_2,GABA_A_g_peak) + GABA_BInitialValue real = compute_synapse_constant(tau_GABAB_1,tau_GABAB_2,GABA_B_g_peak) RefractoryCounts integer = steps(t_ref) # refractory time in steps + alpha_n_init real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) + beta_n_init real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) + alpha_m_init real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) + beta_m_init real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) + alpha_h_init real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) + beta_h_init real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) end input: AMPA nS <-spike @@ -273,12 +240,7 @@ Source code update: U_old mV = V_m integrate_odes() - g_AMPA__d += AMPAInitialValue * AMPA / ms - g_NMDA__d += NMDAInitialValue * NMDA / ms - g_GABAA__d += GABA_AInitialValue * GABA_A / ms - g_GABAB__d += GABA_BInitialValue * GABA_B / ms - - /* sending spikes: */ + # sending spikes: if r > 0: # is refractory? r -= 1 elif V_m > V_Tr and U_old > V_Tr: @@ -288,12 +250,11 @@ Source code end function compute_synapse_constant(Tau_1 msTau_2 msg_peak real) real: - - /* Factor used to account for the missing 1/((1/Tau_2)-(1/Tau_1)) term*/ - /* in the ht_neuron_dynamics integration of the synapse terms.*/ - /* See: Exact digital simulation of time-invariant linear systems*/ - /* with applications to neuronal modeling, Rotter and Diesmann,*/ - /* section 3.1.2.*/ + # Factor used to account for the missing 1/((1/Tau_2)-(1/Tau_1)) term + # in the ht_neuron_dynamics integration of the synapse terms. + # See: Exact digital simulation of time-invariant linear systems + # with applications to neuronal modeling, Rotter and Diesmann, + # section 3.1.2. exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms t_peak real = (Tau_2 * Tau_1) * ln(Tau_2 / Tau_1) / (Tau_2 - Tau_1) / ms normalisation_factor real = 1 / (exp(-t_peak / Tau_1) - exp(-t_peak / Tau_2)) @@ -312,4 +273,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.253476 \ No newline at end of file + Generated at 2022-03-28 19:04:28.885171 \ No newline at end of file diff --git a/doc/models_library/traub_psc_alpha.rst b/doc/models_library/traub_psc_alpha.rst index 522d10582..3d916bcc3 100644 --- a/doc/models_library/traub_psc_alpha.rst +++ b/doc/models_library/traub_psc_alpha.rst @@ -1,28 +1,27 @@ traub_psc_alpha ############### -Name: traub_psc_alpha - Traub model according to Borgers 2017. -Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus[1]. -parameters got from reference [2]. +traub_psc_alpha - Traub model according to Borgers 2017 -(1) Post-synaptic currents - Incoming spike events induce a post-synaptic change of current modelled - by an alpha function. +Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. +parameters got from reference [2]_. -(2) Spike Detection - Spike detection is done by a combined threshold-and-local-maximum search: if - there is a local maximum above a certain threshold of the membrane potential, - it is considered a spike. +Incoming spike events induce a post-synaptic change of current modelled +by an alpha function. +References +++++++++++ + +.. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. +.. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. -References: -[1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. -[2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. +See also +++++++++ +hh_cond_exp_traub -SeeAlso: hh_cond_exp_traub Parameters @@ -35,17 +34,17 @@ Parameters :widths: auto - "t_ref", "ms", "2.0ms", "Refractory period 2.0" - "g_Na", "nS", "10000.0nS", "Sodium peak conductance" - "g_K", "nS", "8000.0nS", "Potassium peak conductance" + "t_ref", "ms", "2ms", "Refractory period" + "g_Na", "nS", "10000nS", "Sodium peak conductance" + "g_K", "nS", "8000nS", "Potassium peak conductance" "g_L", "nS", "10nS", "Leak conductance" - "C_m", "pF", "100.0pF", "Membrane Capacitance" - "E_Na", "mV", "50.0mV", "Sodium reversal potential" - "E_K", "mV", "-100.0mV", "Potassium reversal potentia" - "E_L", "mV", "-67.0mV", "Leak reversal Potential (aka resting potential)" - "V_Tr", "mV", "-20.0mV", "Spike Threshold" - "tau_syn_ex", "ms", "0.2ms", "Rise time of the excitatory synaptic alpha function i" - "tau_syn_in", "ms", "2.0ms", "Rise time of the inhibitory synaptic alpha function" + "C_m", "pF", "100pF", "Membrane capacitance" + "E_Na", "mV", "50mV", "Sodium reversal potential" + "E_K", "mV", "-100mV", "Potassium reversal potential" + "E_L", "mV", "-67mV", "Leak reversal potential (aka resting potential)" + "V_Tr", "mV", "-20mV", "Spike threshold" + "tau_syn_exc", "ms", "0.2ms", "Rise time of the excitatory synaptic alpha function" + "tau_syn_inh", "ms", "2ms", "Rise time of the inhibitory synaptic alpha function" "I_e", "pA", "0pA", "constant external input current" @@ -59,13 +58,8 @@ State variables :widths: auto + "r", "integer", "0", "number of steps in the current refractory phase" "V_m", "mV", "-70.0mV", "Membrane potential" - "alpha_n_init", "real", "0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0))", "" - "beta_n_init", "real", "0.5 * exp(-(V_m / mV + 57.0) / 40.0)", "" - "alpha_m_init", "real", "0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0))", "" - "beta_m_init", "real", "0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0)", "" - "alpha_h_init", "real", "0.128 * exp(-(V_m / mV + 50.0) / 18.0)", "" - "beta_h_init", "real", "4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0))", "" "Act_m", "real", "alpha_m_init / (alpha_m_init + beta_m_init)", "Activation variable m for Na" "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "Inactivation variable h for Na" "Act_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "Activation variable n for K" @@ -80,7 +74,7 @@ Equations .. math:: - \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn,inh} + I_{syn,exc}) } \right) + \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn,exc} - I_{syn,inh}) } \right) .. math:: @@ -101,74 +95,73 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron traub_psc_alpha: state: - r integer # number of steps in the current refractory phase - end - initial_values: + r integer = 0 # number of steps in the current refractory phase V_m mV = -70.0mV # Membrane potential - function alpha_n_init real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) - function beta_n_init real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) - function alpha_m_init real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) - function beta_m_init real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) - function alpha_h_init real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) - function beta_h_init real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) Act_m real = alpha_m_init / (alpha_m_init + beta_m_init) # Activation variable m for Na Inact_h real = alpha_h_init / (alpha_h_init + beta_h_init) # Inactivation variable h for Na Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) # Activation variable n for K end equations: - - /* synapses: alpha functions*/ - kernel I_syn_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel I_syn_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - function I_syn_exc pA = convolve(I_syn_ex,spikeExc) - function I_syn_inh pA = convolve(I_syn_in,spikeInh) - function I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * (V_m - E_Na) - function I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn_inh + I_syn_exc) / C_m - - /* Act_n*/ - function alpha_n real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) - function beta_n real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) + # synapses: alpha functions + kernel K_syn_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel K_syn_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + inline I_syn_exc pA = convolve(K_syn_exc,exc_spikes) + inline I_syn_inh pA = convolve(K_syn_inh,inh_spikes) + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * (V_m - E_Na) + inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn_exc - I_syn_inh) / C_m + # Act_n + inline alpha_n real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) + inline beta_n real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) Act_n'=(alpha_n * (1 - Act_n) - beta_n * Act_n) / ms # n-variable + # Act_m - /* Act_m*/ - function alpha_m real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) - function beta_m real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) + # Act_m + inline alpha_m real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) + inline beta_m real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) Act_m'=(alpha_m * (1 - Act_m) - beta_m * Act_m) / ms # m-variable + # Inact_h' - /* Inact_h'*/ - function alpha_h real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) - function beta_h real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) + # Inact_h' + inline alpha_h real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) + inline beta_h real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) Inact_h'=(alpha_h * (1 - Inact_h) - beta_h * Inact_h) / ms # h-variable end parameters: - t_ref ms = 2.0ms # Refractory period 2.0 - g_Na nS = 10000.0nS # Sodium peak conductance - g_K nS = 8000.0nS # Potassium peak conductance + t_ref ms = 2ms # Refractory period + g_Na nS = 10000nS # Sodium peak conductance + g_K nS = 8000nS # Potassium peak conductance g_L nS = 10nS # Leak conductance - C_m pF = 100.0pF # Membrane Capacitance - E_Na mV = 50.0mV # Sodium reversal potential - E_K mV = -100.0mV # Potassium reversal potentia - E_L mV = -67.0mV # Leak reversal Potential (aka resting potential) - V_Tr mV = -20.0mV # Spike Threshold - tau_syn_ex ms = 0.2ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 2.0ms # Rise time of the inhibitory synaptic alpha function - - /* constant external input current*/ + C_m pF = 100pF # Membrane capacitance + E_Na mV = 50mV # Sodium reversal potential + E_K mV = -100mV # Potassium reversal potential + E_L mV = -67mV # Leak reversal potential (aka resting potential) + V_Tr mV = -20mV # Spike threshold + tau_syn_exc ms = 0.2ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 2ms # Rise time of the inhibitory synaptic alpha function + # constant external input current + + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps + alpha_n_init real = 0.032 * (V_m / mV + 52.0) / (1.0 - exp(-(V_m / mV + 52.0) / 5.0)) + beta_n_init real = 0.5 * exp(-(V_m / mV + 57.0) / 40.0) + alpha_m_init real = 0.32 * (V_m / mV + 54.0) / (1.0 - exp(-(V_m / mV + 54.0) / 4.0)) + beta_m_init real = 0.28 * (V_m / mV + 27.0) / (exp((V_m / mV + 27.0) / 5.0) - 1.0) + alpha_h_init real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) + beta_h_init real = 4.0 / (1.0 + exp(-(V_m / mV + 27.0) / 5.0)) end input: - spikeInh pA <-inhibitory spike - spikeExc pA <-excitatory spike + inh_spikes pA <-inhibitory spike + exc_spikes pA <-excitatory spike I_stim pA <-current end @@ -177,9 +170,9 @@ Source code update: U_old mV = V_m integrate_odes() - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: # is refractory? r -= 1 elif V_m > V_Tr and U_old > V_Tr: @@ -200,4 +193,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:45.520049 \ No newline at end of file + Generated at 2022-03-28 19:04:29.609967 \ No newline at end of file diff --git a/doc/models_library/wb_cond_exp.rst b/doc/models_library/wb_cond_exp.rst index 8b790c916..83254acae 100644 --- a/doc/models_library/wb_cond_exp.rst +++ b/doc/models_library/wb_cond_exp.rst @@ -1,26 +1,33 @@ wb_cond_exp ########### -Name: wb_cond_exp - Wang buzsaki model -Description: +wb_cond_exp - Wang-Buzsaki model -wb_cond_exp is an implementation of a modified Hodkin-Huxley model -(1) Post-synaptic currents - Incoming spike events induce a post-synaptic change of conductance modeled - by an exponential function. +Description ++++++++++++ + +wb_cond_exp is an implementation of a modified Hodkin-Huxley model. + +(1) Post-synaptic currents: Incoming spike events induce a post-synaptic change + of conductance modeled by an exponential function. -(2) Spike Detection - Spike detection is done by a combined threshold-and-local-maximum search: if - there is a local maximum above a certain threshold of the membrane potential, - it is considered a spike. +(2) Spike Detection: Spike detection is done by a combined threshold-and-local- + maximum search: if there is a local maximum above a certain threshold of + the membrane potential, it is considered a spike. -References: +References +++++++++++ + +.. [1] Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic + inhibition in a hippocampal interneuronal network model. Journal of + neuroscience, 16(20), pp.6402-6413. -Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic inhibition in a hippocampal interneuronal network model. Journal of neuroscience, 16(20), pp.6402-6413. +See Also +++++++++ +hh_cond_exp_traub, wb_cond_multisyn -SeeAlso: hh_cond_exp_traub Parameters @@ -33,19 +40,19 @@ Parameters :widths: auto - "t_ref", "ms", "2.0ms", "Refractory period" - "g_Na", "nS", "3500.0nS", "Sodium peak conductance" - "g_K", "nS", "900.0nS", "Potassium peak conductance" + "t_ref", "ms", "2ms", "Refractory period" + "g_Na", "nS", "3500nS", "Sodium peak conductance" + "g_K", "nS", "900nS", "Potassium peak conductance" "g_L", "nS", "10nS", "Leak conductance" - "C_m", "pF", "100.0pF", "Membrane Capacitance" - "E_Na", "mV", "55.0mV", "Sodium reversal potential" - "E_K", "mV", "-90.0mV", "Potassium reversal potentia" - "E_L", "mV", "-65.0mV", "Leak reversal Potential (aka resting potential)" - "V_Tr", "mV", "-55.0mV", "Spike Threshold" - "tau_syn_ex", "ms", "0.2ms", "Rise time of the excitatory synaptic alpha function i" - "tau_syn_in", "ms", "10.0ms", "Rise time of the inhibitory synaptic alpha function" - "E_ex", "mV", "0.0mV", "Excitatory synaptic reversal potential" - "E_in", "mV", "-75.0mV", "Inhibitory synaptic reversal potential" + "C_m", "pF", "100pF", "Membrane capacitance" + "E_Na", "mV", "55mV", "Sodium reversal potential" + "E_K", "mV", "-90mV", "Potassium reversal potential" + "E_L", "mV", "-65mV", "Leak reversal potential (aka resting potential)" + "V_Tr", "mV", "-55mV", "Spike threshold" + "tau_syn_exc", "ms", "0.2ms", "Rise time of the excitatory synaptic alpha function" + "tau_syn_inh", "ms", "10ms", "Rise time of the inhibitory synaptic alpha function" + "E_exc", "mV", "0mV", "Excitatory synaptic reversal potential" + "E_inh", "mV", "-75mV", "Inhibitory synaptic reversal potential" "I_e", "pA", "0pA", "constant external input current" @@ -59,14 +66,9 @@ State variables :widths: auto - "V_m", "mV", "-65.0mV", "Membrane potential" - "alpha_n_init", "1 / ms", "-0.05 / (ms * mV) * (V_m + 34.0mV) / (exp(-0.1 * (V_m + 34.0mV)) - 1.0)", "" - "beta_n_init", "1 / ms", "0.625 / ms * exp(-(V_m + 44.0mV) / 80.0mV)", "" - "alpha_m_init", "1 / ms", "0.1 / (ms * mV) * (V_m + 35.0mV) / (1.0 - exp(-0.1mV * (V_m + 35.0mV)))", "" - "beta_m_init", "1 / ms", "4.0 / (ms) * exp(-(V_m + 60.0mV) / 18.0mV)", "" - "alpha_h_init", "1 / ms", "0.35 / ms * exp(-(V_m + 58.0mV) / 20.0mV)", "" - "beta_h_init", "1 / ms", "5.0 / (exp(-0.1 / mV * (V_m + 28.0mV)) + 1.0) / ms", "" - "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init )" + "r", "integer", "0", "number of steps in the current refractory phase" + "V_m", "mV", "E_L", "Membrane potential" + "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "" "Act_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "" @@ -79,15 +81,15 @@ Equations .. math:: - \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn,inh} + I_{syn,exc}) } \right) + \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn,exc} - I_{syn,inh}) } \right) .. math:: - \frac{ dAct_{n} } { dt }= (\alpha_{n} \cdot (1 - Act_{n}) - \beta_{n} \cdot Act_{n}) + \frac{ dAct_{n} } { dt }= (alpha_n(V_{m}) \cdot (1 - Act_{n}) - beta_n(V_{m}) \cdot Act_{n}) .. math:: - \frac{ dInact_{h} } { dt }= (\alpha_{h} \cdot (1 - Inact_{h}) - \beta_{h} \cdot Inact_{h}) + \frac{ dInact_{h} } { dt }= (alpha_h(V_{m}) \cdot (1 - Inact_{h}) - beta_h(V_{m}) \cdot Inact_{h}) @@ -96,73 +98,58 @@ Equations Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron wb_cond_exp: state: - r integer # number of steps in the current refractory phase - end - initial_values: - V_m mV = -65.0mV # Membrane potential - function alpha_n_init 1/ms = -0.05 / (ms * mV) * (V_m + 34.0mV) / (exp(-0.1 * (V_m + 34.0mV)) - 1.0) - function beta_n_init 1/ms = 0.625 / ms * exp(-(V_m + 44.0mV) / 80.0mV) - function alpha_m_init 1/ms = 0.1 / (ms * mV) * (V_m + 35.0mV) / (1.0 - exp(-0.1mV * (V_m + 35.0mV))) - function beta_m_init 1/ms = 4.0 / (ms) * exp(-(V_m + 60.0mV) / 18.0mV) - function alpha_h_init 1/ms = 0.35 / ms * exp(-(V_m + 58.0mV) / 20.0mV) - function beta_h_init 1/ms = 5.0 / (exp(-0.1 / mV * (V_m + 28.0mV)) + 1.0) / ms - - /* Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init )*/ + r integer = 0 # number of steps in the current refractory phase + V_m mV = E_L # Membrane potential Inact_h real = alpha_h_init / (alpha_h_init + beta_h_init) Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) end equations: - - /* synapses: exponential conductance*/ - kernel g_in = exp(-1.0 / tau_syn_in * t) - kernel g_ex = exp(-1.0 / tau_syn_ex * t) - recordable function I_syn_exc pA = convolve(g_ex,spikeExc) * (V_m - E_ex) - recordable function I_syn_inh pA = convolve(g_in,spikeInh) * (V_m - E_in) - function alpha_n 1/ms = -0.05 / (ms * mV) * (V_m + 34.0mV) / (exp(-0.1 * (V_m + 34.0mV)) - 1.0) - function beta_n 1/ms = 0.625 / ms * exp(-(V_m + 44.0mV) / 80.0mV) - function alpha_m 1/ms = 0.1 / (ms * mV) * (V_m + 35.0mV) / (1.0 - exp(-0.1mV * (V_m + 35.0mV))) - function beta_m 1/ms = 4.0 / (ms) * exp(-(V_m + 60.0mV) / 18.0mV) - function alpha_h 1/ms = 0.35 / ms * exp(-(V_m + 58.0mV) / 20.0mV) - function beta_h 1/ms = 5.0 / (exp(-0.1 / mV * (V_m + 28.0mV)) + 1.0) / ms - - /* alias Act_m real = alpha_m / ( alpha_m + beta_m ) */ - /* function I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * ( V_m - E_Na )*/ - function I_Na pA = g_Na * alpha_m / (alpha_m + beta_m) * alpha_m / (alpha_m + beta_m) * alpha_m / (alpha_m + beta_m) * Inact_h * (V_m - E_Na) - function I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn_inh + I_syn_exc) / C_m - Act_n'=(alpha_n * (1 - Act_n) - beta_n * Act_n) # n-variable - Inact_h'=(alpha_h * (1 - Inact_h) - beta_h * Inact_h) # h-variable + # synapses: exponential conductance + kernel g_inh = exp(-t / tau_syn_inh) + kernel g_exc = exp(-t / tau_syn_exc) + recordable inline I_syn_exc pA = convolve(g_exc,exc_spikes) * (V_m - E_exc) + recordable inline I_syn_inh pA = convolve(g_inh,inh_spikes) * (V_m - E_inh) + inline I_Na pA = g_Na * _subexpr(V_m) * Inact_h * (V_m - E_Na) + inline I_K pA = g_K * Act_n ** 4 * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn_exc - I_syn_inh) / C_m + Act_n'=(alpha_n(V_m) * (1 - Act_n) - beta_n(V_m) * Act_n) # n-variable + Inact_h'=(alpha_h(V_m) * (1 - Inact_h) - beta_h(V_m) * Inact_h) # h-variable end parameters: - t_ref ms = 2.0ms # Refractory period - g_Na nS = 3500.0nS # Sodium peak conductance - g_K nS = 900.0nS # Potassium peak conductance + t_ref ms = 2ms # Refractory period + g_Na nS = 3500nS # Sodium peak conductance + g_K nS = 900nS # Potassium peak conductance g_L nS = 10nS # Leak conductance - C_m pF = 100.0pF # Membrane Capacitance - E_Na mV = 55.0mV # Sodium reversal potential - E_K mV = -90.0mV # Potassium reversal potentia - E_L mV = -65.0mV # Leak reversal Potential (aka resting potential) - V_Tr mV = -55.0mV # Spike Threshold - tau_syn_ex ms = 0.2ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 10.0ms # Rise time of the inhibitory synaptic alpha function - E_ex mV = 0.0mV # Excitatory synaptic reversal potential - E_in mV = -75.0mV # Inhibitory synaptic reversal potential - - /* constant external input current*/ + C_m pF = 100pF # Membrane capacitance + E_Na mV = 55mV # Sodium reversal potential + E_K mV = -90mV # Potassium reversal potential + E_L mV = -65mV # Leak reversal potential (aka resting potential) + V_Tr mV = -55mV # Spike threshold + tau_syn_exc ms = 0.2ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 10ms # Rise time of the inhibitory synaptic alpha function + E_exc mV = 0mV # Excitatory synaptic reversal potential + E_inh mV = -75mV # Inhibitory synaptic reversal potential + # constant external input current + + # constant external input current I_e pA = 0pA end internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps + alpha_n_init 1/ms = -0.05 / (ms * mV) * (E_L + 34.0mV) / (exp(-0.1 * (E_L + 34.0mV)) - 1.0) + beta_n_init 1/ms = 0.625 / ms * exp(-(E_L + 44.0mV) / 80.0mV) + alpha_h_init 1/ms = 0.35 / ms * exp(-(E_L + 58.0mV) / 20.0mV) + beta_h_init 1/ms = 5.0 / (exp(-0.1 / mV * (E_L + 28.0mV)) + 1.0) / ms end input: - spikeInh nS <-inhibitory spike - spikeExc nS <-excitatory spike + inh_spikes nS <-inhibitory spike + exc_spikes nS <-excitatory spike I_stim pA <-current end @@ -171,9 +158,9 @@ Source code update: U_old mV = V_m integrate_odes() - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... - /* sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...*/ + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: # is refractory? r -= 1 elif V_m > V_Tr and U_old > V_m: @@ -182,6 +169,34 @@ Source code end end + function _subexpr(V_m mV) real: + return alpha_m(V_m) ** 3 / (alpha_m(V_m) + beta_m(V_m)) ** 3 + end + + function alpha_m(V_m mV) 1/ms: + return 0.1 / (ms * mV) * (V_m + 35.0mV) / (1.0 - exp(-0.1mV * (V_m + 35.0mV))) + end + + function beta_m(V_m mV) 1/ms: + return 4.0 / (ms) * exp(-(V_m + 60.0mV) / 18.0mV) + end + + function alpha_n(V_m mV) 1/ms: + return -0.05 / (ms * mV) * (V_m + 34.0mV) / (exp(-0.1 * (V_m + 34.0mV)) - 1.0) + end + + function beta_n(V_m mV) 1/ms: + return 0.625 / ms * exp(-(V_m + 44.0mV) / 80.0mV) + end + + function alpha_h(V_m mV) 1/ms: + return 0.35 / ms * exp(-(V_m + 58.0mV) / 20.0mV) + end + + function beta_h(V_m mV) 1/ms: + return 5.0 / (exp(-0.1 / mV * (V_m + 28.0mV)) + 1.0) / ms + end + end @@ -194,4 +209,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.707062 \ No newline at end of file + Generated at 2022-03-28 19:04:29.829103 \ No newline at end of file diff --git a/doc/models_library/wb_cond_multisyn.rst b/doc/models_library/wb_cond_multisyn.rst index 1fb3aa26d..2980c79de 100644 --- a/doc/models_library/wb_cond_multisyn.rst +++ b/doc/models_library/wb_cond_multisyn.rst @@ -1,25 +1,7 @@ wb_cond_multisyn ################ -Name: wb_cond_multisyn - Wang buzsaki model with -Description: - -wb_cond_multisyn is an implementation of a modified Hodkin-Huxley model - -Spike Detection - Spike detection is done by a combined threshold-and-local-maximum search: if - there is a local maximum above a certain threshold of the membrane potential, - it is considered a spike. - -- AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with - beta-function (difference of two exponentials) time course. - -References: - -Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic inhibition in a hippocampal interneuronal network model. Journal of neuroscience, 16(20), pp.6402-6413. - -SeeAlso: hill_tononi Parameters @@ -72,23 +54,18 @@ State variables :widths: auto + "r", "integer", "0", "number of steps in the current refractory phase" "V_m", "mV", "-65.0mV", "Membrane potential" - "alpha_n_init", "real", "-0.05 * (V_m / mV + 34.0) / (exp(-0.1 * (V_m / mV + 34.0)) - 1.0)", "function alpha_n_init real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.))" - "beta_n_init", "real", "0.625 * exp(-(V_m / mV + 44.0) / 80.0)", "" - "alpha_m_init", "real", "0.1 * (V_m / mV + 35.0) / (1.0 - exp(-0.1mV * (V_m / mV + 35.0mV)))", "" - "beta_m_init", "real", "4.0 * exp(-(V_m / mV + 60.0) / 18.0)", "" - "alpha_h_init", "real", "0.35 * exp(-(V_m / mV + 58.0) / 20.0)", "" - "beta_h_init", "real", "5.0 / (exp(-0.1 * (V_m / mV + 28.0)) + 1.0)", "" - "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) Activation variable m for NaInactivation variable h for Na" + "Inact_h", "real", "alpha_h_init / (alpha_h_init + beta_h_init)", "Inactivation variable h for Na" "Act_n", "real", "alpha_n_init / (alpha_n_init + beta_n_init)", "Activation variable n for K" - "g_AMPA", "nS", "0.0nS", "" - "g_AMPA__d", "nS / ms", "0.0nS / ms", "" - "g_NMDA", "nS", "0.0nS", "" - "g_NMDA__d", "nS / ms", "0.0nS / ms", "" - "g_GABAA", "nS", "0.0nS", "" - "g_GABAA__d", "nS / ms", "0.0nS / ms", "" - "g_GABAB", "nS", "0.0nS", "" - "g_GABAB__d", "nS / ms", "0.0nS / ms", "" + "g_AMPA", "real", "0", "" + "g_NMDA", "real", "0", "" + "g_GABAA", "real", "0", "" + "g_GABAB", "real", "0", "" + "g_AMPA$", "real", "AMPAInitialValue", "" + "g_NMDA$", "real", "NMDAInitialValue", "" + "g_GABAA$", "real", "GABA_AInitialValue", "" + "g_GABAB$", "real", "GABA_BInitialValue", "" @@ -100,111 +77,56 @@ Equations .. math:: - \frac{ dInact_{h} } { dt }= \frac 1 { \mathrm{ms} } \left( { (\alpha_{h} \cdot (1 - Inact_{h}) - \beta_{h} \cdot Inact_{h}) } \right) + \frac{ dInact_{h} } { dt }= \frac 1 { \mathrm{ms} } \left( { (alpha_h(V_{m}) \cdot (1 - Inact_{h}) - beta_h(V_{m}) \cdot Inact_{h}) } \right) .. math:: - \frac{ dAct_{n} } { dt }= \frac 1 { \mathrm{ms} } \left( { (\alpha_{n} \cdot (1 - Act_{n}) - \beta_{n} \cdot Act_{n}) } \right) + \frac{ dAct_{n} } { dt }= \frac 1 { \mathrm{ms} } \left( { (alpha_n(V_{m}) \cdot (1 - Act_{n}) - beta_n(V_{m}) \cdot Act_{n}) } \right) .. math:: \frac{ dV_{m} } { dt }= \frac 1 { C_{m} } \left( { (-(I_{Na} + I_{K} + I_{L}) + I_{e} + I_{stim} + I_{syn}) } \right) -.. math:: - \frac{ dg_{AMPA,,d} } { dt }= \frac{ -g_{AMPA,,d} } { AMPA_{\Tau,1} } - - -.. math:: - \frac{ dg_{AMPA} } { dt }= g_{AMPA,,d} - \frac{ g_{AMPA} } { AMPA_{\Tau,2} } - - -.. math:: - \frac{ dg_{NMDA,,d} } { dt }= \frac{ -g_{NMDA,,d} } { NMDA_{\Tau,1} } - - -.. math:: - \frac{ dg_{NMDA} } { dt }= g_{NMDA,,d} - \frac{ g_{NMDA} } { NMDA_{\Tau,2} } - - -.. math:: - \frac{ dg_{GABAA,,d} } { dt }= \frac{ -g_{GABAA,,d} } { GABA_{A,\Tau,1} } - - -.. math:: - \frac{ dg_{GABAA} } { dt }= g_{GABAA,,d} - \frac{ g_{GABAA} } { GABA_{A,\Tau,2} } - - -.. math:: - \frac{ dg_{GABAB,,d} } { dt }= \frac{ -g_{GABAB,,d} } { GABA_{B,\Tau,1} } - - -.. math:: - \frac{ dg_{GABAB} } { dt }= g_{GABAB,,d} - \frac{ g_{GABAB} } { GABA_{B,\Tau,2} } - - Source code +++++++++++ -.. code:: nestml +.. code-block:: nestml neuron wb_cond_multisyn: state: - r integer # number of steps in the current refractory phase - end - initial_values: + r integer = 0 # number of steps in the current refractory phase V_m mV = -65.0mV # Membrane potential - - /* function alpha_n_init real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.)) */ - function alpha_n_init real = -0.05 * (V_m / mV + 34.0) / (exp(-0.1 * (V_m / mV + 34.0)) - 1.0) - function beta_n_init real = 0.625 * exp(-(V_m / mV + 44.0) / 80.0) - function alpha_m_init real = 0.1 * (V_m / mV + 35.0) / (1.0 - exp(-0.1mV * (V_m / mV + 35.0mV))) - function beta_m_init real = 4.0 * exp(-(V_m / mV + 60.0) / 18.0) - function alpha_h_init real = 0.35 * exp(-(V_m / mV + 58.0) / 20.0) - function beta_h_init real = 5.0 / (exp(-0.1 * (V_m / mV + 28.0)) + 1.0) - - /* Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) Activation variable m for Na*/ Inact_h real = alpha_h_init / (alpha_h_init + beta_h_init) # Inactivation variable h for Na Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) # Activation variable n for K - g_AMPA nS = 0.0nS - g_AMPA__d nS/ms = 0.0nS / ms - g_NMDA nS = 0.0nS - g_NMDA__d nS/ms = 0.0nS / ms - g_GABAA nS = 0.0nS - g_GABAA__d nS/ms = 0.0nS / ms - g_GABAB nS = 0.0nS - g_GABAB__d nS/ms = 0.0nS / ms + g_AMPA real = 0 + g_NMDA real = 0 + g_GABAA real = 0 + g_GABAB real = 0 + g_AMPA$ real = AMPAInitialValue + g_NMDA$ real = NMDAInitialValue + g_GABAA$ real = GABA_AInitialValue + g_GABAB$ real = GABA_BInitialValue end equations: - recordable function I_syn_ampa pA = -g_AMPA * (V_m - AMPA_E_rev) - recordable function I_syn_nmda pA = -g_NMDA * (V_m - NMDA_E_rev) / (1 + exp((NMDA_Vact - V_m) / NMDA_Sact)) - recordable function I_syn_gaba_a pA = -g_GABAA * (V_m - GABA_A_E_rev) - recordable function I_syn_gaba_b pA = -g_GABAB * (V_m - GABA_B_E_rev) - recordable function I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b - function alpha_n real = -0.05 * (V_m / mV + 34.0) / (exp(-0.1 * (V_m / mV + 34.0)) - 1.0) - function beta_n real = 0.625 * exp(-(V_m / mV + 44.0) / 80.0) - function alpha_m real = 0.1 * (V_m / mV + 35.0) / (1.0 - exp(-0.1mV * (V_m / mV + 35.0mV))) - function beta_m real = 4.0 * exp(-(V_m / mV + 60.0) / 18.0) - function alpha_h real = 0.35 * exp(-(V_m / mV + 58.0) / 20.0) - function beta_h real = 5.0 / (exp(-0.1 * (V_m / mV + 28.0)) + 1.0) - function Act_m_inf real = alpha_m / (alpha_m + beta_m) - function I_Na pA = g_Na * Act_m_inf * Act_m_inf * Act_m_inf * Inact_h * (V_m - E_Na) - function I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * (V_m - E_K) - function I_L pA = g_L * (V_m - E_L) - Inact_h'=(alpha_h * (1 - Inact_h) - beta_h * Inact_h) / ms # h-variable - Act_n'=(alpha_n * (1 - Act_n) - beta_n * Act_n) / ms # n-variable + recordable inline I_syn_ampa pA = -convolve(g_AMPA,AMPA) * (V_m - AMPA_E_rev) + recordable inline I_syn_nmda pA = -convolve(g_NMDA,NMDA) * (V_m - NMDA_E_rev) / (1 + exp((NMDA_Vact - V_m) / NMDA_Sact)) + recordable inline I_syn_gaba_a pA = -convolve(g_GABAA,GABA_A) * (V_m - GABA_A_E_rev) + recordable inline I_syn_gaba_b pA = -convolve(g_GABAB,GABA_B) * (V_m - GABA_B_E_rev) + recordable inline I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b + inline I_Na pA = g_Na * Act_m_inf(V_m) ** 3 * Inact_h * (V_m - E_Na) + inline I_K pA = g_K * Act_n ** 4 * (V_m - E_K) + inline I_L pA = g_L * (V_m - E_L) + Inact_h'=(alpha_h(V_m) * (1 - Inact_h) - beta_h(V_m) * Inact_h) / ms # h-variable + Act_n'=(alpha_n(V_m) * (1 - Act_n) - beta_n(V_m) * Act_n) / ms # n-variable V_m'=(-(I_Na + I_K + I_L) + I_e + I_stim + I_syn) / C_m - g_AMPA__d'=-g_AMPA__d / AMPA_Tau_1 - g_AMPA'=g_AMPA__d - g_AMPA / AMPA_Tau_2 - g_NMDA__d'=-g_NMDA__d / NMDA_Tau_1 - g_NMDA'=g_NMDA__d - g_NMDA / NMDA_Tau_2 - g_GABAA__d'=-g_GABAA__d / GABA_A_Tau_1 - g_GABAA'=g_GABAA__d - g_GABAA / GABA_A_Tau_2 - g_GABAB__d'=-g_GABAB__d / GABA_B_Tau_1 - g_GABAB'=g_GABAB__d - g_GABAB / GABA_B_Tau_2 + kernel g_AMPA' = g_AMPA$ - g_AMPA / AMPA_Tau_2, g_AMPA$' = -g_AMPA$ / AMPA_Tau_1 + kernel g_NMDA' = g_NMDA$ - g_NMDA / NMDA_Tau_2, g_NMDA$' = -g_NMDA$ / NMDA_Tau_1 + kernel g_GABAA' = g_GABAA$ - g_GABAA / GABA_A_Tau_2, g_GABAA$' = -g_GABAA$ / GABA_A_Tau_1 + kernel g_GABAB' = g_GABAB$ - g_GABAB / GABA_B_Tau_2, g_GABAB$' = -g_GABAB$ / GABA_B_Tau_1 end parameters: @@ -217,8 +139,9 @@ Source code E_K mV = -90.0mV # Potassium reversal potentia E_L mV = -65.0mV # Leak reversal Potential (aka resting potential) V_Tr mV = -55.0mV # Spike Threshold + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA - /* Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA*/ + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA AMPA_g_peak nS = 0.1nS # peak conductance AMPA_E_rev mV = 0.0mV # reversal potential AMPA_Tau_1 ms = 0.5ms # rise time @@ -237,8 +160,9 @@ Source code GABA_B_Tau_1 ms = 60.0ms # rise time GABA_B_Tau_2 ms = 200.0ms # decay time, Tau_1 < Tau_2 GABA_B_E_rev mV = -90.0mV # reversal potential for intrinsic current + # constant external input current - /* constant external input current*/ + # constant external input current I_e pA = 0pA end internals: @@ -247,6 +171,12 @@ Source code GABA_AInitialValue real = compute_synapse_constant(GABA_A_Tau_1,GABA_A_Tau_2,GABA_A_g_peak) GABA_BInitialValue real = compute_synapse_constant(GABA_B_Tau_1,GABA_B_Tau_2,GABA_B_g_peak) RefractoryCounts integer = steps(t_ref) # refractory time in steps + alpha_n_init real = -0.05 * (V_m / mV + 34.0) / (exp(-0.1 * (V_m / mV + 34.0)) - 1.0) + beta_n_init real = 0.625 * exp(-(V_m / mV + 44.0) / 80.0) + alpha_m_init real = 0.1 * (V_m / mV + 35.0) / (1.0 - exp(-0.1 * (V_m / mV + 35.0))) + beta_m_init real = 4.0 * exp(-(V_m / mV + 60.0) / 18.0) + alpha_h_init real = 0.35 * exp(-(V_m / mV + 58.0) / 20.0) + beta_h_init real = 5.0 / (exp(-0.1 * (V_m / mV + 28.0)) + 1.0) end input: AMPA nS <-spike @@ -261,12 +191,7 @@ Source code update: U_old mV = V_m integrate_odes() - g_AMPA__d += AMPAInitialValue * AMPA / ms - g_NMDA__d += NMDAInitialValue * NMDA / ms - g_GABAA__d += GABA_AInitialValue * GABA_A / ms - g_GABAB__d += GABA_BInitialValue * GABA_B / ms - - /* sending spikes: */ + # sending spikes: if r > 0: # is refractory? r -= 1 elif V_m > V_Tr and U_old > V_m: @@ -275,17 +200,44 @@ Source code end end - function compute_synapse_constant(Tau_1 msTau_2 msg_peak real) real: - - /* Factor used to account for the missing 1/((1/Tau_2)-(1/Tau_1)) term*/ - /* in the ht_neuron_dynamics integration of the synapse terms.*/ - /* See: Exact digital simulation of time-invariant linear systems*/ - /* with applications to neuronal modeling, Rotter and Diesmann,*/ - /* section 3.1.2.*/ + function compute_synapse_constant(Tau_1 msTau_2 msg_peak nS) real: + # Factor used to account for the missing 1/((1/Tau_2)-(1/Tau_1)) term + # in the ht_neuron_dynamics integration of the synapse terms. + # See: Exact digital simulation of time-invariant linear systems + # with applications to neuronal modeling, Rotter and Diesmann, + # section 3.1.2. exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms - t_peak real = (Tau_2 * Tau_1) * ln(Tau_2 / Tau_1) / (Tau_2 - Tau_1) / ms + t_peak ms = (Tau_2 * Tau_1) * ln(Tau_2 / Tau_1) / (Tau_2 - Tau_1) normalisation_factor real = 1 / (exp(-t_peak / Tau_1) - exp(-t_peak / Tau_2)) - return g_peak * normalisation_factor * exact_integration_adjustment + return (g_peak / nS) * normalisation_factor * exact_integration_adjustment + end + + function Act_m_inf(V_m mV) real: + return alpha_m(V_m) / (alpha_m(V_m) + beta_m(V_m)) + end + + function alpha_m(V_m mV) real: + return 0.1 * (V_m / mV + 35.0) / (1.0 - exp(-0.1 * (V_m / mV + 35.0))) + end + + function beta_m(V_m mV) real: + return 4.0 * exp(-(V_m / mV + 60.0) / 18.0) + end + + function alpha_n(V_m mV) real: + return -0.05 * (V_m / mV + 34.0) / (exp(-0.1 * (V_m / mV + 34.0)) - 1.0) + end + + function beta_n(V_m mV) real: + return 0.625 * exp(-(V_m / mV + 44.0) / 80.0) + end + + function alpha_h(V_m mV) real: + return 0.35 * exp(-(V_m / mV + 58.0) / 20.0) + end + + function beta_h(V_m mV) real: + return 5.0 / (exp(-0.1 * (V_m / mV + 28.0)) + 1.0) end end @@ -300,4 +252,4 @@ Characterisation .. footer:: - Generated at 2020-05-27 18:26:44.376228 \ No newline at end of file + Generated at 2022-03-28 19:04:30.241254 \ No newline at end of file diff --git a/doc/nestml_language/index.rst b/doc/nestml_language/index.rst new file mode 100644 index 000000000..130dacb84 --- /dev/null +++ b/doc/nestml_language/index.rst @@ -0,0 +1,15 @@ +NESTML language documentation +============================= + +.. toctree:: + :maxdepth: 1 + + nestml_language_concepts + neurons_in_nestml + synapses_in_nestml + +NESTML is a domain specific language for the specification of models. NESTML is a completely generic language, but is specifically tailored for the spiking neural network simulator `NEST `__. It has a concise syntax based on that of Python, which avoids clutter in the form of semicolons, curly braces or tags as known from other programming and description languages. Instead, it concentrates on domain concepts that help to efficiently create neuron and synapse models. + +NESTML files are expected to have the filename extension ``.nestml``. Each file may contain one or more models (neuron or synapse). This means that there is no forced direct correspondence between model and file name. Models that shall be compiled into one extension module for NEST have to reside in the same directory. The name of the directory will be used as the name of the corresponding module. + +In order to give users complete freedom in implementing model dynamics, NESTML has a full procedural programming language built in. This programming language can be used to define a custom update function that is executed on each simulation timestep, and to handle events such as receiving a spike. diff --git a/doc/nestml_language.rst b/doc/nestml_language/nestml_language_concepts.rst similarity index 77% rename from doc/nestml_language.rst rename to doc/nestml_language/nestml_language_concepts.rst index cd6451f8b..a1abd8c08 100644 --- a/doc/nestml_language.rst +++ b/doc/nestml_language/nestml_language_concepts.rst @@ -1,11 +1,5 @@ -NESTML language documentation -============================= - -NESTML is a domain specific language for the specification of models for the neuronal simulator `NEST `__. It has a concise syntax based on that of Python which avoids clutter in the form of semicolons, curly braces or tags as known from other programming and description languages. Instead, it concentrates on domain concepts that help to efficiently write neuron models and their equations. - -NESTML files are expected to have the filename extension ``.nestml``. Each file may contain one or more neuron models. This means that there is no forced direct correspondence between model and file name. Models that shall be compiled into one extension module for NEST have to reside in the same directory. The name of the directory will be used as the name of the corresponding module. - -In order to give users complete freedom in implementing neuron model dynamics, NESTML has a full procedural programming language built in. This programming language is used to define the model's time update and functions. +NESTML language concepts +======================== Data types and physical units ----------------------------- @@ -271,48 +265,93 @@ Names of functions and input ports must also satisfy this pattern. The type of t e string = "foo" f mV = -2e12 mV -Documentation strings -~~~~~~~~~~~~~~~~~~~~~ +It is legal to define a variable (or kernel, or parameter) with the same name as a physical unit, but this could lead to confusion. For example, defining a variable with name ``b`` creates an ambiguity with the physical unit ``b``, a unit of surface area. In these cases, a warning is issued when the model is processed. The variable (or kernel, and parameter) definitions will then take precedence when resolving symbols: all occurrences of the symbol in the model will be resolved to the variable rather than the unit. -Declarations can be enriched with special comments which are then taken into generated NEST code. To do so, ``#`` is used to introduce a single line comment. For multi-line comments, Python style comments (``"""..."""``) or Java-style comments (``/* ... */``) can be used. +For example, the following model will result in one warning and one error: .. code-block:: nestml - var1 real # single line comment + neuron test: + state: + ms mA = 42 mA # redefine "ms" (from milliseconds unit to variable name) + foo s = 0 s # foo has units of time (seconds) + end + + update: + ms = 1 mA # WARNING: Variable 'ms' has the same name as a physical unit! + foo = 42 ms # ERROR: Actual type different from expected. Expected: 's', got: 'mA'! + end + end + + +Documentation string +~~~~~~~~~~~~~~~~~~~~ + +Each neuron model may be documented by a block of text in reStructuredText format. Following `PEP 257 "Docstring Conventions" `_, this block should be enclosed in triple double quotes (``""" ... """``) and appear directly before the definition of the neuron. For example: + +.. code-block:: nestml - /* This is - * a comment - * over several lines. - */ - var2 real """ - This is a multiline comment in Python syntax. + iaf_psc_custom: My customized version of iaf_psc + ################################################ + + Description + +++++++++++ + + Long description follows here. We can typeset LaTeX math: + + .. math:: + + E = mc^2 + """ + neuron iaf_psc_custom: + # [...] + end + +This documentation block is rendered as HTML on the `NESTML Models Library `_. + + +Comments in the model +~~~~~~~~~~~~~~~~~~~~~ + +When the character ``#`` appears as the first character on a line (ignoring whitespace), the remainder of that line is allowed to contain any comment string. Comments are not interpreted as part of the model specification, but when a comment is placed in a strategic location, it will be printed into the generated NEST code. + +Example of single or multi-line comments: + +.. code-block:: nestml -To enable NESTML to recognize the commented element uniquely, the following approach has to be used: there should be no white line separating the comment and its target. For example: + var1 real # single line comment + + # This is + # a comment + # over several lines. + +To enable NESTML to recognize which element a comment belongs to, the following approach has to be used: there should be no white line separating the comment and its target. For example: .. code-block:: nestml V_m mV = -55 mV # I am a comment of the membrane potential - /* I am not a comment of the membrane potential. A white line separates us. */ + # I am not a comment of the membrane potential. A white line separates us. If a comment shall be attached to an element, no white lines are allowed. .. code-block:: nestml - V_m mV = -55mV # I am a comment of the membrane potential - /* I am a comment of the membrane potential.*/ + V_m mV = -55 mV # I am a comment of the membrane potential + # I am a comment of the membrane potential. Whitelines are therefore used to separate comment targets: .. code-block:: nestml - V_m mV = -55mV - /* I am a comment of the membrane potential.*/ + V_m mV = -55 mV + # I am a comment of the membrane potential. + + # I am a comment of the resting potential. + V_rest mV = -60 mV - /* I am a comment of the resting potential.*/ - V_rest mV = -60mV Assignments ~~~~~~~~~~~ @@ -327,6 +366,54 @@ Examples for valid assignments for a numeric variable ``n`` are * compound product: ``n *= 10`` which corresponds to ``n = n * 10`` * compound quotient: ``n /= 10`` which corresponds to ``n = n / 10`` +Vectors +~~~~~~~ + +Variables can be declared as vectors to store an array of values. They can be declared in the ``parameters``, ``state``, and ``internals`` blocks. See :ref:`Block types` for more information on different types of blocks available in NESTML. + +The declaration of a vector variable consists of the name of the variable followed by the size of the vector enclosed in ``[`` and ``]``. The vector must be initialized with a default value and all the values in the vector will be initialized to the specified initial value. For example, + +.. code-block:: nestml + + parameters: + g_ex [20] mV = 10mV + end + +Here, ``g_ex`` is a vector of size 20 and all the elements of the vector are initialized to 10mV. Note that the vector index always starts from 0. +Size of the vector can be a positive integer or an integer variable previously declared in either ``parameters`` or ``internals`` block. For example, an integer variable named ``ten`` declared in the ``parameters`` block can be used to specify the size of the vector variable ``g_ex`` as: + +.. code-block:: nestml + + state: + g_ex [ten] mV = 10mV + x [12] real = 0. + end + + parameters: + ten integer = 10 + end + +If the size of a vector is a variable (as ``ten`` in the above example), the vector will be resized if the value of size variable changes during the simulation. On the other hand, the vector cannot be resized if the size is a fixed integer value. +Vector variables can be used in expressions as an array with an index. For example, + +.. code-block:: nestml + + state: + g_ex [ten] mV = 10mV + x[15] real = 0. + end + + parameters: + ten integer = 10 + end + + update: + integer j = 0 + g_ex[2] = -55. mV + x[j] = g_ex[2] + j += 1 + end + Functions ~~~~~~~~~ @@ -420,10 +507,10 @@ The following functions are predefined in NESTML and can be used out of the box: - Log the string s with logging level "warning". * - ``print`` - s - - Print the string s to stdout (no line break at the end). + - Print the string s to stdout (no line break at the end). See :ref:`print function` for more information. * - ``println`` - s - - Print the string s to stdout (with a line break at the end). + - Print the string s to stdout (with a line break at the end). See :ref:`print function` for more information. * - ``integrate_odes`` - - This function can be used to integrate all stated differential equations of the equations block. @@ -456,6 +543,33 @@ e.g. return b end +Printing output to the console +^^^^^^^^^^^^^^ + +The ``print`` and ``println`` functions print a string to the standard output, with ``println`` printing a line break at the end. They can be used in the ``update`` block. See :ref:`Block types` for more information on the ``update`` block. + +Example: + +.. code-block:: nestml + + update: + print("Hello World") + ... + println("Another statement") + end + +Variables defined in the model can be printed by enclosing them in ``{`` and ``}``. For example, variables ``V_m`` and ``V_thr`` used in the model can be printed as: + +.. code-block:: nestml + + update: + ... + print("A spike event with membrane voltage: {V_m}") + ... + println("Membrane voltage {V_m} is less than the threshold {V_thr}") + end + end + Control structures ~~~~~~~~~~~~~~~~~~ @@ -658,182 +772,122 @@ Block types Within the top-level block, the following blocks may be defined: - ``parameters`` - This block is composed of a list of variable declarations that are supposed to contain all parameters which remain constant during the simulation, but can vary among different simulations or instantiations of the same neuron. These variables can be set and read by the user using ``nest.SetStatus(, , )`` and ``nest.GetStatus(, )``. -- ``state`` - This block is composed of a list of variable declarations that are supposed to describe parts of the neuron which may change over time. -- ``initial_values`` - This block describes the initial values of all stated differential equations. Only variables from this block can be further defined with differential equations. The variables in this block can be recorded using a ``multimeter``. +- ``state`` - This block is composed of a list of variable declarations that describe parts of the neuron which may change over time. All the variables declared in this block must be initialized with a value. - ``internals`` - This block is composed of a list of implementation-dependent helper variables that supposed to be constant during the simulation run. Therefore, their initialization expression can only reference parameters or other internal variables. - ``equations`` - This block contains kernel definitions and differential equations. It will be explained in further detail `later on in the manual <#equations>`__. - ``input`` - This block is composed of one or more input ports. It will be explained in further detail `later on in the manual <#input>`__. - ``output`` *````* - Defines which type of event the neuron can send. Currently, only ``spike`` is supported. No ``end`` is necessary at the end of this block. -- ``update`` - Inside this block arbitrary code can be implemented using the internal programming language. The ``update`` block defines the runtime behavior of the neuron. It contains the logic for state - and equation `updates <#equations>`__ and `refractoriness <#concepts-for-refractoriness>`__. This block is translated into the ``update`` method in NEST. - - -Neuronal interactions ---------------------- +- ``update`` - Inside this block arbitrary code can be implemented using the internal programming language. Input -~~~~~ - -A neuron model written in NESTML can be configured to receive two distinct types of input: spikes and currents. For either of them, the modeler has to decide if inhibitory and excitatory inputs are lumped together into a single named buffer, or if they should be separated into differently named buffers based on their sign. The `input` block is composed of one or more lines to express the exact combinations desired. Each line has the following general form: - -:: - - port_name <- inhibitory? excitatory? (spike | current) +----- -This way, a flexible combination of the inputs is possible. If, for example, current input should be lumped together, but spike input should be separated for inhibitory and excitatory incoming spikes, the following `input` block would be appropriate: +A model written in NESTML can be configured to receive two distinct types of input: spikes and continuous-time values. -.. code-block:: nestml - - input: - I_stim pA <- current - inh_spikes pA <- inhibitory spike - exc_spikes pA <- excitatory spike - end +For more details, on handling inputs in neuron and synapse models, please see :doc:`neurons_in_nestml` and :doc:`synapses_in_nestml`. -Please note that it is equivalent if either both `inhibitory` and `excitatory` are given or none of them at all. If only a single one of them is given, another line has to be present and specify the inverse keyword. Failure to do so will result in a translation error. -Integrating current input -^^^^^^^^^^^^^^^^^^^^^^^^^ +Output +~~~~~~ -The current port symbol (here, `I_stim`) is available as a variable and can be used in expressions, e.g.: +Each model can only send a single type of event. The type of the event has to be given in the `output` block. Currently, however, only spike output is supported. .. code-block:: nestml - V_m' = -V_m/tau_m + ... + I_stim - - -Integrating spiking input -^^^^^^^^^^^^^^^^^^^^^^^^^ - -Spikes arriving at the input port of a neuron can be written as a spike train *s(t)*: - -.. math:: - - \large s(t) = \sum_{i=1}^N \delta(t - t_i) - -To model the effect that an arriving spike has on the state of the neuron, a convolution with a kernel can be used. The kernel defines the postsynaptic response kernel, for example, an alpha (bi-exponential) function, decaying exponential, or a delta function. (See :ref:`Kernel functions` for how to define a kernel.) The convolution of the kernel with the spike train is defined as follows: - -.. math:: - - \large (f \ast s)(t) = \sum_{i=1}^N w_i \cdot f(t - t_i) - -where :math:`w_i` is the weight of spike :math:`i`. + output: spike -For example, say there is a spiking input port defined named ``spikes``. A decaying exponential with time constant ``tau_syn`` is defined as postsynaptic kernel ``G``. Integration into the membrane potential ``V_m`` can be expressed using the ``convolve(f, g)`` function, which takes a kernel and input port as its arguments: +Please note that this block is **not** terminated with the ``end`` keyword. -.. code-block:: nestml - kernel G = exp(-t/tau_syn) - V_m' = -V_m/tau_m + convolve(G, spikes) +Handling of time +---------------- -The type of the convolution is equal to the type of the second parameter, that is, of the spike buffer. Kernels themselves are always untyped. +To retrieve some fundamental simulation parameters, two special functions are built into NESTML: +- ``resolution`` returns the current resolution of the simulation in ms. In NEST, this can be set by the user using the PyNEST function ``nest.SetKernelStatus({"resolution": ...})``. +- ``steps`` takes one parameter of type ``ms`` and returns the number of simulation steps in the current simulation resolution. -Multiple input synapses -^^^^^^^^^^^^^^^^^^^^^^^ +These functions can be used to implement custom buffer lookup logic but should be used with care. In particular, when a non-constant simulation timestep is used, ``steps()`` should be avoided. -If there is more than one line specifying a `spike` or `current` port with the same sign, a neuron with multiple receptor types is created. For example, say that we define three spiking input ports as follows: +When using ``resolution()``, it is recommended to use the function call directly in the code, rather than defining it as a parameter. This makes the model more robust in case of non-constant timestep. In some cases, as in the synapse ``update`` block, a step is made between spike events, a timestep which is not constrained by the simulation timestep. For example: .. code-block:: nestml - input: - spikes1 nS <- spike - spikes2 nS <- spike - spikes3 nS <- spike + parameters: + h ms = resolution() # !! NOT RECOMMENDED. end -For the sake of keeping the example simple, we assign a decaying exponential-kernel postsynaptic response to each input port, each with a different time constant: - -.. code-block:: nestml - - equations: - kernel I_kernel1 = exp(-t / tau_syn1) - kernel I_kernel2 = exp(-t / tau_syn2) - kernel I_kernel3 = -exp(-t / tau_syn3) - function I_syn pA = convolve(I_kernel1, spikes1) - convolve(I_kernel2, spikes2) + convolve(I_kernel3, spikes3) + ... - V_abs' = -V_abs/tau_m + I_syn / C_m + update: + # update from t to t + resolution() + x *= exp(-resolution() / tau) # let x' = -x / tau + # evolve the state of x one timestep end -After generating and building the model code, a ``receptor_type`` entry is available in the status dictionary, which maps port names to numeric port indices in NEST. The receptor type can then be selected in NEST during `connection setup `_: - -.. code-block:: python - neuron = nest.Create("iaf_psc_exp_multisynapse_neuron_nestml") - - sg = nest.Create("spike_generator", params={"spike_times": [20., 80.]}) - nest.Connect(sg, neuron, syn_spec={"receptor_type" : 1, "weight": 1000.}) - - sg2 = nest.Create("spike_generator", params={"spike_times": [40., 60.]}) - nest.Connect(sg2, neuron, syn_spec={"receptor_type" : 2, "weight": 1000.}) - - sg3 = nest.Create("spike_generator", params={"spike_times": [30., 70.]}) - nest.Connect(sg3, neuron, syn_spec={"receptor_type" : 3, "weight": 500.}) - -Note that in multisynapse neurons, receptor ports are numbered starting from 1. - -We furthermore wish to record the synaptic currents ``I_kernel1``, ``I_kernel2`` and ``I_kernel3``. During code generation, one buffer is created for each combination of (kernel, spike input port) that appears in convolution statements. These buffers are named by joining together the name of the kernel with the name of the spike buffer using (by default) the string "__X__". The variables to be recorded are thus named as follows: - -.. code-block:: python - - mm = nest.Create('multimeter', params={'record_from': ['I_kernel1__X__spikes1', - 'I_kernel2__X__spikes2', - 'I_kernel3__X__spikes3'], - 'interval': .1}) - nest.Connect(mm, neuron) - -The output shows the currents for each synapse (three bottom rows) and the net effect on the membrane potential (top row): +Equations +--------- -.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/nestml-multisynapse-example.png - :alt: NESTML multisynapse example waveform traces +Systems of ODEs +~~~~~~~~~~~~~~~ -For a full example, please see `tests/resources/iaf_psc_exp_multisynapse.nestml `_ for the full model and `tests/nest_tests/nest_multisynapse_test.py `_ for the corresponding test harness that produced the figure above. +In the ``equations`` block one can define a system of differential equations with an arbitrary amount of equations that contain derivatives of arbitrary order. When using a derivative of a variable, say ``V``, one must write: ``V'``. It is then assumed that ``V'`` is the first time derivate of ``V``. The second time derivative of ``V`` is ``V''``, and so on. If an equation contains a derivative of order :math:`n`, for example, :math:`V^{(n)}`, all initial values of :math:`V` up to order :math:`n-1` must be defined in the ``state`` block. For example, if stating +.. code-block:: nestml -Output -~~~~~~ + V' = a * V -Each neuron model can only send a single type of event. The type of the event has to be given in the ``output`` block. Currently, however, only spike output is supported. +in the ``equations`` block, .. code-block:: nestml - output: spike - -Please note that this block is **not** terminated with the ``end`` keyword. + V mV = 0 mV +has to be defined in the ``state`` block. Otherwise, an error message is generated. -Handling of time ----------------- +The content of spike and continuous time buffers can be used by just using their plain names. NESTML takes care behind the scenes that the buffer location at the current simulation time step is used. -To retrieve some fundamental simulation parameters, two special functions are built into NESTML: - -- ``resolution`` returns the current resolution of the simulation in ms. In NEST, this can be set by the user using the PyNEST function ``nest.SetKernelStatus({"resolution": ...})``. -- ``steps`` takes one parameter of type ``ms`` and returns the number of simulation steps in the current simulation resolution. +Delay Differential Equations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These functions can be used to implement custom buffer lookup logic but should be used with care. +The differential equations in the ``equations`` block can also be a delay differential equation, where the derivative +at the current time depends on the derivative of a function at previous times. A state variable, say ``foo`` that is +dependent on another state variable ``bar`` at a constant time offset (here, ``delay``) in the past, can be written as +.. code-block:: nestml -Equations ---------- + state: + bar real = -70. + foo real = 0 + end -Systems of ODEs -~~~~~~~~~~~~~~~ + equations: + bar' = -bar / tau + foo' = bar(t - delay) / tau + end -In the ``equations`` block one can define a system of differential equations with an arbitrary amount of equations that contain derivatives of arbitrary order. When using a derivative of a variable, say ``V``, one must write: ``V'``. It is then assumed that ``V'`` is the first time derivate of ``V``. The second time derivative of ``V`` is ``V''``, and so on. If an equation contains a derivative of order :math:`n`, for example, :math:`V^{(n)}`, all initial values of :math:`V` up to order :math:`n-1` must be defined in the ``state`` block. For example, if stating +Note that the ``delay`` can be a numeric constant or a constant defined in the ``parameters`` block. In the above example, the ``delay`` variable is defined in the ``parameters`` block as: .. code-block:: nestml - V' = a * V + parameters: + tau ms = 3.5 ms + delay ms = 5.0 ms + end -in the ``equations`` block, +For a full example, please refer to the tests at `tests/nest_tests/nest_delay_based_variables_test.py `_. -.. code-block:: nestml +.. note:: - V mV = 0 mV - -has to be stated in the ``initial_values`` block. Otherwise, an error message is generated. + - The value of the delayed variable (``bar`` in the above example) returned by the node's ``get()`` function in + PyNEST is always the non-delayed version, i.e., the value of the derivative of ``bar`` at time ``t``. Similarly, the + ``set()`` function sets the value of the actual state variable ``bar`` without the ``delay`` into consideration. + - The ``delay`` variable can be set from PyNEST using the ``set()`` function before running the simulation. Setting the value after the simulation can give rise to unpredictable results and is not currently supported. -The content of spike and current buffers can be used by just using their plain names. NESTML takes care behind the scenes that the buffer location at the current simulation time step is used. +.. note:: + - Delay differential equations where the derivative of a variable is dependent on the derivative of the same + variable at previous times, for example, `The Mackey-Glass equation `_, are not supported currently. + - Delay differential equations with multiple delay values for the same variable are also not supported. Inline expressions ^^^^^^^^^^^^^^^^^^ @@ -873,11 +927,11 @@ Equivalently, the same exponentially decaying kernel can be formulated as a diff kernel g' = -g / tau -In this case, initial values have to be specified up to the order of the differential equation, e.g.: +In this case, initial values have to be specified in the ``state`` block up to the order of the differential equation, e.g.: .. code-block:: nestml - initial_values: + state: g real = 1 end @@ -902,7 +956,7 @@ An example second-order kernel is the dual exponential ("alpha") kernel, which c .. code-block:: nestml - initial_values: + state: g real = 0 g$ real = 1 end @@ -919,7 +973,7 @@ An example second-order kernel is the dual exponential ("alpha") kernel, which c .. code-block:: nestml - initial_values: + state: g real = 0 g' ms**-1 = e / tau end @@ -978,7 +1032,7 @@ In order to model refractory and non-refractory states, two variables are necess Setting and retrieving model properties --------------------------------------- -- All variables in the ``state``, ``parameters`` and ``initial_values`` blocks are added to the status dictionary of the neuron. +- All variables in the ``state`` and ``parameters`` blocks are added to the status dictionary of the neuron. - Values can be set using ``nest.SetStatus(, , )`` where ```` is the name of the corresponding NESTML variable. - Values can be read using ``nest.GetStatus(, )``. This call will return the value of the corresponding NESTML variable. @@ -987,19 +1041,20 @@ Recording values with devices ----------------------------- - All values in the ``state`` block are recordable by a ``multimeter`` in NEST. -- The ``recordable`` keyword can be used to also make variables in other blocks (``parameters, internals``) available to recording devices. +- The ``recordable`` keyword can be used to also make ``inline`` expressions in the ``equations`` block available to recording devices. .. code-block:: nestml - parameters: - recordable t_ref ms = 5 ms + equations: + ... + recordable inline V_m mV = V_abs + V_reset end Guards ------ -Variables which are defined in the ``state`` and ``parameters`` blocks can optionally be secured through guards. These guards are checked during the call to ``nest.SetStatus()`` in NEST. +Variables which are defined in the ``state`` and ``parameters`` blocks can optionally be secured through guards. These guards are checked during the call to ``nest.SetStatus()`` in NEST. :: diff --git a/doc/nestml_language/neurons_in_nestml.rst b/doc/nestml_language/neurons_in_nestml.rst new file mode 100644 index 000000000..3b1ef2a90 --- /dev/null +++ b/doc/nestml_language/neurons_in_nestml.rst @@ -0,0 +1,238 @@ +Modeling neurons in NESTML +========================== + +Writing the NESTML model +######################## + +The top-level element of the model is ``neuron``, followed by a name. All other blocks appear inside of here. + +.. code-block:: nestml + + neuron hodkin_huxley: + # [...] + end + + +Neuronal interactions +--------------------- + +Input +~~~~~ + +A neuron model written in NESTML can be configured to receive two distinct types of input: spikes and continuous-time values. This can be indicated using the following syntax: + +.. code-block:: nestml + + input: + I_stim pA <- continuous + AMPA_spikes pA <- spike + end + +The general syntax is: + +:: + + port_name dataType <- inputQualifier* (spike | continuous) + +For spiking input ports, the qualifier keywords decide whether inhibitory and excitatory inputs are lumped together into a single named input port, or if they are separated into differently named input ports based on their sign. When processing a spike event, some simulators (including NEST) use the sign of the amplitude (or weight) property in the spike event to indicate whether it should be considered an excitatory or inhibitory spike. By using the qualifier keywords, a single spike handler can route each incoming spike event to the correct input buffer (excitatory or inhibitory). Compare: + +.. code-block:: nestml + + input: + # [...] + all_spikes pA <- spike + end + +In this case, all spike events will be processed through the ``all_spikes`` input port. A spike weight could be positive or negative, and the occurrences of ``all_spikes`` in the model should be considered a signed quantity. + +.. code-block:: nestml + + input: + # [...] + AMPA_spikes pA <- excitatory spike + GABA_spikes pA <- inhibitory spike + end + +In this case, spike events that have a negative weight are routed to the ``GABA_spikes`` input port, and those that have a positive weight to the ``AMPA_spikes`` port. + +It is equivalent if either both `inhibitory` and `excitatory` are given, or neither: an unmarked port will by default handle all incoming presynaptic spikes. + +.. list-table:: + :header-rows: 1 + :widths: 10 60 + + * - Keyword + - The incoming weight :math:`w`... + * - none, or ``excitatory`` and ``inhibitory`` + - ... may be positive or negative. It is added to the buffer with signed value :math:`w` (positive or negative). + * - ``excitatory`` + - ... should not be negative. It is added to the buffer with non-negative magnitude :math:`w`. + * - ``inhibitory`` + - ... should be negative. It is added to the buffer with non-negative magnitude :math:`-w`. + + +Integrating current input +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The current port symbol (here, `I_stim`) is available as a variable and can be used in expressions, e.g.: + +.. code-block:: nestml + + equations + V_m' = -V_m/tau_m + ... + I_stim + end + + input: + I_stim pA <- continuous + end + + + +Integrating spiking input +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Spikes arriving at the input port of a neuron can be written as a spike train :math:`s(t)`: + +.. math:: + + \large s(t) = \sum_{i=1}^N \delta(t - t_i) + +To model the effect that an arriving spike has on the state of the neuron, a convolution with a kernel can be used. The kernel defines the postsynaptic response kernel, for example, an alpha (bi-exponential) function, decaying exponential, or a delta function. (See :ref:`Kernel functions` for how to define a kernel.) The convolution of the kernel with the spike train is defined as follows: + +.. math:: + + \large (f \ast s)(t) = \sum_{i=1}^N w_i \cdot f(t - t_i) + +where :math:`w_i` is the weight of spike :math:`i`. + +For example, say there is a spiking input port defined named ``spikes``. A decaying exponential with time constant ``tau_syn`` is defined as postsynaptic kernel ``G``. Their convolution is expressed using the ``convolve(f, g)`` function, which takes a kernel and input port, respectively, as its arguments: + +.. code-block:: nestml + + equations: + kernel G = exp(-t/tau_syn) + V_m' = -V_m/tau_m + convolve(G, spikes) + end + +The type of the convolution is equal to the type of the second parameter, that is, of the spike buffer. Kernels themselves are always untyped. + + +(Re)setting synaptic integration state +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When convolutions are used, additional state variables are required for each pair *(shape, spike input port)* that appears as the parameters in a convolution. These variables track the dynamical state of that kernel, for that input port. The number of variables created corresponds to the dimensionality of the kernel. For example, in the code block above, the one-dimensional kernel ``G`` is used in a convolution with spiking input port ``spikes``. During code generation, a new state variable called ``G__conv__spikes`` is created for this combination, by joining together the name of the kernel with the name of the spike buffer using (by default) the string “__conv__”. If the same kernel is used later in a convolution with another spiking input port, say ``spikes_GABA``, then the resulting generated variable would be called ``G__conv__spikes_GABA``, allowing independent synaptic integration between input ports but allowing the same kernel to be used more than once. + +The process of generating extra state variables for keeping track of convolution state is normally hidden from the user. For some models, however, it might be required to set or reset the state of synaptic integration, which is stored in these internally generated variables. For example, we might want to set the synaptic current (and its rate of change) to 0 when firing a dendritic action potential. Although we would like to set the generated variable ``G__conv__spikes`` to 0 in the running example, a variable by this name is only generated during code generation, and does not exist in the namespace of the NESTML model to begin with. To still allow referring to this state in the context of the model, it is recommended to use an inline expression, with only a convolution on the right-hand side. + +For example, suppose we define: + +.. code-block:: nestml + + inline g_dend pA = convolve(G, spikes) + +Then the name ``g_dend`` can be used as a target for assignment: + +.. code-block:: nestml + + update: + g_dend = 42 pA + end + +This also works for higher-order kernels, e.g. for the second-order alpha kernel :math:`H(t)`: + +.. code-block:: nestml + + kernel H'' = (-2/tau_syn) * H' - 1/tau_syn**2) * H + +We can define an inline expression with the same port as before, ``spikes``: + +.. code-block:: nestml + + inline h_dend pA = convolve(H, spikes) + +The name ``h_dend`` now acts as an alias for this particular convolution. We can now assign to the inline defined variable up to the order of the kernel: + +.. code-block:: nestml + + update: + h_dend = 42 pA + h_dend' = 10 pA/ms + end + +For more information, see the :doc:`Active dendrite tutorial ` + + + +Multiple input synapses +^^^^^^^^^^^^^^^^^^^^^^^ + +If there is more than one line specifying a `spike` or `continuous` port with the same sign, a neuron with multiple receptor types is created. For example, say that we define three spiking input ports as follows: + +.. code-block:: nestml + + input: + spikes1 nS <- spike + spikes2 nS <- spike + spikes3 nS <- spike + end + +For the sake of keeping the example simple, we assign a decaying exponential-kernel postsynaptic response to each input port, each with a different time constant: + +.. code-block:: nestml + + equations: + kernel I_kernel1 = exp(-t / tau_syn1) + kernel I_kernel2 = exp(-t / tau_syn2) + kernel I_kernel3 = -exp(-t / tau_syn3) + function I_syn pA = convolve(I_kernel1, spikes1) - convolve(I_kernel2, spikes2) + convolve(I_kernel3, spikes3) + ... + V_abs' = -V_abs/tau_m + I_syn / C_m + end + +After generating and building the model code, a ``receptor_type`` entry is available in the status dictionary, which maps port names to numeric port indices in NEST. The receptor type can then be selected in NEST during `connection setup `_: + +.. code-block:: python + + neuron = nest.Create("iaf_psc_exp_multisynapse_neuron_nestml") + + sg = nest.Create("spike_generator", params={"spike_times": [20., 80.]}) + nest.Connect(sg, neuron, syn_spec={"receptor_type" : 1, "weight": 1000.}) + + sg2 = nest.Create("spike_generator", params={"spike_times": [40., 60.]}) + nest.Connect(sg2, neuron, syn_spec={"receptor_type" : 2, "weight": 1000.}) + + sg3 = nest.Create("spike_generator", params={"spike_times": [30., 70.]}) + nest.Connect(sg3, neuron, syn_spec={"receptor_type" : 3, "weight": 500.}) + +Note that in multisynapse neurons, receptor ports are numbered starting from 1. + +We furthermore wish to record the synaptic currents ``I_kernel1``, ``I_kernel2`` and ``I_kernel3``. During code generation, one buffer is created for each combination of (kernel, spike input port) that appears in convolution statements. These buffers are named by joining together the name of the kernel with the name of the spike buffer using (by default) the string "__X__". The variables to be recorded are thus named as follows: + +.. code-block:: python + + mm = nest.Create('multimeter', params={'record_from': ['I_kernel1__X__spikes1', + 'I_kernel2__X__spikes2', + 'I_kernel3__X__spikes3'], + 'interval': .1}) + nest.Connect(mm, neuron) + +The output shows the currents for each synapse (three bottom rows) and the net effect on the membrane potential (top row): + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/nestml-multisynapse-example.png + :alt: NESTML multisynapse example waveform traces + +For a full example, please see `tests/resources/iaf_psc_exp_multisynapse.nestml `_ for the full model and `tests/nest_tests/nest_multisynapse_test.py `_ for the corresponding test harness that produced the figure above. + +Output +~~~~~~ + +``emit_spike``: calling this function in the ``update`` block results in firing a spike to all target neurons and devices time stamped with the current simulation time. + + + +Generating code +############### + +Co-generation of neuron and synapse +----------------------------------- + +The ``update`` block in a NESTML model is translated into the ``update`` method in NEST. diff --git a/doc/nestml_language/synapses_in_nestml.rst b/doc/nestml_language/synapses_in_nestml.rst new file mode 100644 index 000000000..49edd20ec --- /dev/null +++ b/doc/nestml_language/synapses_in_nestml.rst @@ -0,0 +1,617 @@ +Modeling synapses in NESTML +=========================== + +.. toctree:: + +Conceptually, a synapse model formalises the interaction between two (or more) neurons. In biophysical terms, they may contain some elements that are part of the postsynaptic neuron (such as the postsynaptic density) as well as the presynaptic neuron (such as the vesicle pool), or external factors such as the concentration of an extracellular diffusing factor. We will discuss in detail the spike-timing dependent plasticity (STDP) model and some of its variants. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/synapse_conceptual.png + :scale: 10 % + :align: center + + Conceptual illustration of which parts of biophysics are captured by a synapse model. Presynaptic neuron on the left, postsynaptic neuron on the right. Three synapses are shown and highlighted with yellow boxes. *Copyright Sebastian B.C. Lehmann , INM-6, Forschungszentrum Jülich GmbH (CC-BY-SA)* + +From the modeling point of view, a synapse shares many of the same behaviours of a neuron: it has parameters and internal state variables, can communicate over input and output ports, and its dynamics and responses can be described by differential equations, kernels and as an algorithm. Typically, there is a single spiking input port and a single spiking output port. + +.. Attention:: The NEST Simulator platform target has some additional constraints, such as precluding updates on a regular time grid. See :ref:`The NEST target` for more details. + +Key to writing the synapse model is the requirement that the event handler for the spiking input port is responsible for submitting the event to the (spiking) output port. + +Note that the synaptic strength ("weight") variable is of type real; if the type were given in more specific units, such as nS or pA, the synapse model would only be compatible with either a conductance or current-based postsynaptic neuron model. + + +Writing the NESTML model +######################## + +The top-level element of the model is ``synapse``, followed by a name. All other blocks appear inside of here. + +.. code-block:: nestml + + synapse stdp: + # [...] + end + +Input and output ports +---------------------- + +Depending on whether the plasticity rule depends only on pre-, or on both pre- and postsynaptic activity, one or two input ports are defined. Synapses always have only one (spiking) output port. + +.. code-block:: nestml + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + +Presynaptic spike event handler +------------------------------- + +It is the responsibility of the event handler for the spiking input port to submit the event to the (spiking) output port. This can be done using the predefined ``deliver_spike(w, d)`` function, which takes two parameters: a weight ``w`` and delay ``d``. + +The corresponding event handler has the general structure: + +.. code-block:: nestml + + onReceive(pre_spikes): + print("Info: processing a presynaptic spike at time t = {t}") + # ... plasticity dynamics go here ... + deliver_spike(w, d) + end + +The statements in the event handler will be executed sequentially when the event occurs. The weight and delay could be defined as follows: + +.. code-block:: nestml + + state: + w real = 1 + end + + parameters: + d ms = 1 ms + end + +If synaptic plasticity modifies the weight of the synapse, the weight update could (but does not have to) take place before calling ``deliver_spike()`` with the updated weight. + +State variables (in particular, synaptic "trace" variables as often used in plasticity models) can be updated in the event handler as follows: + +.. code-block:: nestml + + state: + tr_pre real = 0 + end + + onReceive(post_spikes): + print("Info: processing a presynaptic spike at time t = {t}") + tr_pre += 1 + end + + equations: + tr_pre' = -tr_pre / tau_tr + end + +Equivalently, the trace can be defined as a convolution between a trace kernel and the spiking input port: + +.. code-block:: nestml + + equations: + kernel tr_pre_kernel = exp(-t / tau_tr) + inline tr_pre real = convolve(tr_pre_kernel, pre_spikes) + end + + +Postsynaptic spike event handler +-------------------------------- + +Some plasticity rules are defined in terms of postsynaptic spike activity. A corresponding additional spiking input port and event handler (and convolutions) can be defined in the NESTML model: + +.. code-block:: nestml + + input: + pre_spikes nS <- spike # (same as before) + post_spikes nS <- spike + end + + onReceive(post_spikes): + print("Info: processing a postsynaptic spike at time t = {t}") + # ... plasticity dynamics go here ... + end + + +Sharing parameters between synapses +----------------------------------- + +If one or more synapse parameters are the same across a population (homogeneous), then sharing the parameter value between all synapses can save vast amounts of memory. To mark a particular parameter as homogeneous, use the `@homogeneous` decorator keyword. This can be done on a per-parameter basis. + +By default, parameters are heterogeneous which means can be set on a per-synapse basis by the user. + +For example: + +.. code-block:: nestml + + parameters: + a real = 3.14159 @homogeneous + b real = 100. @heterogeneous # the default! + end + + +Third-factor plasticity +####################### + +The postsynaptic trace value in the models so far is assumed to correspond to a property of the postsynaptic neuron, but it is specified in the synapse model. Some synaptic plasticity rules require access to a postsynaptic value that cannot be specified as part of the synapse model, but is a part of the (postsynaptic) neuron model. + +An example would be a neuron that generates dendritic action potentials. The synapse could need access to the postsynaptic dendritic current. For more details on this example, please see the tutorial https://nestml.readthedocs.io/en/latest/tutorials/active_dendrite/nestml_active_dendrite_tutorial.html + +An additional complication is that when combining models from different sources, the naming convention can be different between the neuron and synapse model. + +To make the "third factor" value available in the synapse model, begin by defining an appropriate input port: + +.. code-block:: nestml + + input: + I_post_dend pA <- continuous + end + +In the synapse, the value will be referred to as ``I_post_dend`` and can be used in equations and expressions. In this example, we will use it as a simple gating variable between 0 and 1, that can disable or enable weight updates in a graded manner: + +.. code-block:: nestml + + onReceive(post_spikes): + # potentiate synapse + w_ real = # [...] normal STDP update rule + w_ = (I_post_dend / pA) * w_ + (1 - I_post_dend / pA) * w # "gating" of the weight update + w = min(Wmax, w_) + end + +In the neuron, no special output port is required; all state variables are accessible for the third factor rules. + +NESTML needs to be invoked so that it generates code for neuron and synapse together. Additionally, specify the ``"post_ports"`` entry to connect the input port on the synapse with the right variable of the neuron (see :ref:`Generating code`). + +In this example, the ``I_dend`` state variable of the neuron will be simply an exponentially decaying function of time, which can be set to 1 at predefined times in the simulation script. By inspecting the magnitude of the weight updates, we see that the synaptic plasticity is indeed being gated by the neuronal state variable ("third factor") ``I_dend``. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp_triplet_synapse_test.png + +For a full example, please see the following files: + +* ``tests/nest_tests/third_factor_stdp_synapse_test.py`` (produces the figure) +* ``models/neurons/iaf_psc_exp_dend.nestml`` (neuron model) +* ``models/synapses/third_factor_stdp_synapse.nestml`` (synapse model) + + +Examples +######## + +Spike-Timing Dependent Plasticity (STDP) +---------------------------------------- + +Experiments have shown that synaptic strength changes as a function of the precise spike timing of the presynaptic and postsynaptic neurons. If the pre neuron fires an action potential strictly before the post neuron, the synapse connecting them will be strengthened ("facilitated"). If the pre neuron fires after the post neuron, the synapse will be weakened ("depressed"). The depression and facilitation effects become stronger when the spikes occur closer together in time. This is illustrated by empirical results (open circles), fitted by exponential curves (solid lines). + +.. figure:: https://raw.githubusercontent.com/nest/nestml/b96d9144664ef8ddb75dce51c8e5b38b7878dde5/doc/fig/Asymmetric-STDP-learning-window-Spike-timing-window-of-STDP-for-the-induction-of.png + + Asymmetric STDP learning window. Spike-timing window of STDP for the induction of synaptic potentiation and depression characterized in hippocampal cultures. Data points from Bi and Poo (1998), represent the relative change in the amplitude of EPSC after repetitive correlated activity of pre-post spike pairs. The potentiation window (right of the vertical axis) and depression window (left of the vertical axis) are fitted by an exponential function $A^\pm\exp(−|\Delta t|/\tau^\pm)$, with parameters $A^+ = 0.86$, $A^- = -0.25$, $\tau^+ = 19 \text{ms}$, and $\tau^- = 34 \text{ms}$. Adopted from Bi and Wang (2002). + +We will define the theoretical model following [3]_. + +A pair of spikes in the input and the output cell, at times :math:`t_i` and :math:`t_j` respectively, induces a change :math:`\Delta w` in the weight :math:`w`: + +.. math:: + + \Delta^\pm w = \pm \lambda \cdot f_\pm(w) \cdot K(|t_o - t_i|) + +The weight is increased by :math:`\Delta^+ w` when :math:`t_o>t_i` and decreased by :math:`\Delta^- w` when :math:`t_i>t_o`. The temporal dependence of the update is defined by the filter kernel :math:`K` which is taken to be :math:`K(t) = \exp(-t/\tau)`. The coefficient :math:`\lambda\in\mathbb{R}` sets the magnitude of the update. The functions :math:`f_\pm(w)` determine the relative magnitude of the changes in the positive and negative direction. These are here taken as + +.. math:: + + \begin{align} + f_+(w) &= (1 - w)^{\mu_+}\\ + f_-(w) &= \alpha w^{\mu_-} + \end{align} + +with the parameter :math:`\alpha\in\mathbb{R}, \alpha>0` allowing to set an asymmetry between increasing and decreasing the synaptic efficacy, and :math:`\mu_\pm\in\{0,1\}` allowing to choose between four different kinds of STDP (for references, see https://nest-simulator.readthedocs.io/en/nest-2.20.1/models/stdp.html?highlight=stdp#_CPPv4I0EN4nest14STDPConnectionE). + +To implement the kernel, we use two extra state variables, one presynaptic so-called *trace value* and another postsynaptic trace value. These could correspond to calcium concentration in biology, maintaing a history of recent neuron spiking activity. They are incremented by 1 whenever a spike is generated, and decay back to zero exponentially. Mathematically, this can be formulated as a convolution between the exponentially decaying kernel and the emitted spike train: + +.. math:: + + \text{tr_pre} = K \ast \sum_i \delta_{pre,i} + +and + +.. math:: + + \text{tr_post} = K \ast \sum_i \delta_{post,i} + +These are implemented in the NESTML model as follows: + +.. code-block:: nestml + + equations: + # all-to-all trace of presynaptic neuron + kernel tr_pre_kernel = exp(-t / tau_tr_pre) + inline tr_pre real = convolve(tr_pre_kernel, pre_spikes) + + # all-to-all trace of postsynaptic neuron + kernel tr_post_kernel = exp(-t / tau_tr_post) + inline tr_post real = convolve(tr_post_kernel, post_spikes) + end + +with time constants defined as parameters: + +.. code-block:: nestml + + parameters: + tau_tr_pre ms = 20 ms + tau_tr_post ms = 20 ms + end + +With the traces in place, the weight updates can then be expressed closely following the mathematical definitions. Begin by defining the weight state variable and its initial value: + +.. code-block:: nestml + + state: + w real = 1. + end + +Our update rule for facilitation is: + +.. math:: + + \Delta^+ w = \lambda \cdot (1 - w)^{\mu_+} \cdot \text{tr_pre} + +In NESTML, this expression can be entered almost verbatim. Note that the only difference is that scaling with an absolute maximum weight ``Wmax`` was added: + +.. code-block:: nestml + + onReceive(post_spikes): + # potentiate synapse + w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * tr_pre )) + w = min(Wmax, w_) + end + +Our update rule for depression is: + +.. math:: + + \Delta^- w = -\alpha \cdot \lambda \cdot w^{\mu_-} \cdot \text{tr_post} + +.. code-block:: nestml + + onReceive(pre_spikes): + # depress synapse + w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * tr_post )) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, d) + end + +Finally, all remaining parameters are defined: + +.. code-block:: nestml + + parameters: + lambda real = .01 + alpha real = 1. + mu_plus real = 1. + mu_minus real = 1. + Wmax real = 100. + Wmin real = 0. + end + +The NESTML STDP synapse integration test (``tests/nest_tests/stdp_window_test.py``) runs the model for a variety of pre/post spike timings, and measures the weight change numerically. We can use this to verify that our model approximates the correct STDP window. Note that the dendritic delay in this example has been set to 10 ms, to make its effect on the STDP window more clear: it is not centered around zero, but shifted to the left by the dendritic delay. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/c4c47d053077b11ad385d5f882696248a55b31af/doc/fig/stdp_test_window.png + + STDP window, obtained from numerical simulation, for purely additive STDP (mu_minus = mu_plus = 0) and a dendritic delay of 10 ms. + + +STDP synapse with nearest-neighbour spike pairing +------------------------------------------------- + +This synapse model extends the STDP model by restrictions on interactions between pre- and post spikes. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/1c692f7ce70a548103b4cc1572a05a2aed3b27a4/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner [1]_. Original caption: "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006)" + + +Nearest-neighbour symmetric +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This variant corresponds to panel 7A in [1]_: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike. + +To implement this rule, the pre- and postsynaptic traces are reset to 1 instead of incremented by 1. To implement this in the model, we define the traces are state variables and ODEs, instead of convolutions: + +.. code-block:: nestml + + state: + tr_pre real = 0. + tr_post real = 0. + end + + equations: + tr_pre' = -tr_pre / tau_tr_pre + tr_post' = -tr_post / tau_tr_post + end + +Resetting to 1 can then be done by assignment in the pre- and post-event handler blocks: + +.. code-block:: nestml + + onReceive(pre_spikes): + tr_pre = 1 + [...] + end + + onReceive(post_spikes): + tr_post = 1 + [...] + end + +The rest of the model is equivalent to the normal (all-to-all spike pairing) STDP. + +The full model can be downloaded here: `stdp_nn_symm.nestml `_. + + +Presynaptic centered +~~~~~~~~~~~~~~~~~~~~ + +This variant corresponds to panel 7B in [1]_: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike. + +To implement this rule, the postsynaptic trace is reset to 1 upon a spike, whereas the presynaptic trace is incremented by 1. Additionally, when a postsynaptic spike occurs, the presynaptic trace is reset to zero, thus "forgetting" presynaptic spike history. + +.. code-block:: nestml + + onReceive(post_spikes): + tr_post = 1 + w = ... # facilitation step (omitted) + tr_pre = 0 + end + + onReceive(pre_spikes): + tr_pre += 1 + w = ... # depression step (omitted) + deliver_spike(w, d) + end + +The remainder of the model is the same as the all-to-all STDP synapse. + +The full model can be downloaded here: `stdp_nn_pre_centered.nestml `_. + + +Restricted symmetric +~~~~~~~~~~~~~~~~~~~~ + +This variant corresponds to panel 7C in [1]_: like the :ref:`Nearest-neighbour symmetric` rule, but only for immediate pairings. + +To implement this rule, depression and facilitation are gated through a boolean, ``pre_handled``, which ensures that each postsynaptic spike can only pair with a single presynaptic spike. + +.. code-block:: nestml + + initial_values: + # [...] + pre_handled boolean = True + end + + onReceive(pre_spikes): + # [...] + + # depress synapse + if pre_handled: + w = ... # depression step (omitted) + end + + # [...] + end + + onReceive(post_spikes): + # [...] + + if not pre_handled: + w = ... # potentiation step (omitted) + pre_handled = True + end + + # [...] + end + +The remainder of the model is the same as the :ref:`Presynaptic centered` variant. + +The full model can be downloaded here: `stdp_nn_restr_symm.nestml `_. + + +Triplet-rule STDP synapse +------------------------- + +Traditional STDP models express the weight change as a function of pairs of pre- and postsynaptic spikes, but these fall short in accounting for the frequency dependence of weight changes. To improve the fit between model and empirical data, [4]_ propose a "triplet" rule, which considers sets of three spikes, that is, two pre and one post, or one pre and two post. + +.. figure:: https://www.jneurosci.org/content/jneuro/26/38/9673/F1.large.jpg?width=800&height=600&carousel=1 + + Figure 1 from [4]_. + +Two traces, with different time constants, are defined for both pre- and postsynaptic partners. The temporal evolution of the traces is illustrated in panels B and C: for the all-to-all variant of the rule, each trace is incremented by 1 upon a spike (panel B), whereas for the nearest-neighbour variant, each trace is reset to 1 upon a spike (panel C). The weight updates are then computed as a function of the trace values and four coefficients: a depression pair term :math:`A_2^-` and triplet term :math:`A_3^-`, and a facilitation pair term :math:`A_2^+` and triplet term :math:`A_3^+`. A presynaptic spike after a postsynaptic one induces depression, if the temporal difference is not much larger than :math:`\tau_-` (pair term, :math:`A_2^−`). The presence of a previous presynaptic spike gives an additional contribution (2-pre-1-post triplet term, :math:`A_3^−`) if the interval between the two presynaptic spikes is not much larger than :math:`\tau_x`. Similarly, the triplet term for potentiation depends on one presynaptic spike but two postsynaptic spikes. The presynaptic spike must occur before the second postsynaptic one with a temporal difference not much larger than :math:`\tau_+`. + +.. code-block:: nestml + + parameters: + tau_plus ms = 16.8 ms # time constant for tr_r1 + tau_x ms = 101 ms # time constant for tr_r2 + tau_minus ms = 33.7 ms # time constant for tr_o1 + tau_y ms = 125 ms # time constant for tr_o2 + end + + equations: + kernel tr_r1_kernel = exp(-t / tau_plus) + inline tr_r1 real = convolve(tr_r1_kernel, pre_spikes) + + kernel tr_r2_kernel = exp(-t / tau_x) + inline tr_r2 real = convolve(tr_r2_kernel, pre_spikes) + + kernel tr_o1_kernel = exp(-t / tau_minus) + inline tr_o1 real = convolve(tr_o1_kernel, post_spikes) + + kernel tr_o2_kernel = exp(-t / tau_y) + inline tr_o2 real = convolve(tr_o2_kernel, post_spikes) + end + +The weight update rules can then be expressed in terms of the traces and parameters, directly following the formulation in the paper (eqs. 3 and 4, [4]_): + +.. code-block:: nestml + + parameters: + A2_plus real = 7.5e-10 + A3_plus real = 9.3e-3 + A2_minus real = 7e-3 + A3_minus real = 2.3e-4 + + Wmax real = 100. + Wmin real = 0. + end + + onReceive(post_spikes): + # potentiate synapse + w_ real = w + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) + w = min(Wmax, w_) + end + + onReceive(pre_spikes): + # depress synapse + w_ real = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, d) + end + + +Generating code +############### + +Co-generation of neuron and synapse +----------------------------------- + +Most plasticity models, including all of the STDP variants discussed above, depend on the storage and maintenance of "trace" values, that record the history of pre- and postsynaptic spiking activity. The trace dynamics and parameters are part of the synaptic plasticity rule that is being modeled, so logically belong in the NESTML synapse model. However, if each synapse maintains pre- and post traces for its connected partners, and considering that a single neuron may have on the order of thousands of synapses connected to it, these traces would be stored and computed redundantly. Instead of keeping them as part of the synaptic state during simulation, they more logically belong to the neuronal state. + +To prevent this redundancy, a fully automated dependency analysis is run during code generation, that identifies those variables that depend exclusively on postsynaptic spikes, and moves them into the postsynaptic neuron model. For this to work, the postsynaptic neuron model used needs to be known at the time of synaptic code generation. Thus, we need to generate code "in tandem" now for connected neuron and synapse models, hence the name "co-generation". + +.. figure:: https://raw.githubusercontent.com/nest/nestml/d4bf4f521d726dd638e8a264c7253a5746bcaaae/doc/fig/neuron_synapse_co_generation.png + + (a) Without co-generation: neuron and synapse models are treated independently. (b) co-generation: the code generator knows which neuron types will be connected using which synapse types, and treats these as pairs rather than independently. + +To indicate which neurons will be connected to by which synapses during simulation, a list of such (neuron, synapse) pairs is passed to the code generator. This list is encoded as a JSON file. For example, if we want to use the "stdp" synapse model, connected to an "iaf_psc_exp" neuron, we would write the following: + +.. code-block:: json + + { + "neuron_synapse_pairs": [["iaf_psc_exp", "stdp"]] + } + +This file can then be passed to NESTML when generating code on the command line. If the JSON file is named ``nest_code_generator_opts_triplet.json``: + +.. code:: sh + + nestml --input_path my_models/ --codegen_opts=nest_code_generator_opts_triplet.json + +Further integration with NEST Simulator is planned, to achieve a just-in-time compilation/build workflow. This would automatically generate a list of these pairs and automatically generate the requisite JSON file. + + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/code_gen_opts.png + :scale: 50 % + :align: center + + Code generator options instruct the target platform code generator (in this case, NEST) how to process the models. + + + +The NEST target +--------------- + +Event-based updating +~~~~~~~~~~~~~~~~~~~~ + +NEST target synapses are not allowed to have any time-based internal dynamics (ODEs). This is due to the fact that synapses are, unlike nodes, not updated on a regular time grid. + +The synapse is allowed to contain an ``update`` block. Statements in the ``update`` block are executed whenever the internal state of the synapse is updated from one timepoint to the next; these updates are typically triggered by incoming spikes. The NESTML ``resolution()`` function will return the time that has elapsed since the last event was handled. + + +Dendritic delay +~~~~~~~~~~~~~~~ + +In NEST, all synapses are expected to specify a nonzero dendritic delay, that is, the delay between arrival of a spike at the dendritic spine and the time at which its effects are felt at the soma (or conversely, the delay between a somatic action potential and the arrival at the dendritic spine due to dendritic backpropagation). To indicate that a given parameter is specifying this NEST-specific delay value, use an annotation: + +.. code:: nestml + + parameters: + dend_delay ms = 1 ms @nest::delay + end + + +Generating code +--------------- + +When NESTML is invoked to generate code for plastic synapses, the code generator needs to know which neuron model the synapses will be connected to, so that it can generate fast C++ code for the neuron and the synapse that is mutually dependent at runtime. These pairs can be specified as a list of two-element dictionaries of the form :python:`{"neuron": "neuron_model_name", "synapse": "synapse_model_name"}`, for example: + +.. code-block:: python + + generate_target(..., + codegen_opts={..., + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp_dend", + "synapse": "third_factor_stdp"}]}) + +Additionally, if the synapse requires it, specify the ``"post_ports"`` entry to connect the input port on the synapse with the right variable of the postsynaptic neuron: + +.. code-block:: python + + generate_target(..., + codegen_opts={..., + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp_dend", + "synapse": "third_factor_stdp", + "post_ports": ["post_spikes", + ["I_post_dend", "I_dend"]]}]}) + +This specifies that the neuron ``iaf_psc_exp_dend`` has to be generated paired with the synapse ``third_factor_stdp``, and that the input ports ``post_spikes`` and ``I_post_dend`` in the synapse are to be connected to the postsynaptic partner. For the ``I_post_dend`` input port, the corresponding variable in the (postsynaptic) neuron is called ``I_dend``. + +Simulation of volume-transmitted neuromodulation in NEST can be done using "volume transmitter" devices [5]_. These are event-based and should correspond to a "spike" type input port in NESTML. The code generator options keyword "vt_ports" can be used here. + +.. code-block:: python + + generate_target(..., + codegen_opts={..., + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp_dend", + "synapse": "third_factor_stdp", + "vt_ports": ["dopa_spikes"]}]}) + + + +Implementation notes +~~~~~~~~~~~~~~~~~~~~ + +Note that ``access_counter`` now has an extra multiplicative factor equal to the number of trace values that exist, so that spikes are removed from the history only after they have been read out for the sake of computing each trace. + +.. figure:: https://www.frontiersin.org/files/Articles/1382/fncom-04-00141-r1/image_m/fncom-04-00141-g003.jpg + + Potjans et al. 2010 + +Random numbers +~~~~~~~~~~~~~~ + +In case random numbers are needed inside the synapse, the random number generator belonging to the postsynaptic target is used. + + + +References +---------- + +.. [1] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 + +.. [2] Front. Comput. Neurosci., 23 November 2010 | https://doi.org/10.3389/fncom.2010.00141 Enabling functional neural circuit simulations with distributed computing of neuromodulated plasticity, Wiebke Potjans, Abigail Morrison and Markus Diesmann + +.. [3] Rubin, Lee and Sompolinsky. Equilibrium Properties of Temporally Asymmetric Hebbian Plasticity. Physical Review Letters, 8 Jan 2001, Vol 86, No 2 + +.. [4] Pfister JP, Gerstner W (2006). Triplets of spikes in a model of spike timing-dependent plasticity. The Journal of Neuroscience 26(38):9673-9682. DOI: https://doi.org/10.1523/JNEUROSCI.1425-06.2006 + +.. [5] Potjans W, Morrison A and Diesmann M (2010) Enabling functional neural circuit simulations with distributed computing of neuromodulated plasticity. Front. Comput. Neurosci. 4:141. doi: 10.3389/fncom.2010.00141 diff --git a/doc/pynestml_toolchain/back.rst b/doc/pynestml_toolchain/back.rst index 6f4521e6d..8f868492f 100644 --- a/doc/pynestml_toolchain/back.rst +++ b/doc/pynestml_toolchain/back.rst @@ -1,4 +1,4 @@ -Section 3: The Generating Backend +Section 3: The Generating Backend --------------------------------- The generation of executable code is one of the most important aspects of a DSL-processing framework and enables the validation of the modeled concepts. The transformation of a textual model to an executable representation by means of a DSL framework prevents a manual, error-prone mapping of models to target platforms. In the case of PyNESTML, the NEST simulator [1]_ was selected as the first major platform for code generation. NEST represents a powerful simulation environment for biological neural networks and is implemented in C++. In this section, we will demonstrate how the code-generating backend was implemented to generate NEST-specific C++ code. For this purpose, `Section 3.1 <#chap:main:backend:codegeneration>`__ will first introduce the orchestrating *NestCodeGenerator* class and subsequently demonstrate how models are adjusted to be more NEST affine. An overview of the components used to generate NEST-specific code subsequently concludes this section. :numref:`fig_overview_backend` illustrates the subsystems as introduced in the following and their relations. @@ -11,7 +11,7 @@ The generation of executable code is one of the most important aspects of a DSL- Overview of the code-generating backend: The model-processing frontend provides an input AST for the code generation. The NEST-specific backend first transforms the AST by means of the *model transformation subsystem*, before the *NEST code generator* is used to generate the respective C++ code. The instructions how the AST has to be adapted are computed by an external ODE-toolbox. -Section 3.1: AST Transformations and Code Generation +Section 3.1: AST Transformations and Code Generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _fig_overview_nest_code_generator: @@ -21,7 +21,7 @@ Section 3.1: AST Transformations and Code Generation Overview of the NEST code generator. -In order to demonstrate the code-generating backend, this section will first introduce the coordinating *NestCodeGenerator* class and show how the code generation is prepared by transforming the handed over AST to a more efficient form. Subsequently, we highlight a set of templates used for the generation of NEST-specific C++ code. Concluding, an introduction to the special case of expression handling as implemented in the *ExpressionPrettyPrinter* class is given. :numref:`fig_overview_nest_code_generator` illustrates all components of the code-generating backend. +In order to demonstrate the code-generating backend, this section will first introduce the coordinating *NestCodeGenerator* class and show how the code generation is prepared by transforming the handed over AST to a more efficient form. Subsequently, we highlight a set of templates used for the generation of NEST-specific C++ code. Concluding, an introduction to the special case of expression handling as implemented in the *ExpressionPrinter* class is given. :numref:`fig_overview_nest_code_generator` illustrates all components of the code-generating backend. The *NestCodeGenerator* class orchestrates all steps required to generate NEST-specific artifacts. The overall interface of this class consists of the *analyseAndGenerateNeuron* and *generateModuleCode* methods. By separating the code generation into two different operations, a clear single responsibility is achieved. While all steps necessary to generate the C++ implementation of a neuron model are executed in the *analyseAndGenerateNeuron* method, the task of generating a set of setup artifacts is delegated to the *generateModuleCode* method. The *analyseAndGenerateNeuron* function hereby implements the following steps: First, the assisting *solveOdesAndKernels* function is executed which indicates whether a transformation of the model to a more efficient structure is possible. If so, the AST is handed over to the further-on presented *EquationsBlockProcessor* class, and a restructured AST is computed. Back to the orchestrating *analyseAndGenerateNeuron* method, an update of the symbol table is invoked by means of the *ASTSymbolTableVisitor*, cf. :ref:`Section 1: The model-processing Frontend`. This step is required in order to update the model's symbols according to the restructured AST where new declarations have been added. Finally, the generation of C++ code is started by means of the *generateModelCode* method. Being responsible for the generation of a header as well as an implementation file of a concrete neuron model, this operation delegates the work to the *generateModelHeader* and *generateModelImplementation* subroutines. :numref:`fig_processing_model_nest_backend` summarizes the above-introduced workflow. @@ -53,7 +53,7 @@ In order to compute these optimizations, the ODE-toolbox as introduced by Blunde From NESTML to JSON: In order to interact with the ODE-toolbox, all declarations contained in the *equations* block are converted to JSON format. -The task of creating a JSON representation of a given *equations* block is handled by the *InputJSON* method. The purpose of this operation is to analyze the *equations* block, print all components to a processable format and finally restructure it into a correct JSON string. This function retrieves three different types of equation specifications as definable in the *equations* block, namely all *kernels*, *functions* and *equations*. Instead of handing over an AST to the ODE-toolbox, all expressions are first printed by means of the *ExpressionPrettyPrinter* class to a Python-processable format. By exchanging strings instead of objects, a better control and comprehension of all side effects is achieved. For all three types of declarations in the *equations* block, PyNESTML implements an additional printing routine: The *printEquation* function retrieves the name of the left-hand side variable together with the differential order and combines it with the right-hand side expression printed by the *ExpressionPrettyPrinter*. This procedure is executed analogously for *kernels* and *functions*. Finally, it remains to combine the stored strings to a valid JSON format. The *InputJSON* function, therefore, iterates over the stored strings and combines them by means of a correct syntax as illustrated in :numref:`fig_nestml_to_json`. The result of the process as implemented in this function is a JSON string encapsulating all *equations* block specifications in a format processable by the ODE-toolbox. +The task of creating a JSON representation of a given *equations* block is handled by the *InputJSON* method. The purpose of this operation is to analyze the *equations* block, print all components to a processable format and finally restructure it into a correct JSON string. This function retrieves three different types of equation specifications as definable in the *equations* block, namely all *kernels*, *functions* and *equations*. Instead of handing over an AST to the ODE-toolbox, all expressions are first printed by means of the *ExpressionPrinter* class to a Python-processable format. By exchanging strings instead of objects, a better control and comprehension of all side effects is achieved. For all three types of declarations in the *equations* block, PyNESTML implements an additional printing routine: The *printEquation* function retrieves the name of the left-hand side variable together with the differential order and combines it with the right-hand side expression printed by the *ExpressionPrinter*. This procedure is executed analogously for *kernels* and *functions*. Finally, it remains to combine the stored strings to a valid JSON format. The *InputJSON* function, therefore, iterates over the stored strings and combines them by means of a correct syntax as illustrated in :numref:`fig_nestml_to_json`. The result of the process as implemented in this function is a JSON string encapsulating all *equations* block specifications in a format processable by the ODE-toolbox. .. _fig_interaction_ode_toolbox: @@ -115,9 +115,9 @@ Target implementations can often be described in a schematic way by means of a t Context sensitive target syntax. -While templates, in general, are able to depict an arbitrary syntax, their usage can become inconvenient whenever many cases have to be regarded and conditional branching occurs. This problem becomes more apparent when dealing with expressions: While the overall form of the AST is restructured to be more NEST affine, individual elements remain untouched and are still represented in PyNESTML syntax. However, certain details such as the used physical units are not supported by NEST. It is therefore required to transform atomic elements such as variables and constants to an appropriate representation in NEST. Moreover, in a single model it may be necessary to represent a certain element in different ways, cf. :numref:`fig_context_sensitive_target_syntax`. Consequently, it is not possible to simply modify the AST to use appropriate references and definitions. PyNESTML solves this problem by using an ad-hoc solution as implemented in the *ExpressionPrettyPrinter* class. Mostly used whenever expressions have to be printed, this class is able to generate a handed over AST object in a specified syntax. Similar to the type deriving routine, cf. :ref:`Section 1: The model-processing Frontend`, the *ExpressionPrettyPrinter* class first descends to the leaves of a handed over expression node. Subsequently, all leaf nodes are printed to a target-specific format, before being combined by counter pieces of the stated operators. This process is executed until the root node has been reached. The returned result is then used to replace a placeholder in the template by a string representation of the expression. +While templates, in general, are able to depict an arbitrary syntax, their usage can become inconvenient whenever many cases have to be regarded and conditional branching occurs. This problem becomes more apparent when dealing with expressions: While the overall form of the AST is restructured to be more NEST affine, individual elements remain untouched and are still represented in PyNESTML syntax. However, certain details such as the used physical units are not supported by NEST. It is therefore required to transform atomic elements such as variables and constants to an appropriate representation in NEST. Moreover, in a single model it may be necessary to represent a certain element in different ways, cf. :numref:`fig_context_sensitive_target_syntax`. Consequently, it is not possible to simply modify the AST to use appropriate references and definitions. PyNESTML solves this problem by using an ad-hoc solution as implemented in the *ExpressionPrinter* class. Mostly used whenever expressions have to be printed, this class is able to generate a handed over AST object in a specified syntax. Similar to the type deriving routine, cf. :ref:`Section 1: The model-processing Frontend`, the *ExpressionPrinter* class first descends to the leaves of a handed over expression node. Subsequently, all leaf nodes are printed to a target-specific format, before being combined by counter pieces of the stated operators. This process is executed until the root node has been reached. The returned result is then used to replace a placeholder in the template by a string representation of the expression. -The key principle of the *ExpressionPrettyPrinter* class is its composable nature: While the *ExpressionPrettyPrinter* only dictates how subexpressions and elements have to be printed and combined, the task to derive the actual syntax of elements and operators is delegated to so-called *reference converters*. Implementing the *template and hook* pattern [6]_\ , here it is possible to utilize different reference converters to print elements and operators into a different syntax. :numref:`fig_astexpression_to_string` demonstrates how expressions are transformed to a string representation by utilizing the above-introduced routine. +The key principle of the *ExpressionPrinter* class is its composable nature: While the *ExpressionPrinter* only dictates how subexpressions and elements have to be printed and combined, the task to derive the actual syntax of elements and operators is delegated to so-called *reference converters*. Implementing the *template and hook* pattern [6]_\ , here it is possible to utilize different reference converters to print elements and operators into a different syntax. :numref:`fig_astexpression_to_string` demonstrates how expressions are transformed to a string representation by utilizing the above-introduced routine. .. _fig_astexpression_to_string: @@ -126,9 +126,9 @@ The key principle of the *ExpressionPrettyPrinter* class is its composable natur From *ASTExpression* object to a string. -The abstract *IReferenceConverter* class declares which operations concrete reference converter classes have to implement. Besides converting functions for binary as well as unary operators, it is also necessary to map variables, constants and function calls. All these elements are therefore provided with their respective *convert* functions expecting an AST node of a corresponding type. The *ExpressionPrettyPrinter* class hereby stores a reference to the currently used reference converter, which is then used to convert the above-mentioned elements. The separation of a reference converter and the pretty printer leads to an easily maintainable and extensible system: Similar to the visitor pattern, cf. :ref:`Section 2: Assisting Classes`, where only the *visit* method has to be adjusted, here the user can simply replace or extend the reference converter without the need to modify the overall printing routine. Moreover, the code-generating routine becomes composable, where the implemented pretty printer can be independently combined with different reference converters. +The abstract *ReferenceConverter* class declares which operations concrete reference converter classes have to implement. Besides converting functions for binary as well as unary operators, it is also necessary to map variables, constants and function calls. All these elements are therefore provided with their respective *convert* functions expecting an AST node of a corresponding type. The *ExpressionPrinter* class hereby stores a reference to the currently used reference converter, which is then used to convert the above-mentioned elements. The separation of a reference converter and the pretty printer leads to an easily maintainable and extensible system: Similar to the visitor pattern, cf. :ref:`Section 2: Assisting Classes`, where only the *visit* method has to be adjusted, here the user can simply replace or extend the reference converter without the need to modify the overall printing routine. Moreover, the code-generating routine becomes composable, where the implemented pretty printer can be independently combined with different reference converters. -The *NESTReferenceConverter* is the first concrete implementation of the *IReferenceConverter* class and is used whenever concepts of NESTML have to be converted to those in NEST. Being used in almost all parts of the provided templates, this class features a conversion of operators and constants to their equivalents of the NEST library. As illustrated in :numref:`fig_astexpression_to_string`, each element of a given expression is inspected individually and a counter piece in NEST is returned, making the generated code semantically correct and references valid. The *GSLReferenceConverter* class implements the handling of references which is only required in the context of *equation* blocks. NEST utilizes GSL for the evolvement of equations. Consequently, references as stated in the *equations* block have to resolve to elements of GSL. The *GSLReferenceConverter* hereby inspects the handed over element and returns the respective counterpiece. If a mapping is not defined, the element is simply returned without any modifications. +The *NESTReferenceConverter* is the first concrete implementation of the *ReferenceConverter* class and is used whenever concepts of NESTML have to be converted to those in NEST. Being used in almost all parts of the provided templates, this class features a conversion of operators and constants to their equivalents of the NEST library. As illustrated in :numref:`fig_astexpression_to_string`, each element of a given expression is inspected individually and a counter piece in NEST is returned, making the generated code semantically correct and references valid. The *GSLReferenceConverter* class implements the handling of references which is only required in the context of *equation* blocks. NEST utilizes GSL for the evolvement of equations. Consequently, references as stated in the *equations* block have to resolve to elements of GSL. The *GSLReferenceConverter* hereby inspects the handed over element and returns the respective counterpiece. If a mapping is not defined, the element is simply returned without any modifications. .. _fig_syntax_by_converttocppname: @@ -137,7 +137,7 @@ The *NESTReferenceConverter* is the first concrete implementation of the *IRefer Adaption of syntax by the *convertToCPPName* method. -C++ as well as many other languages does not support the apostrophe as a valid part of an identifier. Consequently, variables stated together with their differential order cannot be directly generated as C++ code. PyNESTML solves this problem by implementing an on-demand transformation of names, executed whenever a variable is processed during code generation. In the case that the name of a generated element contains an invalid literal, PyNESTML employs the *convertToCPPName* operation which prefixes a variable for each stated order by the letter *D*, cf. :numref:`fig_syntax_by_converttocppname`, resulting in a valid C++ syntax. Moreover, as illustrated in :numref:`fig_templates_generated_code_izhikevich`, generated code features information hiding where attributes of objects and classes can only be accessed by the corresponding data access operations. Together with the *convertToCPPName* function, a conversion of names and references to their respective data access operation is implemented in the *NestNamesConverter*, respectively *GSLNamesConverter* class for the processing of equations. Both elements are accessed during code generation and the usage of the *ExpressionPrettyPrinter* class. +C++ as well as many other languages does not support the apostrophe as a valid part of an identifier. Consequently, variables stated together with their differential order cannot be directly generated as C++ code. PyNESTML solves this problem by implementing an on-demand transformation of names, executed whenever a variable is processed during code generation. In the case that the name of a generated element contains an invalid literal, PyNESTML employs the *convertToCPPName* operation which prefixes a variable for each stated order by the letter *D*, cf. :numref:`fig_syntax_by_converttocppname`, resulting in a valid C++ syntax. Moreover, as illustrated in :numref:`fig_templates_generated_code_izhikevich`, generated code features information hiding where attributes of objects and classes can only be accessed by the corresponding data access operations. Together with the *convertToCPPName* function, a conversion of names and references to their respective data access operation is implemented in the *NestNamesConverter*, respectively *GSLNamesConverter* class for the processing of equations. Both elements are accessed during code generation and the usage of the *ExpressionPrinter* class. .. _fig_mapping_nestml_types_to_nest: @@ -148,7 +148,7 @@ C++ as well as many other languages does not support the apostrophe as a valid p The second type of assisting component, namely the *NestPrinter* class, is used across the overall backend and implements several methods as often required. The *printOrigin* method, for instance, states from which type of block the corresponding variable or constant originates. Depending on the origin, a different prefix is attached, e.g., *S\_.* for state or *P\_.* for parameters. Such a handling is required given the fact, that all attributes in the generated code are stored in *structs* [7]_ of their respective types. By prefixing an element's name by a reference to its structure, the correctness of generated code is preserved. -The *NESTML2NestTypeConverter* class provides a mapping from NESTML types to appropriate types in C++, cf. :numref:`fig_mapping_nestml_types_to_nest`. It should be noted that NESTML buffers represent variables and consequently have to be declared with a respective type. For this purpose, NEST's implementation of the *RingBuffer* is used as the corresponding counter piece. Whenever an element is generated, the functionality contained in the *NESTML2NestTypeConverter* class is used and an appropriate NEST type is returned. +The *CppTypesPrinter* class provides a mapping from NESTML types to appropriate types in C++, cf. :numref:`fig_mapping_nestml_types_to_nest`. It should be noted that NESTML buffers represent variables and consequently have to be declared with a respective type. For this purpose, NEST's implementation of the *RingBuffer* is used as the corresponding counter piece. Whenever an element is generated, the functionality contained in the *CppTypesPrinter* class is used and an appropriate NEST type is returned. .. _fig_common_neuroscientific_units: @@ -169,14 +169,14 @@ In the case of physical units, additional handling is required. NEST assumes tha However, a mapping of physical units to their respective scalars is not bijective. For instance, the scalar *1000* in a transformed expression could originate from the unit *volt* or *second*, or be a simple scalar stated in the source model. Such a handling makes troubleshooting of generated code complex where the origin of an element is not directly clear. This problem is solved by the *IdempotentReferenceConverter* class, a component which implements a simple *identity mapping*, i.e., all elements are converted to themselves. This class is used during the generation of a model's documentation where all variables, types, as well as references, are generated in plain NESTML syntax. -Together with the above-presented set of assisting classes, the functionality as implemented in the *ExpressionPrettyPrinter* class enables PyNESTML to print complex expressions and other declarations without utilizing templates with cascaded branching and sub-templates for the generation of atomic parts, e.g., function calls. The result is an easy to maintain set of components, where complexity is distributed across several subsystems and no *god* classes or templates [8]_ are used. +Together with the above-presented set of assisting classes, the functionality as implemented in the *ExpressionPrinter* class enables PyNESTML to print complex expressions and other declarations without utilizing templates with cascaded branching and sub-templates for the generation of atomic parts, e.g., function calls. The result is an easy to maintain set of components, where complexity is distributed across several subsystems and no *god* classes or templates [8]_ are used. -Section 3.2: Summary of the code-generating Backend +Section 3.2: Summary of the code-generating Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We conclude this chapter by a brief overview of the implemented routines. :ref:`Section 3.1: AST Transformations and Code Generation` demonstrated how NEST-specific C++ code can be generated from an optimized AST. Here, we first introduced the coordinating *NestCodeGenerator* class and showed how code generation is prepared. To this end, we outlined how declarations of models can be optimized by restructuring the *equations* block to a more efficient form. The computation of the optimizations is hereby delegated to the ODE-toolbox by Blundell et al. In order to integrate the results as returned by the toolbox, we implemented the *EquationsBlockProcessor* and its assisting classes. Together, these two components yield a more efficient definition of a model. Subsequently, we highlighted a set of templates used to depict the general structure of generated C++ code. In order to reduce the complexity in the used templates, PyNESTML delegated the task of generating expressions to the *ExpressionPrettyPrinter* class. Together, these components implement a process which achieves a *model to text* transformation on textual models. +We conclude this chapter by a brief overview of the implemented routines. :ref:`Section 3.1: AST Transformations and Code Generation` demonstrated how NEST-specific C++ code can be generated from an optimized AST. Here, we first introduced the coordinating *NestCodeGenerator* class and showed how code generation is prepared. To this end, we outlined how declarations of models can be optimized by restructuring the *equations* block to a more efficient form. The computation of the optimizations is hereby delegated to the ODE-toolbox by Blundell et al. In order to integrate the results as returned by the toolbox, we implemented the *EquationsBlockProcessor* and its assisting classes. Together, these two components yield a more efficient definition of a model. Subsequently, we highlighted a set of templates used to depict the general structure of generated C++ code. In order to reduce the complexity in the used templates, PyNESTML delegated the task of generating expressions to the *ExpressionPrinter* class. Together, these components implement a process which achieves a *model to text* transformation on textual models. -PyNESTML has been developed with the intent to provide a base for future development and extensions. As we demonstrated in :ref:`Section 3.1: AST Transformations and Code Generation`, the transformation used to construct NEST-affine and efficient code has been called from within the NEST code generator as a preprocessing step. Future backends for target platform-specific code generation can, therefore, implement their individual and self-contained transformations, while all backends receive the same, unmodified input from the frontend. Individual modifications of the AST can be easily implemented as composable filters in the AST processing pipeline. Nonetheless, some of the model optimization steps are of target platform-agnostic nature, e.g., simplification of physical units, and are therefore implemented as a target-unspecific component in the workflow. Moreover, the key principle of the *ExpressionPrettyPrinter*, namely its composability by means of reference converters, represents a reusable component which can be used for code generation to arbitrary target platforms. All this leads to a situation where extensions can be implemented by simply composing existing components. +PyNESTML has been developed with the intent to provide a base for future development and extensions. As we demonstrated in :ref:`Section 3.1: AST Transformations and Code Generation`, the transformation used to construct NEST-affine and efficient code has been called from within the NEST code generator as a preprocessing step. Future backends for target platform-specific code generation can, therefore, implement their individual and self-contained transformations, while all backends receive the same, unmodified input from the frontend. Individual modifications of the AST can be easily implemented as composable filters in the AST processing pipeline. Nonetheless, some of the model optimization steps are of target platform-agnostic nature, e.g., simplification of physical units, and are therefore implemented as a target-unspecific component in the workflow. Moreover, the key principle of the *ExpressionPrinter*, namely its composability by means of reference converters, represents a reusable component which can be used for code generation to arbitrary target platforms. All this leads to a situation where extensions can be implemented by simply composing existing components. Go to :ref:`Section 4: Extending PyNESTML`. diff --git a/doc/pynestml_toolchain/front.rst b/doc/pynestml_toolchain/front.rst index 815ce8278..d07225da2 100644 --- a/doc/pynestml_toolchain/front.rst +++ b/doc/pynestml_toolchain/front.rst @@ -8,7 +8,7 @@ In this section we will demonstrate how the model-processing frontend of PyNESTM .. figure:: https://raw.githubusercontent.com/nest/NESTML/master/doc/pynestml_toolchain/pic/front_overview_cropped.jpg :alt: Overview of the model-processing Frontend - Overview of the model-processing Frontend: The lexer and parser process a textual model to the corresponding parse tree and can be completely generated from a grammar artifact. The ASTBuilderVisitor is responsible for the initialization of a model's AST, employing classes which conform to the DSL's grammar. After the AST has been constructed, the CommentCollectorVisitor collects and stores all comments stated in the source model. The ASTSymbolTableVisitor subsequently collects context information of the model by utilizing Symbols and the predefined subsystem. Semantic Checks conclude the rocessing by checking the model for semantical correctness. All steps are orchestrated by the ModelParser. + Overview of the model-processing Frontend: The lexer and parser process a textual model to the corresponding parse tree and can be completely generated from a grammar artifact. The ASTBuilderVisitor is responsible for the initialization of a model's AST, employing classes which conform to the DSL's grammar. After the AST has been constructed, the CommentCollectorVisitor collects and stores all comments stated in the source model. The ASTSymbolTableVisitor subsequently collects context information of the model by utilizing Symbols and the predefined subsystem. Semantic Checks conclude the processing by checking the model for semantical correctness. All steps are orchestrated by the ModelParser. .. _sec-lexer-parser-overview: @@ -251,8 +251,6 @@ Given the fact that context conditions have the commonality of checking the cont - *CoCoIllegalExpression*: Checks that all expressions are typed according to the left-hand side variable, or are at least castable to each other. -- *CoCoInitVarsWithOdesProvided*: Checks that all variables declared in the *initial values* block are provided with the corresponding ODEs. - - *CoCoInvariantIsBoolean*: Checks that the type of all given invariants is *boolean*. - *CoCoNeuronNameUnique*: Checks that no name collisions of neurons occur. Here, only the names in the same artifact are checked. diff --git a/doc/pynestml_toolchain/index.rst b/doc/pynestml_toolchain/index.rst index d3bfde483..961c13caa 100644 --- a/doc/pynestml_toolchain/index.rst +++ b/doc/pynestml_toolchain/index.rst @@ -14,6 +14,7 @@ PyNESTML - NESTML Toolchain in Python This documentation represents PyNESTML's implementation "as is" at the time of writing. **No guarantee of completeness or correctness is given.** As typical for all types of software, the actual implementation may change over time. The following documentation, therefore, provides an overview of the used components and approaches, while the actual code may be adapted in future. Nonetheless, the general ideas and concepts should remain applicable and valid. + Engineering of domain-specific languages (DSL) such as NESTML represents a process which requires a fundamental understanding in two areas: The problem domain (e.g., computational neuroscience), and a set of tools to model and solve problems in this domain. In the following, we will leave all principles related to the former to the experts of the respective domain, and only demonstrate how the latter can be solved by means of a set of generated and hand-coded solutions. Consequently, no discussion of modeled aspects takes place, the language is therefore assumed to be given. Instead, we will demonstrate, starting from the specification of the language, which components are required and how these components have been implemented in PyNESTML. :doc:`Section 1 ` introduces the model processing frontend, a subsystem which is able to read in a (textual) model and instantiate a computer processable representation. :doc:`Section 2 ` will subsequently demonstrate a set of assisting components which make interaction with the tool, as well as other tasks, easier to achieve. :doc:`Section 3 ` will then show how model-to-text transformations (i.e., code generation) can be achieved. Finally, for those who are interested in extension points of PyNESTML, :doc:`Section 4 ` will subsume how the framework has to be adapted and extended to support new concepts in NESTML. diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 000000000..b80f11000 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,5 @@ +ipykernel +nbsphinx +docutils +sphinx>=4 +sphinx_rtd_theme>=1.0.0 diff --git a/doc/running.rst b/doc/running.rst index c94ef36de..4274daf40 100644 --- a/doc/running.rst +++ b/doc/running.rst @@ -1,67 +1,22 @@ Running NESTML ############## -After the installation, the toolchain can be executed by the following command. +Running NESTML from Python +-------------------------- -.. code-block:: bash - - nestml ARGUMENTS - -where arguments are: - -.. list-table:: - :header-rows: 1 - :widths: 10 30 - - * - Command - - Description - * - ``-h`` or ``--help`` - - Print help message. - * - ``--input_path`` - - Path to the source file or directory containing the model. - * - ``--target_path`` - - (Optional) Path to target directory where generated code will be written into. Default is ``target``, which will be created in the current working directory if it does not yet exist. - * - ``--target`` - - (Optional) The name of the target platform to generate code for. Default is NEST. - * - ``--logging_level`` - - (Optional) Sets the logging level, i.e., which level of messages should be printed. Default is ERROR, available are [INFO, WARNING, ERROR, NO] - * - ``--module_name`` - - (Optional) Sets the name of the module which shall be generated. Default is the name of the directory containing the models. The name has to end in "module". Default is `nestmlmodule`. - * - ``--store_log`` - - (Optional) Stores a log.txt containing all messages in JSON notation. Default is OFF. - * - ``--suffix`` - - (Optional) A suffix string that will be appended to the name of all generated models. - * - ``--dev`` - - (Optional) Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code. Default is OFF. - - -Generated artifacts are copied to the selected target directory (default is ``target``). In order to install the models into NEST, the following commands have to be executed from within the target directory: - -.. code-block:: bash - - cmake -Dwith-nest=/bin/nest-config . - make all - make install - -where ```` is the installation directory of NEST (e.g. ``/home/nest/work/nest-install``). Subsequently, the module can either be linked into NEST (see `Writing an extension module `_), or loaded dynamically using the ``Install`` API call. For example, to dynamically load a module with ``module_name`` equal to ``nestmlmodule`` in PyNEST: +NESTML can be imported as a Python package, and can therefore be used from within other Python tools and scripts. After PyNESTML has been installed, the following function has to be imported: .. code-block:: python - nest.Install("nestmlmodule") + from pynestml.frontend.pynestml_frontend import generate_target -PyNESTML is also available as a component and can therefore be used from within other Python tools and scripts. After PyNESTML has been installed, the following modules have to be imported: +Subsequently, it is possible to call PyNESTML from other Python tools and scripts via calls to ``generate_target()``, which generates, builds and installs code for the target platform. ``generate_target()`` can be called as follows: .. code-block:: python - from pynestml.frontend.pynestml_frontend import to_nest, install_nest + generate_target(input_path, target_platform, target_path, install_path, logging_level, module_name, store_log, suffix, dev, codegen_opts) -Subsequently, it is possible to call PyNESTML from other Python tools and scripts via: - -.. code-block:: python - - to_nest(input_path, target_path, logging_level, module_name, store_log, dev) - -This operation expects the same set of arguments as in the case of command line invocation. The following default values are used, corresponding to the command line defaults. Possible values for ``logging_level`` are the same as before ('INFO', 'WARNING', 'ERROR', 'NO'). Note that only the ``input_path`` argument is mandatory: +The following default values are used, corresponding to the command line defaults. Possible values for ``logging_level`` are the same as before ("DEBUG", "INFO", "WARNING", "ERROR", "NO"). Note that only the ``input_path`` argument is mandatory: .. list-table:: :header-rows: 1 @@ -71,47 +26,140 @@ This operation expects the same set of arguments as in the case of command line - Type - Default * - input_path - - string + - str or Sequence[str] - *no default* + * - target_platform + - str + - "NEST" * - target_path - - string + - str + - None + * - install_path + - str - None * - logging_level - - string - - 'ERROR' + - str + - "ERROR" * - module_name - - string - - ``nestmlmodule`` + - str + - "nestmlmodule" + * - suffix + - str + - "" * - store_log - - boolean + - bool - False * - dev - - boolean + - bool - False + * - codegen_opts + - Optional[Mapping[str, Any]] + - (Optional) A JSON equivalent Python dictionary containing additional options for the target platform code generator. These options are specific to a given target platform, see for example :ref:`Running NESTML with custom templates`. -If no errors occur, the output will be generated into the specified target directory. In order to avoid an execution of all required module-installation routines by hand, PyNESTML features a function for an installation of NEST models directly into NEST: +A typical script for the NEST Simulator target could look like the following. First, import the function: .. code-block:: python - install_nest(models_path, nest_path) + from pynestml.frontend.pynestml_frontend import generate_target + + generate_target(input_path="/home/nest/work/pynestml/models", + target_platform="NEST", + target_path="/tmp/nestml_target") -Here, ``models_path`` should be set to the ``target`` directory of ``to_nest()``, and ``nest_path`` points to the directory where NEST is installed (e.g., ``/home/nest/work/nest-install``). This path can conveniently be obtained from the ``nest`` module as follows: +We can also use a shorthand function for each supported target platform (here, NEST): .. code-block:: python - import nest - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") + from pynestml.frontend.pynestml_frontend import generate_nest_target + + generate_nest_target(input_path="/home/nest/work/pynestml/models", + target_path="/tmp/nestml_target") -A typical script, therefore, could look like the following. For this example, we assume that the name of the generated module is ``nestmlmodule``. +To dynamically load a module with ``module_name`` equal to ``nestmlmodule`` (the default) in PyNEST can be done as follows: .. code-block:: python - from pynestml.frontend.pynestml_frontend import to_nest, install_nest + nest.Install("nestmlmodule") - to_nest(input_path="/home/nest/work/pynestml/models", target_path="/home/nest/work/pynestml/target") +The NESTML models are then available for instantiation, for example as: - install_nest("/home/nest/work/pynestml/target", "/home/nest/work/nest-install") +.. code-block:: python - nest.Install("nestmlmodule") - # ... - nest.Simulate(400.) + pre, post = nest.Create("neuron_nestml", 2) + nest.Connect(pre, post, "one_to_one", syn_spec={"synapse_model": "synapse_nestml"}) + + +Running NESTML from the command line +------------------------------------ + +The toolchain can also be executed from the command line by running: + +.. code-block:: bash + + nestml ARGUMENTS + +This will generate, compile, build, and install the code for a set of specified NESTML models. The following arguments can be given, corresponding to the arguments in the command line invocation: + +.. list-table:: + :header-rows: 1 + :widths: 10 30 + + * - Command + - Description + * - ``-h`` or ``--help`` + - Print help message. + * - ``--input_path`` + - One or more input path(s). Each path is a NESTML file, or a directory containing NESTML files. Directories will be searched recursively for files matching "\*.nestml". + * - ``--target_path`` + - (Optional) Path to target directory where generated code will be written into. Default is ``target``, which will be created in the current working directory if it does not yet exist. + * - ``--target_platform`` + - (Optional) The name of the target platform to generate code for. Default is ``NEST``. + * - ``--logging_level`` + - (Optional) Sets the logging level, i.e., which level of messages should be printed. Default is ERROR, available are [DEBUG, INFO, WARNING, ERROR, NO] + * - ``--module_name`` + - (Optional) Sets the name of the module which shall be generated. Default is the name of the directory containing the models. The name has to end in "module". Default is `nestmlmodule`. + * - ``--store_log`` + - (Optional) Stores a log.txt containing all messages in JSON notation. Default is OFF. + * - ``--suffix`` + - (Optional) A suffix string that will be appended to the name of all generated models. + * - ``--install_path`` + - (Optional) Path to the directory where the generated code will be installed. + * - ``--dev`` + - (Optional) Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code. Default is OFF. + * - ``--codegen_opts`` + - (Optional) Path to a JSON file containing additional options for the target platform code generator. + + +NEST Simulator target +--------------------- + +After NESTML completes, the NEST extension module (by default called ``"nestmlmodule"``) can either be statically linked into NEST (see `Writing an extension module `_), or loaded dynamically using the ``Install`` API call in Python. + +Manually building the extension module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes it can be convenient to directly edit the generated code. To manually build and install the NEST extension module, go into the target directory and run: + +.. code-block:: bash + + cmake -Dwith-nest=/bin/nest-config . + make all + make install + +where ```` is the installation directory of NEST (e.g. ``/home/nest/work/nest-install``). + + +Custom templates +~~~~~~~~~~~~~~~~ + +See :ref:`Running NESTML with custom templates`. + + +Compatibility with different versions of NEST +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To generate code that is compatible with particular release versions of NEST Simulator, the code generator option ``nest_version`` can be used. It takes a string as its value that corresponds to a git tag or git branch name. The following values are supported: + +- The default is the empty string, which causes the NEST version to be automatically identified from the ``nest`` Python module. +- ``"v2.20.2"``: Latest NEST 2 release. +- ``"master"``: Latest NEST GitHub master branch version (https://github.com/nest/nest-simulator/). diff --git a/doc/sphinx-apidoc/_static/css/custom.css b/doc/sphinx-apidoc/_static/css/custom.css index 0a31186a7..b24225f7f 100644 --- a/doc/sphinx-apidoc/_static/css/custom.css +++ b/doc/sphinx-apidoc/_static/css/custom.css @@ -133,4 +133,3 @@ code.descclassname { overflow: visible !important; } } - diff --git a/doc/sphinx-apidoc/conf.py b/doc/sphinx-apidoc/conf.py index 86c0f28e3..7cecf9c9a 100644 --- a/doc/sphinx-apidoc/conf.py +++ b/doc/sphinx-apidoc/conf.py @@ -19,13 +19,8 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -""" +r""" Readthedocs configuration file ------------------------------- - -Use: -sphinx-build -c ../extras/help_generator -b html . _build/html - """ import os @@ -59,18 +54,22 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('../doc/sphinx-apidoc')) sys.path.insert(0, os.path.abspath('doc/sphinx-apidoc')) +sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('doc')) sys.path.insert(0, os.path.abspath('pynestml')) sys.path.insert(0, os.path.abspath('pynestml/codegeneration')) +print("sys.path: " + str(sys.path)) +print("Running sphinx-apidoc...") os.system("sphinx-apidoc --module-first -o " + os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../pynestml') + " " + os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../pynestml')) # in-source generation of necessary .rst files - +print("Copying documentation files...") import fnmatch import os @@ -87,6 +86,8 @@ matches.append(os.path.join(root, filename)) for filename in fnmatch.filter(filenames, '*.png'): matches.append(os.path.join(root, filename)) + for filename in fnmatch.filter(filenames, '*.ipynb'): + matches.append(os.path.join(root, filename)) print("Matches:") print(matches) @@ -100,12 +101,12 @@ print(fns) """ for fn in matches: - if "sphinx-apidoc" in fn: - continue - fn_from = fn - fn_to = os.path.join(static_docs_dir, "sphinx-apidoc", fn[len(static_docs_dir)+1:]) - print("From " + fn_from + " to " + fn_to) - os.system('install -v -D ' + fn_from + " " + fn_to) + if "sphinx-apidoc" in fn: + continue + fn_from = fn + fn_to = os.path.join(static_docs_dir, "sphinx-apidoc", fn[len(static_docs_dir)+1:]) + print("From " + fn_from + " to " + fn_to) + os.system('install -v -D ' + fn_from + " " + fn_to) #os.system('for i in `find .. -name "*.rst"` ; do if [[ ${i} != *"sphinx-apidoc"* ]] ; then install -v -D ${i} ${i/\.\.\//}; fi ; done') """os.system('cp -v ' @@ -141,6 +142,7 @@ 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', + 'nbsphinx', ] mathjax_path = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS-MML_HTMLorMML" @@ -205,12 +207,19 @@ # documentation. html_theme_options = {'logo_only': True} -html_logo = "nestml-logo.png" +html_logo = "nestml-logo/nestml-logo.png" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static', 'nestml-logo'] +html_static_path = ['_static'] + +# These paths are either relative to html_static_path +# or fully qualified paths (eg. https://...) +html_css_files = [ + 'css/custom.css', + 'css/pygments.css' +] # -- Options for HTMLHelp output ------------------------------------------ @@ -228,9 +237,8 @@ def setup(app): - app.add_stylesheet('css/custom.css') - app.add_stylesheet('css/pygments.css') - app.add_javascript("js/custom.js") + app.add_css_file('css/custom.css') + app.add_css_file('css/pygments.css') # -- Options for LaTeX output --------------------------------------------- diff --git a/doc/sphinx-apidoc/index.rst b/doc/sphinx-apidoc/index.rst index d9658bef0..547ed7c26 100644 --- a/doc/sphinx-apidoc/index.rst +++ b/doc/sphinx-apidoc/index.rst @@ -1,58 +1,50 @@ -Welcome to the NESTML documentation -=================================== +The NESTML modeling language +============================ + +.. figure:: https://raw.githubusercontent.com/clinssen/nestml/doc_blurb/doc/fig/nestml_clip_art.png + :width: 296px + :height: 350px + :align: right + +NESTML is a domain-specific language for neuron and synapse models. These dynamical models can be used in simulations of brain activity on several platforms, in particular the `NEST Simulator `_. + +NESTML combines: + +- an easy to understand, yet powerful syntax; +- a flexible processing toolchain, written in Python; +- good simulation performance by means of code generation (C++ for NEST Simulator). + +To see what NESTML looks like, please see the :doc:`models library `. The library contains a variety of models from standard integrate-and-fire to a family of biophysical, Hodgkin-Huxley type neurons, as well as several synaptic plasticity models such as spike-timing dependent plasticity (STDP) variants and third-factor plasticity rules. + +:doc:`PyNESTML ` is the Python-based toolchain for the NESTML language: it parses the model and performs code generation. Modify PyNESTML to add language elements such as new predefined functions, or to add new target platforms in the form of `Jinja `_ templates. + +Internally, differential equations are analyzed by the associated `ODE-toolbox `_, to compute an exact solution if possible or to select an appropriate numeric solver otherwise. -NESTML is a domain-specific language that supports the specification of neuron models in a precise and concise syntax. It was developed to address the maintainability issues that follow from an increasing number of models, model variants, and an increased model complexity in computational neuroscience. Our aim is to ease the modelling process for neuroscientists both with and without prior training in computer science. This is achieved without compromising on performance by automatic source-code generation, allowing the same model file to target different hardware or software platforms by changing only a command-line parameter. While originally developed in the context of `NEST Simulator `_, the language itself as well as the associated toolchain are lightweight, modular and extensible, by virtue of using a parser generator and internal abstract syntax tree (AST) representation, which can be operated on using well-known patterns such as visitors and rewriting. Model equations can either be given as a simple string of mathematical notation or as an algorithm written in the built-in procedural language. The equations are analyzed by the associated toolchain `ODE-toolbox `_, to compute an exact solution if possible or to invoke an appropriate numeric solver otherwise. .. toctree:: :glob: :hidden: :maxdepth: 1 - nestml_language + nestml_language/index installation running models_library/index - pynestml_toolchain/index + tutorials/index + extending getting_help citing license - .. .. figure:: nestml-logo/nestml-logo.png :scale: 30 % :align: center -Model development with NESTML -============================= - -Summary of language features and syntax -####################################### - -:doc:`The NESTML language ` - - -Models library -############## - -Out of the box, use any of :doc:`over 20 models ` that come packaged with NESTML, from standard integrate-and-fire varieties to a family of biophysical, Hodgkin-Huxley type neurons. - Tutorials ######### -* :doc:`Izhikevich tutorial ` - - Learn how to finish a partial Izhikevich spiking neuron model. - - -NESTML language and toolchain development -========================================= - -:doc:`PyNESTML ` is the Python-based toolchain for the NESTML language: it parses the model, invokes ODE-toolbox and performs code generation. Modify PyNESTML to add language elements such as new predefined functions, or to add new target platforms. - -API documentation is automatically generated from source code: :mod:`pynestml` **module index** - -Internally, the `ODE-toolbox `__ Python package is used for the processing of differential equations. +.. include:: tutorials/tutorials_list.rst .. include:: getting_help.rst @@ -64,3 +56,5 @@ Acknowledgements This software was initially supported by the JARA-HPC Seed Fund *NESTML - A modeling language for spiking neuron and synapse models for NEST* and the Initiative and Networking Fund of the Helmholtz Association and the Helmholtz Portfolio Theme *Simulation and Modeling for the Human Brain*. This software was developed in part or in whole in the Human Brain Project, funded from the European Union's Horizon 2020 Framework Programme for Research and Innovation under Specific Grant Agreements No. 720270, No. 785907 and No. 945539 (Human Brain Project SGA1, SGA2 and SGA3). + +Neuron and synapse illustration: copyright Sebastian B.C. Lehmann , INM-6, Forschungszentrum Jülich GmbH (CC-BY-SA) diff --git a/doc/tutorial/Slides.pdf b/doc/tutorial/Slides.pdf deleted file mode 100644 index f1932e79d..000000000 Binary files a/doc/tutorial/Slides.pdf and /dev/null differ diff --git a/doc/tutorial/Slides.pptx b/doc/tutorial/Slides.pptx deleted file mode 100644 index 2db51126c..000000000 Binary files a/doc/tutorial/Slides.pptx and /dev/null differ diff --git a/doc/tutorial/izhikevich_tutorial.rst b/doc/tutorial/izhikevich_tutorial.rst deleted file mode 100644 index 00f2988ad..000000000 --- a/doc/tutorial/izhikevich_tutorial.rst +++ /dev/null @@ -1,64 +0,0 @@ -Introduction ------------- - -The aim of this exercise is to obtain familiarity with NESTML by completing a partial model of the Izhikevich neuron [1]_. In the file `izhikevich_task.nestml`, a subset of the parameters, state equations and update block is implemented. Your task is to complete the model code. For reference, the solution is included as `izhikevich_solution.nestml`. - - -Start your Python interpreter ------------------------------ - -`PYTHONPATH` needs to be set so that PyNEST can be imported (`import nest` in Python). `LD_LIBRARY_PATH` needs to be set to the directory where NESTML will generate the C++ code for the model, and where the dynamic library (`.so`) will be built. I chose `/tmp/nestml-component` here as an example. - -Note that on MacOS, `LD_LIBRARY_PATH` is called `DYLD_LIBRARY_PATH`. - -.. code-block:: bash - - PYTHONPATH=$PYTHONPATH:/home/johndoe/nest-simulator-build/lib/python3.6/site-packages LD_LIBRARY_PATH=/tmp/nestml-component ipython3 - - -NESTML code generation ----------------------- - -Assume we have a NESTML input model at `/home/johndoe/nestml-tutorial/izhikevich_solution.nestml`. To generate code, build the module and load the module into the NEST Simulator: - -.. code-block:: python - - from pynestml.frontend.pynestml_frontend import to_nest, install_nest - to_nest(input_path="/home/johndoe/nestml-tutorial/izhikevich_solution.nestml", target_path="/tmp/nestml-component", logging_level="INFO") - install_nest("/tmp/nestml-component", "/home/johndoe/nest-simulator-build") - - -Instantiate model in NEST Simulator and run -------------------------------------------- - -In the same Python session, continue entering the following code. This performs the instantiation of the model (`nest.Create("izhikevich_tutorial")`), injects a constant current and runs the simulation for 250 ms. - -.. code-block:: python - - import nest - import matplotlib.pyplot as plt - - nest.set_verbosity("M_WARNING") - nest.ResetKernel() - nest.Install("nestmlmodule") - - neuron = nest.Create("izhikevich_tutorial") - voltmeter = nest.Create("voltmeter") - - voltmeter.set({"record_from": ["v"]}) - nest.Connect(voltmeter, neuron) - - cgs = nest.Create('dc_generator') - cgs.set({"amplitude": 25.}) - nest.Connect(cgs, neuron) - - nest.Simulate(250.) - - plt.plot(voltmeter.get("events")["times"], voltmeter.get("events")["v"]) - plt.show() - - -References ----------- - -.. [1] Eugene M. Izhikevich, "Simple Model of Spiking Neurons", IEEE Transactions on Neural Networks, Vol. 14, No. 6, November 2003 diff --git a/doc/tutorials/active_dendrite/nestml_active_dendrite_tutorial.ipynb b/doc/tutorials/active_dendrite/nestml_active_dendrite_tutorial.ipynb new file mode 100644 index 000000000..f91bd75d5 --- /dev/null +++ b/doc/tutorials/active_dendrite/nestml_active_dendrite_tutorial.ipynb @@ -0,0 +1,602 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NESTML active dendrite tutorial\n", + "\n", + "In this tutorial, we create a neuron model with a \"nonlinear\" or \"active\" dendritic compartment, that can, independently from the soma, generate a dendritic action potential. Instead of modeling the membrane potential of the dendritic compartment explicitly, the dendritic action potential (dAP) is modeled here as the injection of a rectangular (pulse shaped) dendritic current into the soma, parameterized by an amplitude and a duration. The rectangular shape can be interpreted as the approximation of an NMDA spike (Antic et al. 2010). A dendritic action potential is triggered when the total synaptic current exceeds a threshold.\n", + "\n", + "The model we are building is an adapted version of the neuron model introduced by Memmesheimer et al. (2012) and Jahnke et al. (2012).\n", + "\n", + "**Table of contents**\n", + "
    \n", + "
  • [Adding dAP current to the model](#section_adding_to_model)
  • \n", + "
  • [Dynamically controlling synaptic integration](#section_integration)
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib as mpl\n", + "import matplotlib.pyplot as plt\n", + "import nest\n", + "import numpy as np\n", + "import os\n", + "from pynestml.frontend.pynestml_frontend import generate_nest_target\n", + "\n", + "NEST_SIMULATOR_INSTALL_LOCATION = nest.ll_api.sli_func(\"statusdict/prefix ::\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Adding dAP current to the model\n", + "\n", + "\n", + "We will use a standard, linear integrate-and-fire neuron with the governing equation:\n", + " \n", + "\\begin{align}\n", + "\\frac{dV_m}{dt} &= -\\frac{1}{\\tau_m} (V_m - E_L) + \\frac{1}{C_m} (I_{syn} + I_{dAP})\n", + "\\end{align}\n", + "\n", + "Here, the term $I_{syn}$ contains all the currents flowing into the soma due to synaptic input, and $I_{dAP}$ contains the contribution of a dendritic action potential.\n", + "\n", + "### Implementing the pulse shape\n", + "\n", + "The dAP current is modeled here as a rectangular (pulse) function, parameterized by an amplitude (current strength) and width (duration). \n", + "\n", + "```nestml\n", + "parameters:\n", + " I_dAP_peak pA = 150 pA # current clamp value for I_dAP during a dendritic action potential\n", + " T_dAP ms = 10 ms # time window over which the dendritic current clamp is active\n", + " ...\n", + "```\n", + "\n", + "We also define a synaptic current threshold that, when crossed, initiates the dendritic action potential:\n", + "\n", + "```nestml\n", + "parameters:\n", + " I_th pA = 100 pA # current threshold for a dendritic action potential\n", + " ...\n", + "```\n", + "\n", + "The current is switched on and off as follows. When a dendritic action potential is triggered, the magnitude of the ``I_dAP`` current is set to ``I_dAP_peak``, and a timer variable ``t_dAP`` is set to the duration of the current pulse, ``T_dAP``. At each future run of the NESTML ``update`` block, the timer is decremented until it reaches 0, at which point the dendritic action potential current ``I_dAP`` is set back to zero.\n", + "```nestml\n", + "update:\n", + " if t_dAP > 0 ms:\n", + " # during a dendritic action potential pulse\n", + " t_dAP -= resolution()\n", + " if t_dAP <= 0 ms:\n", + " # end of dendritic action potential\n", + " I_dAP = 0 pA\n", + " t_dAP = 0 ms\n", + " end\n", + " end\n", + "\n", + " if I_syn > I_th:\n", + " # current-threshold, emit a dendritic action potential\n", + " t_dAP = T_dAP\n", + " I_dAP = I_dAP_peak\n", + " end\n", + "```\n", + "\n", + "The complete neuron model is as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_active_dend_model = '''\n", + "neuron iaf_psc_exp_active_dendrite:\n", + " state:\n", + " V_m mV = 0 mV # membrane potential\n", + " t_dAP ms = 0 ms # dendritic action potential timer\n", + " I_dAP pA = 0 pA # dendritic action potential current magnitude\n", + " end\n", + "\n", + " equations:\n", + " # alpha shaped postsynaptic current kernel\n", + " kernel syn_kernel = (e / tau_syn) * t * exp(-t / tau_syn)\n", + " recordable inline I_syn pA = convolve(syn_kernel, spikes_in)\n", + " V_m' = -(V_m - E_L) / tau_m + (I_syn + I_dAP + I_e) / C_m\n", + " end\n", + "\n", + " parameters:\n", + " C_m pF = 250 pF # capacity of the membrane\n", + " tau_m ms = 20 ms # membrane time constant\n", + " tau_syn ms = 10 ms # time constant of synaptic current\n", + " V_th mV = 25 mV # action potential threshold\n", + " V_reset mV = 0 mV # reset voltage\n", + " I_e pA = 0 pA # external current\n", + " E_L mV = 0 mV # resting potential\n", + "\n", + " # dendritic action potential\n", + " I_th pA = 100 pA # current threshold for a dendritic action potential\n", + " I_dAP_peak pA = 150 pA # current clamp value for I_dAP during a dendritic action potential\n", + " T_dAP ms = 10 ms # time window over which the dendritic current clamp is active\n", + " end\n", + "\n", + " input:\n", + " spikes_in pA <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " update:\n", + " # solve ODEs\n", + " integrate_odes()\n", + "\n", + " if t_dAP > 0 ms:\n", + " t_dAP -= resolution()\n", + " if t_dAP <= 0 ms:\n", + " # end of dendritic action potential\n", + " t_dAP = 0 ms\n", + " I_dAP = 0 pA\n", + " end\n", + " end\n", + "\n", + " if I_syn > I_th:\n", + " # current-threshold, emit a dendritic action potential\n", + " t_dAP = T_dAP\n", + " I_dAP = I_dAP_peak\n", + " end\n", + "\n", + " # emit somatic action potential\n", + " if V_m > V_th:\n", + " emit_spike()\n", + " V_m = V_reset\n", + " end\n", + " end\n", + "end\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save to a temporary file and make the model available to instantiate in NEST (see [Running NESTML](https://nestml.readthedocs.io/en/latest/running.html)):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"iaf_psc_exp_active_dendrite.nestml\", \"w\") as nestml_model_file:\n", + " print(nestml_active_dend_model, file=nestml_model_file)\n", + "\n", + "generate_nest_target(input_path=\"iaf_psc_exp_active_dendrite.nestml\",\n", + " target_path=\"/tmp/nestml-active-dend-target\",\n", + " module_name=\"nestml_active_dend_module\",\n", + " suffix=\"_nestml\",\n", + " logging_level=\"ERROR\", # try \"INFO\" for more debug information\n", + " codegen_opts={\"nest_path\": NEST_SIMULATOR_INSTALL_LOCATION})\n", + "nest.Install(\"nestml_active_dend_module\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Running the simulation in NEST\n", + "\n", + "Let's define a function that will instantiate the active dendrite model, run a simulation, and plot and return the results." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def evaluate_neuron(neuron_name, neuron_parms=None, t_sim=100., plot=True):\n", + " \"\"\"\n", + " Run a simulation in NEST for the specified neuron. Inject a stepwise\n", + " current and plot the membrane potential dynamics and action potentials generated.\n", + " \n", + " Returns the number of postsynaptic action potentials that occurred.\n", + " \"\"\"\n", + " dt = .1 # [ms]\n", + "\n", + " nest.ResetKernel()\n", + " try:\n", + " nest.Install(\"nestml_active_dend_module\")\n", + " except :\n", + " pass\n", + " neuron = nest.Create(neuron_name)\n", + " if neuron_parms:\n", + " for k, v in neuron_parms.items():\n", + " nest.SetStatus(neuron, k, v)\n", + "\n", + " sg = nest.Create(\"spike_generator\", params={\"spike_times\": [10., 20., 30., 40., 50.]})\n", + " \n", + " multimeter = nest.Create(\"multimeter\")\n", + " record_from_vars = [\"V_m\", \"I_syn\", \"I_dAP\"]\n", + " if \"enable_I_syn\" in neuron.get().keys():\n", + " record_from_vars += [\"enable_I_syn\"]\n", + " multimeter.set({\"record_from\": record_from_vars,\n", + " \"interval\": dt})\n", + " sr_pre = nest.Create(\"spike_recorder\")\n", + " sr = nest.Create(\"spike_recorder\")\n", + "\n", + " nest.Connect(sg, neuron, syn_spec={\"weight\": 50., \"delay\": 1.})\n", + " nest.Connect(multimeter, neuron)\n", + " nest.Connect(sg, sr_pre)\n", + " nest.Connect(neuron, sr)\n", + " \n", + " nest.Simulate(t_sim)\n", + "\n", + " mm = nest.GetStatus(multimeter)[0]\n", + " timevec = mm.get(\"events\")[\"times\"]\n", + " I_syn_ts = mm.get(\"events\")[\"I_syn\"]\n", + " I_dAP_ts = mm.get(\"events\")[\"I_dAP\"]\n", + " ts_somatic_curr = I_syn_ts + I_dAP_ts\n", + " if \"enable_I_syn\" in mm.get(\"events\").keys():\n", + " enable_I_syn = mm.get(\"events\")[\"enable_I_syn\"]\n", + " ts_somatic_curr = enable_I_syn * I_syn_ts + I_dAP_ts\n", + "\n", + " ts_pre_sp = nest.GetStatus(sr_pre, keys='events')[0]['times']\n", + " ts_sp = nest.GetStatus(sr, keys='events')[0]['times']\n", + " n_post_spikes = len(ts_sp)\n", + " \n", + " if plot:\n", + " n_subplots = 3\n", + " n_ticks = 4\n", + " if \"enable_I_syn\" in mm.get(\"events\").keys():\n", + " n_subplots += 1\n", + " fig, ax = plt.subplots(n_subplots, 1, dpi=100)\n", + " ax[0].scatter(ts_pre_sp, np.zeros_like(ts_pre_sp), marker=\"d\", c=\"orange\", alpha=.8, zorder=99)\n", + " ax[0].plot(timevec, I_syn_ts, label=r\"I_syn\")\n", + " ax[0].set_ylabel(\"I_syn [pA]\")\n", + " ax[0].set_ylim(0, np.round(1.1*np.amax(I_syn_ts)/50)*50)\n", + " ax[0].yaxis.set_major_locator(mpl.ticker.LinearLocator(n_ticks))\n", + " twin_ax = ax[0].twinx()\n", + " twin_ax.plot(timevec, I_dAP_ts, linestyle=\"--\", label=r\"I_dAP\")\n", + " twin_ax.set_ylabel(\"I_dAP [pA]\")\n", + " twin_ax.set_ylim(0, max(3, np.round(1.1*np.amax(I_dAP_ts)/50)*50))\n", + " twin_ax.legend(loc=\"upper right\")\n", + " twin_ax.yaxis.set_major_locator(mpl.ticker.LinearLocator(n_ticks))\n", + " ax[-2].plot(timevec, ts_somatic_curr, label=\"total somatic\\ncurrent\")\n", + " ax[-2].set_ylabel(\"[pA]\")\n", + " if \"enable_I_syn\" in mm.get(\"events\").keys():\n", + " ax[1].plot(timevec, enable_I_syn, label=\"enable_I_syn\")\n", + " ax[1].set_ylim([-.05, 1.05])\n", + " ax[1].set_yticks([0, 1])\n", + " ax[-1].plot(timevec, mm.get(\"events\")[\"V_m\"], label=\"V_m\")\n", + " ax[-1].scatter(ts_sp, np.zeros_like(ts_sp), marker=\"d\", c=\"olivedrab\", alpha=.8, zorder=99)\n", + " ax[-1].set_ylabel(\"V_m [mV]\")\n", + " ax[-1].set_xlabel(\"Time [ms]\")\n", + " for _ax in set(ax) | set([twin_ax]):\n", + " _ax.grid()\n", + " if not _ax == twin_ax: _ax.legend(loc=\"upper left\")\n", + " if not _ax == ax[-1]: _ax.set_xticklabels([])\n", + " for _loc in ['top', 'right', 'bottom', 'left']: _ax.spines[_loc].set_visible(False) # hide axis outline\n", + " for o in fig.findobj(): o.set_clip_on(False) # disable clipping\n", + " fig.show()\n", + "\n", + " return n_post_spikes" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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fNtxRvXowvDucX55HYrSXtRtRUFo9uzZrF69mhdffBEhBEIIsrOzAVi9ejWnnXYaYWFhpKWl8ac//Qmbzdbsfna7nblz55KRkYHRaKR///68+OKLLarT4cOHueiii+jSpQuRkZEMHjyYpUuXup9vrl6g9ZzdeeedPPjggyQkJJCSksLrr79OVVUVc+bMITo6mj59+vD111+79zlVvefNm8fbb7/NkiVL3K931apVZGdnI4Rg69at7rI7d+7kwgsvJCYmhujoaCZNmsTBgwdb1AYNuXqoVECldDSxRgMjusdx6ah07p7ejxeuHsmnt01k0yPT+fXxc1l65yT+c+1oUmK0NA1VZtspjqgoHZ/qoQpCL774Ivv27WPIkCE88cQTACQlJXHs2DFmzJjB7Nmzeeedd9izZw8333wz4eHhzJs3r8n9HA4H6enpfPTRRyQkJPDzzz/zu9/9jrS0NK688kqP6nT77bdjsVhYs2YNkZGR7Nq1i6ioKIBT1svlnXfe4c4772TdunV89NFH3HrrrXz66adccsklPPTQQzz//PNcd911HDlyhIiIiFPW+95772X37t2Ul5ezcOFCAOLj4zl+/Hi9uh87dozJkyczdepUvv/+e2JiYvjpp5/qBXyt4VrDV8VTSjCJCgthkHN5ohdW7CO/3Ewj61UrStBRAVUQio2NJTQ0lIiIiHpDV//+97/p3r07L7/8MkIIBgwYwPHjx3nggQd47LHHmtxPr9fz+OOPux9nZGSwdu1a/ve//3kcUB05coTLLruMoUOHAtC7d2+P6+XKij58+HDuvfdeYmJiePDBB/nHP/5BYmIiN998MwCPPfYYr7zyCtu3b2f8+PEYDIZm6x0VFYXRaMRsNjc7xDd//nxiY2P54IMP3Mkv+/Xr59Hrbo5UPVRKkHPdbFE3RYiiBCs15NeJ7N69mwkTJtS7o2zixIlUVlZy9OjRZvedP38+o0ePJikpiaioKF577TWOHDni8bnvvPNOnnzySSZOnMif//xntm/f3uJ6uYIx0IK8hISEettSUrR5Hq619LxRb4CtW7cyadIkr2cSl6qHSglyrnnoKqBSOoOACqiEEH8SQkghxAt1toULIeYLIYqEEJVCiE+EECkN9ushhPhKCFEthCgQQjwthFC9b17ywQcfcO+99zJ37ly+/fZbtm7dypw5c7BYLB4f46abbuLQoUNcd9117NixgzFjxvDSSy+1qB4NAxohRL1t7m/DDofX6g216/N5m5pDpQQ713tbxVNKZxAwAZUQYizwe2B7g6eeBy4CrgCmAF2BxXX20wNfAaHA6cANwGzgCZ9XOoCFhoZit9vrbRs4cCBr1651DzUB/PTTT0RHR5Oent7kfj/99BOnn346t912GyNHjqRPnz6tmpDdvXt3brnlFhYvXsw999zD66+/7nG9WsOTejf2ehsaNmwYP/zwg3tdR29Rc6iUYOfqoZKoiEoJfgERUAkhooD3gJuBkjrbY4G5wN1Syu+llJuBOcDpQojxzmLnAIOAa6WUW6WUXwOPArcLITrtAlW9evVi/fr1ZGdnU1hYiMPh4LbbbiMnJ4c//OEP7NmzhyVLlvDnP/+Zu+++2z1PqbH9+vbty6ZNm1i2bBn79u3j0UcfZePGjS2qz1133cWyZcvIysril19+YeXKlQwcOBDAo3q1hif17tWrF9u3b2fv3r0UFhY2GjTdcccdlJeXc/XVV7Np0yb279/Pu+++y969e1tdN1A9VEon4O419nM9FKUdBMqw2HzgKynlCiHEI3W2jwYMwArXBinlHiHEEWACsM75e4eUMr/OfsuAV4DBwJaGJxNChAHuZdcjIyPJy8sjLOzklditVitSShwOh3soyROu3hbXvu3t7rvvZs6cOQwaNIiamhoOHjxIr169+PLLL3nggQcYPnw48fHx3HjjjTz00EPuOja2380338wvv/zCVVddhRCCq6++mltvvZVvvvnGvZ+UstnXarPZuP322zl69CgxMTGce+65PPfcczgcDtLS0k5Zr7rqnqexc7r+rzyp99y5c1m5ciVjxoyhsrKS7777jl69etU7TpcuXVixYgX3338/U6ZMQa/XM2LECCZMmNBo/RwOB1JKrFYrer2+yf8jq1W7S1CA13u/POU6r7/OH6xUu2qEs2fKarO1uS1Um/qGt9p16dKlMUDFzJkzO213pJB+HtwWQlwNPAyMlVKahBCrgK1SyruEELOAhVLKsAb7bABWSikfEEK8BvSUUp5b5/kIoAqY4eyxanjOecCf62676qqruOaaa06qX0hICKmpqXTv3p3Q0E7b4aW0gMViIScnh7y8vGZTK+RVw9+3hRAZIvnb2OaHHRWlI3rhVz1ZFYIb+9kZntBpr7OdSezMmTNPXqeo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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "n_post_sp = evaluate_neuron(\"iaf_psc_exp_active_dendrite_nestml\", neuron_parms={\"I_th\": 100., \"I_dAP_peak\": 400.})\n", + "assert n_post_sp == 2 # check for correctness of the result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the top panel, we can see the synaptic and dAP currents separately. Incoming action potentials from the presynaptic partner, triggering postsynaptic currents, are indicated by orange diamonds . The middle panel shows the total synaptic current, which is equal to the sum of synaptic and dendritic action potential current. The bottom panel shows the resulting postsynaptic membrane potential, and postsynaptic (somatic) action potentials using green diamonds .\n", + "\n", + "The presynaptic action potentials by themselves are not sufficient by themselves to trigger a postsynaptic action potential, which can be seen by setting the dAP threshold to a very high value, preventing it from triggering. No postsynaptic spikes are observed." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "n_post_sp = evaluate_neuron(\"iaf_psc_exp_active_dendrite_nestml\", neuron_parms={\"I_th\": 9999.})\n", + "assert n_post_sp == 0 # check for correctness of the result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dynamically controlling synaptic integration\n", + "\n", + "\n", + "We now add the additional requirement for the dendritic action potential to disable synaptic integration. When a dendritic action potential happens, we want to ignore synaptic currents for the duration of the action potential, and to reset the synaptic currents such that any presynaptic activity before the dendritic action potential is ignored.\n", + "\n", + "To do this, we add a state variable ``enable_I_syn``, that will have the value 1 if synaptic current integration is enabled, and 0 in case it is disabled. This variables multiplies the ``I_syn`` term in the differential equation for $V_m$. The new governing equation is then:\n", + "\n", + "\\begin{align}\n", + "\\frac{dV_m}{dt} &= -\\frac{1}{\\tau_m} (V_m - E_L) + \\frac{1}{C_m} (\\mathtt{enable\\_I\\_syn} \\cdot I_{syn} + I_{dAP})\n", + "\\end{align}\n", + "\n", + "We can then temporarily disable the synaptic current from contributing to the update of ``V_m`` by setting ``enable_I_syn`` to zero, for instance:\n", + "\n", + "```nestml\n", + "update:\n", + " if I_syn > I_th:\n", + " # current-threshold, emit a dendritic action potential\n", + " ...\n", + " # temporarily pause synaptic integration\n", + " enable_I_syn = 0.\n", + " ...\n", + "```\n", + "\n", + "In order to ignore presynaptic input that arrives during and before a dendritic action potential, we use the inline aliasing feature of NESTML. Usually, synaptic integration is expressed as a convolution, for example:\n", + "\n", + "```nestml\n", + "equations:\n", + " kernel syn_kernel = exp(-t / tau_syn)\n", + "\n", + " V_m' = -(V_m - E_L) / tau_m + convolve(syn_kernel, in_spikes) / C_m\n", + " ...\n", + "```\n", + "\n", + "We will define an inline expression that aliases this convolution (see https://nestml.readthedocs.io/en/latest/nestml_language.html#%28Re%29setting-synaptic-integration-state for a more detailed explanation):\n", + "\n", + "```nestml\n", + "equations:\n", + " inline I_syn pA = convolve(syn_kernel, in_spikes)\n", + " ...\n", + "```\n", + "\n", + "Now, we can not only use the variable ``I_syn`` in expressions, but we can also assign to it. To reset the state of synaptic integration (thereby \"forgetting\" any past action potential events):\n", + "\n", + "```nestml\n", + "update:\n", + " ...\n", + " if t_dAP <= 0 ms:\n", + " # end of dendritic action potential\n", + " ...\n", + " I_syn = 0 pA\n", + " I_syn' = 0 pA/ms\n", + " ...\n", + " end\n", + " end\n", + "\n", + "```\n", + "\n", + "Putting it all together in a new model, we have:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_active_dend_reset_model = '''\n", + "neuron iaf_psc_exp_active_dendrite_resetting:\n", + " state:\n", + " V_m mV = 0 mV # membrane potential\n", + " t_dAP ms = 0 ms # dendritic action potential timer\n", + " I_dAP pA = 0 pA # dendritic action potential current magnitude\n", + " enable_I_syn real = 1. # set to 1 to allow synaptic currents to\n", + " # contribute to V_m integration, 0 otherwise\n", + " end\n", + "\n", + " equations:\n", + " # alpha shaped postsynaptic current kernel\n", + " kernel syn_kernel = (e / tau_syn) * t * exp(-t / tau_syn)\n", + " recordable inline I_syn pA = convolve(syn_kernel, spikes_in)\n", + " V_m' = -(V_m - E_L) / tau_m + (enable_I_syn * I_syn + I_dAP + I_e) / C_m\n", + " end\n", + "\n", + " parameters:\n", + " C_m pF = 250 pF # capacity of the membrane\n", + " tau_m ms = 20 ms # membrane time constant\n", + " tau_syn ms = 10 ms # time constant of synaptic current\n", + " V_th mV = 25 mV # action potential threshold\n", + " V_reset mV = 0 mV # reset voltage\n", + " I_e pA = 0 pA # external current\n", + " E_L mV = 0 mV # resting potential\n", + "\n", + " # dendritic action potential\n", + " I_th pA = 100 pA # current-threshold for a dendritic action potential\n", + " I_dAP_peak pA = 150 pA # current clamp value for I_dAP during a dendritic action potential\n", + " T_dAP ms = 10 ms # time window over which the dendritic current clamp is active\n", + " end\n", + "\n", + " input:\n", + " spikes_in pA <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " update:\n", + " # solve ODEs\n", + " integrate_odes()\n", + "\n", + " if t_dAP > 0 ms:\n", + " t_dAP -= resolution()\n", + " if t_dAP <= 0 ms:\n", + " I_dAP = 0 pA\n", + " t_dAP = 0 ms\n", + " # reset and re-enable synaptic integration\n", + " I_syn = 0 pA\n", + " I_syn' = 0 pA/ms\n", + " enable_I_syn = 1.\n", + " end\n", + " end\n", + "\n", + " if I_syn > I_th:\n", + " # current-threshold, emit a dendritic action potential\n", + " t_dAP = T_dAP\n", + " I_dAP = I_dAP_peak\n", + " # temporarily pause synaptic integration\n", + " enable_I_syn = 0.\n", + " end\n", + "\n", + " # emit somatic action potential\n", + " if V_m > V_th:\n", + " emit_spike()\n", + " V_m = V_reset\n", + " end\n", + " end\n", + "end\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save to a temporary file and make the model available to instantiate in NEST (see [Running NESTML](https://nestml.readthedocs.io/en/latest/running.html)):" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "with open(\"iaf_psc_exp_active_dendrite.nestml\", \"w\") as nestml_model_file:\n", + " print(nestml_active_dend_reset_model, file=nestml_model_file)\n", + "\n", + "generate_nest_target(input_path=\"iaf_psc_exp_active_dendrite.nestml\",\n", + " target_path=\"/tmp/nestml-active-dend-target\",\n", + " module_name=\"nestml_active_dend_reset_module\",\n", + " suffix=\"_nestml\",\n", + " logging_level=\"ERROR\", # try \"INFO\" for more debug information\n", + " codegen_opts={\"nest_path\": NEST_SIMULATOR_INSTALL_LOCATION})\n", + "nest.Install(\"nestml_active_dend_reset_module\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we run the simulation with the same parameters as last time, we now observe only one instead of two action potentials, because the synaptic current (shown as ``I_syn`` in the top subplot below) does not contribute to ``V_m`` during the dendritic action potential interval." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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hST2FP7OXnGXn3frIURLkIBKCC+pvMZIRCX8k8yhEoFEAqpG0lpTbCl36VFisblc1pVHYycv2+12nn32Wbp06UJ4eDiDBg3iv//9LwCLFi1CKcXPP//M8OHDiYiIYNSoUWzfvr3i/bt372bSpEm0a9eOqKgoTjrpJBYsWHDCcQoKCrjiiiuIjIwkNTWVmTNn1luv9PR0LrvsMuLi4oiPj2fSpEns27evUb+bKxYtWsTJJ59MZGQkcXFxjB49mv3797Nv3z5MJhOrVq2qVv7VV1+lU6dO2O12l9qnuaSHSvg7uctPBBK/yEPVkkqsNvo+/qNXjr1l+tlEhLj+X/bss8/y8ccf889//pMePXqwePFirr76ahITEyvKPPLII7z00kskJiZyyy23cN1117F06VIACgsLmThxIn//+98JDQ3lww8/5IILLmD79u107NixYh8vvvgiDz/8MNOmTePHH3/krrvuomfPnkyYMOGEOlmtVs4++2xGjhzJkiVLCAoK4umnn+acc85hw4YNhISENKOFKpWXl3PhhRdy44038umnn2KxWFixYgVKKTp16sSZZ57JrFmzGD58eMV7Zs2axZQpU6olDa2vfZpLyRwq4ed0RQ+VBFTC/0lA5afKysp45plnWLBgASNHjgSga9eu/Pbbb/zrX//ipptuAuDvf/87Y8eOBeDBBx/kvPPOo7S0lLCwMAYNGsSgQYMq9vnUU0/x1Vdf8c0333D77bdXbB89ejQPPvggAD179mTp0qW88sortQZUc+bMwW63884771RMVJ01axZxcXEsWrSIs846yy2/f35+Pnl5eZx//vl069YNgD59+lS8fsMNN3DLLbfw8ssvExoaypo1a9i4cSNz586ttp/62qe5pIdK+DtJ7CkCiQRUjRQebGbL9LMbLGe32ynILyA6Jtpty6SEBzecfdtp165dFBcXnxDUWCwWhgwZUvF84MCBFf92rkGXnZ1Nx44dKSws5Mknn+S7774jMzOT8vJySkpKOHCg+vKIzoCt6vO67vxbv349u3btIjo6utr20tJSdu/e7fLv15D4+HimTJnC2WefzYQJEzjzzDO57LLLKn7HCy+8kKlTp/LVV19x+eWX8/777zN+/Hg6d+5cbT/1tU9zOT8WkodK+CtZHFkEEgmoGkkp5dKwm91upzzETERIkFfWnSssLATgu+++IzU1tdproaGhFcFLcHBwxfbKvEhGYqT77ruP+fPn849//IPu3bsTHh7OpZdeisViaVa9hg0bxieffHLCa1WHIt1h1qxZ3Hnnnfzwww/MmTOHRx99lPnz53PKKacQEhLCNddcw6xZs7j44ouZPXs2r7322gn7qK99mst5kZF4Svirih4qL9dDiJYgAZWf6tu3L6GhoRw4cKBiyKoqV3qDli5dypQpU7jooosAIxiqbfL4H3/8ccLzqsNrVQ0dOpQ5c+aQlJRETEyMC79J8wwZMoQhQ4bw0EMPMXLkSGbPns0pp5wCGMN+/fv3580336S8vJyLL77Y4/WpqnJxZImohH+qSOwpt/mJACB3+fmp6Oho7rvvPu655x4++OADdu/ezZo1a3jjjTf44IMPXNpHjx49+PLLL1m3bh3r16/nyiuvrLV3ZunSpbzwwgvs2LGDmTNn8vnnn3PXXXfVus+rrrqKtm3bMmnSJJYsWcLevXtZtGgRd955JwcPHmzW71zV3r17eeihh1i2bBn79+/np59+YufOndUCvT59+nDKKafwwAMPcMUVVxAeHu6247vCeYmRgEr4Ky1zqEQAkR4qP/bUU0+RmJjIs88+y549e4iLi2Po0KE8/PDDLg1bvfzyy1x33XWMGjWKtm3b8sADD5Cfn39CuXvvvZdVq1Yxbdo0YmJiePnllzn77NrnmUVERLB48WIeeOABLr74YgoKCkhNTeWMM85wa49VREQE27Zt44MPPuDYsWOkpKQwdepUbr755mrlrr/+en7//Xeuu+46tx3bVTIpXfg7mUMlAokEVH5MKcVdd91VZ29RzcnQgwcPrratc+fO/PLLL9XKTJ06tdpzV/JH1TxOcnKyy71kNT344IM888wzDZZr164dX331VYPlMjIyGDBgACeddFK17ePGjWuwfZrLOQoik9KFv5LEniKQyJCfCEiFhYVs2rSJGTNmcMcdd3ilDkp6qISfc35XUDItXQQACaiET4mKiqrzsWTJkiaXren2229n2LBhjBs3zivDfSA9VML/SQ+VCCQy5Cd8yrp16+p8LSUlBavV6lLZmqkianr//fd5//33G1k795I5VMLfVSb2lIhK+D8JqIRP6d69e52v2e32agFVfWVbAyU9VMLPaZmULgKIDPm5SC56oiGN/YxID5Xwd5V3+Xm3HkK0BAmoGuDMlF1c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/DZrtVrRWmO327E34v5n57wJ53tb0p/+9CesVivff//9Ca8tWbKEcePGsXbtWgYObMp61o1jt9vRWrtlDpVzPpurucBEw3y5TfNLrPy87QjzNmWxdPexakFUz6QozuqbxJl9kuibEl1laNmO1er9PAVWq7VyyM9u98n2bW18+bPamrmrXefNmxcDFEyaNClgv0Iod06YVEpdDHyjtS53206r798EfAPEaa1PdWy7EpiltQ6tUXYFsFBr/UAt+3kSeKLqtsmTJ3PFFVeccMygoCCSk5NJS0sjJCTEbb+LJ3333Xdcc801bNiwgdTU1Gqv3X777WzZsoVffvmlRepisVhIT08nKyuL8nKPfCyEH7HaYXOOYuURxdZchU1XzsFLCdcMTrAzOEGT3AruEdmSo/jXNjNpkZr7BgZmcl8RcGInTZqU33Ax/+TuPFRfVn2ulEoCkgBTjXIbmniImUB/4NQmvt/pWeBl55PIyEjeeeedvNp6qEpLS0lPTycqKoqwsDCXD6C1pqCggOjo6BafmP3nP/+Ze++9ly+//JJHHnmkYnthYSFz587l+eefJyYmps73L1q0iDPOOIN58+bx8MMPs23bNkaOHMns2bNZvXo19913HxkZGZx33nm8/fbb9d4BWVpaSnh4OGPGjGlU+9XGarUyf/58JkyYQHBwcLP2JQy+0KZaa1YfyOXrdZl8vymL/NLKwLtHUiTn9k/m3H7t6J4U5ZX6NYXVamXr50aneXRMDBMnjvRyjVo/X/is+iN3teu8efNigQL31az18cikdKXUMOADoA9V7h52/FsDjR77UUrNAM4HxmitD1Z5KQsIUUrF1ViYuZ3jtRNorcuAstpeq8lms6GUwmQyYTKZ0FpTYm3426bdbqfEYiPIanNbHqrwYLNLwVlISAjXXHMNH3zwAY8++mjFe7744gtsNhtXXXVVvXVyvjZ9+nRmzJhBREQEl112GZdffjmhoaHMnj2bwsJCLrroImbOnMkDD5zQCVhtX0opgoOD3XYSdOe+hMEbbbrvaBFfrs3g67UZHDheXLG9fWwYk4akctGQVHq2i27ROrlT5YlPyefVjeTv3zOa266B3DPl5Km7/N4DdmBMFj9MM3LbKSMaeAO4CBintd5bo8hqwAqcAXzheE8voCOwrKnHrUuJ1Ubfx390925dsmX62USEuPZfdt111/Hi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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "n_post_sp = evaluate_neuron(\"iaf_psc_exp_active_dendrite_resetting_nestml\",\n", + " neuron_parms={\"I_th\": 100., \"I_dAP_peak\": 400.})\n", + "assert n_post_sp == 1 # check for correctness of the result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Acknowledgements\n", + "\n", + "We extend our gratitude to Younes Bouhadjar and Tom Tetzlaff for their contributions.\n", + "\n", + "This software was developed in part or in whole in the Human Brain Project, funded from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under Specific Grant Agreements No. 720270 and No. 785907 (Human Brain Project SGA1 and SGA2).\n", + "\n", + "\n", + "## References\n", + "\n", + "Jahnke, S., Timme, M. & Memmesheimer, R. M. (2012). Guiding synchrony through random networks. Physical Review X, 2(4), 041016. https://doi.org/10.1103/PhysRevX.2.041016\n", + "\n", + "Memmesheimer, R. M. & Timme, M. (2012). Non-additive coupling enables propagation of synchronous spiking activity in purely random networks. PLoS Comput Biol, 8(4), e1002384. https://doi.org/10.1371/journal.pcbi.1002384\n", + "\n", + "Antic, S.D. Zhou, W.-L., Moore, A.R., Short, S.M., & Ikonomu, K.D. (2010). The Decade of the Dendritic NMDA Spike. J Neurosci Res. Nov 1, 88(14). https://doi.org/10.1002/jnr.22444\n", + "\n", + "\n", + "## Copyright\n", + "\n", + "This file is part of NEST.\n", + "\n", + "Copyright (C) 2004 The NEST Initiative\n", + "\n", + "NEST is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.\n", + "\n", + "NEST is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n", + "\n", + "You should have received a copy of the GNU General Public License along with NEST. If not, see .\n" + ] + } + ], + "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.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/doc/tutorials/index.rst b/doc/tutorials/index.rst new file mode 100644 index 000000000..c1cdfaa2b --- /dev/null +++ b/doc/tutorials/index.rst @@ -0,0 +1,5 @@ +Tutorials +========= + +.. include:: tutorials_list.rst + diff --git a/doc/tutorial/izhikevich_solution.nestml b/doc/tutorials/izhikevich/izhikevich_solution.nestml similarity index 94% rename from doc/tutorial/izhikevich_solution.nestml rename to doc/tutorials/izhikevich/izhikevich_solution.nestml index 9a291eba3..b44103549 100644 --- a/doc/tutorial/izhikevich_solution.nestml +++ b/doc/tutorials/izhikevich/izhikevich_solution.nestml @@ -1,6 +1,6 @@ neuron izhikevich_tutorial: - initial_values: + state: v mV = -65 mV # Membrane potential in mV u real = 0 # Membrane potential recovery variable end @@ -19,7 +19,7 @@ neuron izhikevich_tutorial: input: spikes mV <- spike - I_e pA <- current + I_e pA <- continuous end output: spike diff --git a/doc/tutorial/izhikevich_task.nestml b/doc/tutorials/izhikevich/izhikevich_task.nestml similarity index 95% rename from doc/tutorial/izhikevich_task.nestml rename to doc/tutorials/izhikevich/izhikevich_task.nestml index b80070eb9..e928b8bb7 100644 --- a/doc/tutorial/izhikevich_task.nestml +++ b/doc/tutorials/izhikevich/izhikevich_task.nestml @@ -1,6 +1,6 @@ neuron izhikevich_tutorial: - initial_values: + state: v mV = -65 mV # Membrane potential in mV # TODO: add new variable u with the type real @@ -19,7 +19,7 @@ neuron izhikevich_tutorial: input: spikes mV <- spike - I_e pA <- current + I_e pA <- continuous end output: spike diff --git a/doc/tutorials/izhikevich/nestml_izhikevich_tutorial.ipynb b/doc/tutorials/izhikevich/nestml_izhikevich_tutorial.ipynb new file mode 100644 index 000000000..6e4fa91af --- /dev/null +++ b/doc/tutorials/izhikevich/nestml_izhikevich_tutorial.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NESTML Izhikevich tutorial\n", + "\n", + "Introduction\n", + "------------\n", + "\n", + "The aim of this exercise is to obtain familiarity with NESTML by completing a partial model of the Izhikevich neuron [1].\n", + "\n", + "\n", + "Prerequisites\n", + "-------------\n", + "\n", + "You need to have a working NEST Simulator and NESTML installation, see [Installing NESTML](https://nestml.readthedocs.io/en/latest/installation.html).\n", + "\n", + "You need to be able to run NESTML to generate and build model code. NESTML can be used from the command line, and via a Python API. The latter will be used in this notebook. See [Running NESTML](https://nestml.readthedocs.io/en/latest/running.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import nest\n", + "import numpy as np\n", + "import os\n", + "\n", + "from pynestml.frontend.pynestml_frontend import generate_nest_target\n", + "\n", + "NEST_SIMULATOR_INSTALL_LOCATION = nest.ll_api.sli_func(\"statusdict/prefix ::\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Paths\n", + "\n", + "We assume here that we will generate code in a temporary directory `/tmp/nestml-component`. You can also create a unique temporary path using the [Python tempfile module](https://docs.python.org/3/library/tempfile.html).\n", + "\n", + "\n", + "The Izhikevich model\n", + "--------------------\n", + "\n", + "A simple model for spiking neurons that nevertheless can exhibit a wide variety of dynamical behaviour, depending on its parameter values [1]. It is defined as follows:\n", + "\n", + "\\begin{align}\n", + "\\frac{dv}{dt} &= 0.04 v^2 + 5 v + 140 - u + I\\\\\n", + "\\frac{du}{dt} &= a (b v - u)\n", + "\\end{align}\n", + "\n", + "State update:\n", + "\n", + "\\begin{align}\n", + " &\\text{if}\\;\\; v \\geq V_{th}:\\\\\n", + " &\\;\\;\\;\\; v \\text{ is set to } c\\\\\n", + " &\\;\\;\\;\\; u \\text{ is incremented by } d\\\\\n", + " & \\, \\\\\n", + " &v \\text{ jumps on each spike arrival by the weight of the spike}\n", + "\\end{align}\n", + "\n", + "Example parameters for regular spiking (the meaning of these parameters is described in detail in the paper [1]; see also Task 2 below): \n", + "\n", + "\\begin{align}\n", + "a&=0.02\\\\\n", + "b&=0.2\\\\\n", + "c&=-65~\\text{mV}\\\\\n", + "d&=8\n", + "\\end{align}\n", + "\n", + "\n", + "Task 1: Finish the model\n", + "------------------------\n", + "\n", + "In the file [`izhikevich_task.nestml`](https://raw.githubusercontent.com/nest/nestml/master/doc/tutorials/izhikevich/izhikevich_task.nestml), only a subset of the parameters, state equations and update block is implemented.\n", + "\n", + "Open the file in a text editor and finish the partially-completed model.\n", + "\n", + "For reference, the solution is included as [`izhikevich_solution.nestml`](https://raw.githubusercontent.com/nest/nestml/master/doc/tutorials/izhikevich/izhikevich_solution.nestml)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### NESTML code generation\n", + "\n", + "Assume that our NESTML input model is at `izhikevich_solution.nestml`. To generate code and build a dynamic library that can be loaded as a user module in NEST Simulator:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "generate_nest_target(input_path=\"izhikevich_solution.nestml\",\n", + " target_path=\"/tmp/nestml-component\",\n", + " logging_level=\"ERROR\",\n", + " codegen_opts={\"nest_path\": NEST_SIMULATOR_INSTALL_LOCATION})\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check the generated log output for any potential error messages or warnings.\n", + "\n", + "The generated module is called ``nestmlmodule`` by default. It can be loaded using ``nest.Install()``:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "nest.Install(\"nestmlmodule\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Instantiate model in NEST Simulator and run\n", + "\n", + "Using the PyNEST API, the model can be instantiated and simulated in NEST. The following code will create one instance of the neuron model (`nest.Create(\"izhikevich_tutorial\")`), inject a constant current and run the simulation for 250 ms." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "nest.set_verbosity(\"M_WARNING\")\n", + "nest.ResetKernel()\n", + "\n", + "neuron = nest.Create(\"izhikevich_tutorial\")\n", + "voltmeter = nest.Create(\"voltmeter\")\n", + "\n", + "voltmeter.set({\"record_from\": [\"v\", \"u\"]})\n", + "nest.Connect(voltmeter, neuron)\n", + "\n", + "cgs = nest.Create('dc_generator')\n", + "cgs.set({\"amplitude\": 25.})\n", + "nest.Connect(cgs, neuron)\n", + "\n", + "sr = nest.Create(\"spike_recorder\")\n", + "nest.Connect(neuron, sr)\n", + "\n", + "nest.Simulate(250.)\n", + "\n", + "spike_times = nest.GetStatus(sr, keys='events')[0]['times']\n", + "\n", + "fig, ax = plt.subplots(nrows=2)\n", + "ax[0].plot(voltmeter.get(\"events\")[\"times\"], voltmeter.get(\"events\")[\"v\"])\n", + "ax[1].plot(voltmeter.get(\"events\")[\"times\"], voltmeter.get(\"events\")[\"u\"])\n", + "ax[0].scatter(spike_times, 30 * np.ones_like(spike_times), marker=\"d\", c=\"orange\", alpha=.8, zorder=99)\n", + "for _ax in ax:\n", + " _ax.grid(True)\n", + "ax[0].set_ylabel(\"v [mV]\")\n", + "ax[1].set_ylabel(\"u\")\n", + "ax[-1].set_xlabel(\"Time [ms]\")\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Task 2: Parameter space exploration\n", + "-----------------------------------\n", + "\n", + "Perform a parameter space exploration to reproduce the bottom eight panels from [1], figure 2." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References\n", + "\n", + "[1] Eugene M. Izhikevich, \"Simple Model of Spiking Neurons\", IEEE Transactions on Neural Networks, Vol. 14, No. 6, November 2003\n", + "\n", + "## Copyright\n", + "\n", + "This file is part of NEST.\n", + "\n", + "Copyright (C) 2004 The NEST Initiative\n", + "\n", + "NEST is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.\n", + "\n", + "NEST is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n", + "\n", + "You should have received a copy of the GNU General Public License along with NEST. If not, see .\n" + ] + } + ], + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/doc/tutorials/ornstein_uhlenbeck_noise/nestml_ou_noise_tutorial.ipynb b/doc/tutorials/ornstein_uhlenbeck_noise/nestml_ou_noise_tutorial.ipynb new file mode 100644 index 000000000..d2741db1b --- /dev/null +++ b/doc/tutorials/ornstein_uhlenbeck_noise/nestml_ou_noise_tutorial.ipynb @@ -0,0 +1,790 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NESTML Ornstein-Uhlenbeck noise tutorial\n", + "\n", + "In this tutorial, we will formulate the Ornstein-Uhlenbeck (O-U) noise process in NESTML and simulate it in NEST Simulator." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import nest\n", + "import numpy as np\n", + "import os\n", + "from pynestml.frontend.pynestml_frontend import generate_nest_target\n", + "\n", + "NEST_SIMULATOR_INSTALL_LOCATION = nest.ll_api.sli_func(\"statusdict/prefix ::\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Ornstein-Uhlenbeck process\n", + "\n", + "The Ornstein-Uhlenbeck process is often used as a source of noise because it is well understood and has convenient properties (it is a Gaussian process, has the Markov property, and is stationary). Let the O-U process, denoted $U(t)$ (with $t\\geq 0$) , be defined as the solution of the following stochastic differential equation:\n", + "\n", + "\\begin{align}\n", + "\\frac{dU}{dt} = \\frac{\\mu - U}{\\tau} + \\sigma\\sqrt{\\frac 2 \\tau} \\frac{dB(t)}{dt}\n", + "\\end{align}\n", + "\n", + "The first right-hand side term is a \"drift\" term which is deterministic and slowly reverts $U_t$ to the mean $\\mu$, with time constant $\\tau$. The second term is stochastic as $B(t)$ is the Brownian motion (also \"Wiener\") process, and $\\sigma>0$ is the standard deviation of the noise.\n", + "\n", + "It turns out that the infinitesimal step in Brownian motion is white noise, that is, an independent and identically distributed sequence of Gaussian $\\mathcal{N}(0, 1)$ random variables. The noise $dB(t)/dt$ can be sampled at time $t$ by drawing a sample from that Gaussian distribution, so if the process is sampled at discrete intervals of length $h$, we can write (equation 2.47 from [\\[1\\]](#References)):\n", + "\n", + "\\begin{align}\n", + "U(t + h) = (U(t) - \\mu)\\exp(-h/\\tau) + \\sigma\\sqrt{(1 - \\exp(-2h / \\tau ))} \\cdot\\mathcal{N}(0, 1)\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simulating the Ornstein-Uhlenbeck process with NESTML\n", + "\n", + "### Formulating the model in NESTML\n", + "\n", + "The O-U process is now defined as a stepwise update equation, that is carried out at each timestep. All statements contained in the NESTML ``update`` block are run at every timestep, so this is a natural place to place the O-U updates.\n", + "\n", + "Updating the O-U process state requires knowledge about how much time has elapsed. As we will update the process once every simulation timestep, we pass this value by invoking the ``resolution()`` function." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_ou_model = '''\n", + "neuron ornstein_uhlenbeck_noise:\n", + "\n", + "parameters:\n", + " mean_noise real = 500 # mean of the noise\n", + " sigma_noise real = 50 # std. dev. of the noise\n", + " tau_noise ms = 20 ms # time constant of the noise\n", + "end\n", + "\n", + "internals:\n", + " A_noise real = sigma_noise * ((1 - exp(-2 * resolution() / tau_noise)))**.5\n", + "end\n", + "\n", + "state:\n", + " U real = mean_noise # set the initial condition\n", + "end\n", + "\n", + "update:\n", + " U = mean_noise \\\n", + " + (U - mean_noise) * exp(-resolution() / tau_noise) \\\n", + " + A_noise * random_normal(0, 1)\n", + "end\n", + "\n", + "end\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save to a temporary file and make the model available to instantiate in NEST:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + ], + "source": [ + "with open(\"ornstein_uhlenbeck_noise.nestml\", \"w\") as nestml_model_file:\n", + " print(nestml_ou_model, file=nestml_model_file)\n", + "\n", + "generate_nest_target(input_path=\"ornstein_uhlenbeck_noise.nestml\",\n", + " target_path=\"/tmp/nestml-ou-noise-target\",\n", + " module_name=\"nestml_ou_module\",\n", + " suffix=\"_nestml\",\n", + " logging_level=\"ERROR\",\n", + " codegen_opts={\"nest_path\": NEST_SIMULATOR_INSTALL_LOCATION})\n", + "nest.Install(\"nestml_ou_module\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Running the simulation in NEST\n", + "\n", + "Let's define a function that will instantiate and set parameters for the O-U model, run a simulation, and plot and return the results." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def evaluate_ou_process(h: float=.1, t_sim:float=100., neuron_parms=None, title=None, plot=True):\n", + " \"\"\"\n", + " h : float\n", + " timestep in ms\n", + " t_sim : float\n", + " total simulation time in ms\n", + " \"\"\"\n", + " nest.ResetKernel()\n", + " nest.SetKernelStatus({\"resolution\": h})\n", + " neuron = nest.Create(\"ornstein_uhlenbeck_noise_nestml\")\n", + "\n", + " if neuron_parms:\n", + " for k, v in neuron_parms.items():\n", + " nest.SetStatus(neuron, k, v)\n", + " \n", + " multimeter = nest.Create(\"multimeter\")\n", + " multimeter.set({\"record_from\": [\"U\"],\n", + " \"interval\": h})\n", + " nest.Connect(multimeter, neuron)\n", + " \n", + " nest.Simulate(t_sim)\n", + "\n", + " dmm = nest.GetStatus(multimeter)[0]\n", + " U = dmm[\"events\"][\"U\"]\n", + " timevec = dmm[\"events\"][\"times\"]\n", + " \n", + " if plot:\n", + " fig, ax = plt.subplots(figsize=(12., 5.))\n", + " if title is not None:\n", + " fig.suptitle(title)\n", + " ax.plot(timevec, U)\n", + " ax.set_xlabel(\"Time [ms]\")\n", + " ax.set_ylabel(\"U\")\n", + " ax.set_xlim(0., t_sim)\n", + " ax.grid()\n", + " \n", + " return timevec, U" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then, we can run the process. Hint: play with the parameters a bit here and see the effects it has on the returned timeseries." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "timevec, U = evaluate_ou_process(h=1.,\n", + " t_sim=1000.,\n", + " neuron_parms={\"U\" : -2500.,\n", + " \"mean_noise\": -3333.,\n", + " \"tau_noise\": 20.,\n", + " \"sigma_noise\": 100.},\n", + " title=r\"Ornstein-Uhlenbeck process\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Correctness test based on predicting variance\n", + "\n", + "Assuming that the initial value of the process is picked equal to the process mean, we can predict the variance of the timeseries as ([\\[1\\]](#References), eq. 2.26):\n", + " \n", + "\\begin{align}\n", + "\\text{Var}(U) = \\sigma^2\n", + "\\end{align}\n", + "\n", + "We now run a consistency check across parameters, to make sure that the prediction matches the result derived from the timeseries generated by sampling the process." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "For h = 0.01, tau_noise = 10.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 0.01, tau_noise = 10.0, sigma_noise = 10.0\n", + "Actual variance: 106.76668007577253\n", + "Expected variance: 100.0\n", + "For h = 0.01, tau_noise = 10.0, sigma_noise = 100.0\n", + "Actual variance: 10676.66800757725\n", + "Expected variance: 10000.0\n", + "For h = 0.01, tau_noise = 10.0, sigma_noise = 1000.0\n", + "Actual variance: 1067666.8007577253\n", + "Expected variance: 1000000.0\n", + "For h = 0.01, tau_noise = 100.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 0.01, tau_noise = 100.0, sigma_noise = 10.0\n", + "Actual variance: 113.21667422685765\n", + "Expected variance: 100.0\n", + "For h = 0.01, tau_noise = 100.0, sigma_noise = 100.0\n", + "Actual variance: 11321.667422685767\n", + "Expected variance: 10000.0\n", + "For h = 0.01, tau_noise = 100.0, sigma_noise = 1000.0\n", + "Actual variance: 1132166.7422685784\n", + "Expected variance: 1000000.0\n", + "For h = 0.01, tau_noise = 1000.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 0.01, tau_noise = 1000.0, sigma_noise = 10.0\n", + "Actual variance: 74.73990623130236\n", + "Expected variance: 100.0\n", + "For h = 0.01, tau_noise = 1000.0, sigma_noise = 100.0\n", + "Actual variance: 7473.990623130268\n", + "Expected variance: 10000.0\n", + "For h = 0.01, tau_noise = 1000.0, sigma_noise = 1000.0\n", + "Actual variance: 747399.0623130301\n", + "Expected variance: 1000000.0\n", + "For h = 0.1, tau_noise = 10.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 0.1, tau_noise = 10.0, sigma_noise = 10.0\n", + "Actual variance: 97.00510550205651\n", + "Expected variance: 100.0\n", + "For h = 0.1, tau_noise = 10.0, sigma_noise = 100.0\n", + "Actual variance: 9700.51055020565\n", + "Expected variance: 10000.0\n", + "For h = 0.1, tau_noise = 10.0, sigma_noise = 1000.0\n", + "Actual variance: 970051.0550205648\n", + "Expected variance: 1000000.0\n", + "For h = 0.1, tau_noise = 100.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 0.1, tau_noise = 100.0, sigma_noise = 10.0\n", + "Actual variance: 110.2600214635856\n", + "Expected variance: 100.0\n", + "For h = 0.1, tau_noise = 100.0, sigma_noise = 100.0\n", + "Actual variance: 11026.002146358567\n", + "Expected variance: 10000.0\n", + "For h = 0.1, tau_noise = 100.0, sigma_noise = 1000.0\n", + "Actual variance: 1102600.2146358567\n", + "Expected variance: 1000000.0\n", + "For h = 0.1, tau_noise = 1000.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 0.1, tau_noise = 1000.0, sigma_noise = 10.0\n", + "Actual variance: 74.81594631061263\n", + "Expected variance: 100.0\n", + "For h = 0.1, tau_noise = 1000.0, sigma_noise = 100.0\n", + "Actual variance: 7481.594631061229\n", + "Expected variance: 10000.0\n", + "For h = 0.1, tau_noise = 1000.0, sigma_noise = 1000.0\n", + "Actual variance: 748159.4631061255\n", + "Expected variance: 1000000.0\n", + "For h = 1.0, tau_noise = 10.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 1.0, tau_noise = 10.0, sigma_noise = 10.0\n", + "Actual variance: 99.72039832007492\n", + "Expected variance: 100.0\n", + "For h = 1.0, tau_noise = 10.0, sigma_noise = 100.0\n", + "Actual variance: 9972.039832007491\n", + "Expected variance: 10000.0\n", + "For h = 1.0, tau_noise = 10.0, sigma_noise = 1000.0\n", + "Actual variance: 997203.983200749\n", + "Expected variance: 1000000.0\n", + "For h = 1.0, tau_noise = 100.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 1.0, tau_noise = 100.0, sigma_noise = 10.0\n", + "Actual variance: 97.8429827631681\n", + "Expected variance: 100.0\n", + "For h = 1.0, tau_noise = 100.0, sigma_noise = 100.0\n", + "Actual variance: 9784.298276316811\n", + "Expected variance: 10000.0\n", + "For h = 1.0, tau_noise = 100.0, sigma_noise = 1000.0\n", + "Actual variance: 978429.8276316813\n", + "Expected variance: 1000000.0\n", + "For h = 1.0, tau_noise = 1000.0, sigma_noise = 0.0\n", + "Actual variance: 0.0\n", + "Expected variance: 0.0\n", + "For h = 1.0, tau_noise = 1000.0, sigma_noise = 10.0\n", + "Actual variance: 96.09899911143707\n", + "Expected variance: 100.0\n", + "For h = 1.0, tau_noise = 1000.0, sigma_noise = 100.0\n", + "Actual variance: 9609.899911143682\n", + "Expected variance: 10000.0\n", + "For h = 1.0, tau_noise = 1000.0, sigma_noise = 1000.0\n", + "Actual variance: 960989.991114368\n", + "Expected variance: 1000000.0\n" + ] + } + ], + "source": [ + "h = [.01, .1, 1.]\n", + "tau_noise = [10., 100., 1000.]\n", + "sigma_noise = [0., 10., 100., 1000.]\n", + "\n", + "max_rel_error = .25 # yes, this is pretty terrible!\n", + " # Need a very long integration time (esp. for large tau)\n", + " # to get a tighter bound.\n", + "\n", + "for _h in h:\n", + " for _tau_noise in tau_noise:\n", + " for _sigma_noise in sigma_noise:\n", + " print(\"For h = \" + str(_h) + \", tau_noise = \" + str(_tau_noise) + \", sigma_noise = \" + str(_sigma_noise))\n", + " c = (_sigma_noise * np.sqrt(2 / _tau_noise))**2\n", + " timevec, U = evaluate_ou_process(h=_h,\n", + " t_sim=25000.,\n", + " neuron_parms={\"U\" : 0.,\n", + " \"mean_noise\": 0.,\n", + " \"tau_noise\": _tau_noise,\n", + " \"sigma_noise\": _sigma_noise},\n", + " title=r\"Ornstein-Uhlenbeck process ($\\tau$=\" + str(_tau_noise) + \", $\\sigma$=\" + str(_sigma_noise) + \")\",\n", + " plot=False)\n", + " var_actual = np.var(U)\n", + " print(\"Actual variance: \" + str(var_actual))\n", + " var_expected = _sigma_noise**2\n", + " print(\"Expected variance: \" + str(var_expected))\n", + " if var_actual < 1E-15:\n", + " assert var_expected < 1E-15\n", + " else:\n", + " assert np.abs(var_expected - var_actual) / (var_expected + var_actual) < max_rel_error" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Autocorrelogram\n", + "\n", + "If we plot the autocorrelogram, we should find high correlations only for lags lower than $\\tau$.\n", + "\n", + "Let's look at a process with $\\tau=1000$:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "timevec, U = evaluate_ou_process(h=_h,\n", + " t_sim=10000.,\n", + " neuron_parms={\"U\" : 0.,\n", + " \"mean_noise\": 0.,\n", + " \"tau_noise\": 1000.,\n", + " \"sigma_noise\": 1000.},\n", + " title=r\"Ornstein-Uhlenbeck process ($\\tau$=1000, $\\sigma$=1000)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "def autocorr(x):\n", + " return np.correlate(x, x, mode='full')\n", + "\n", + "fig, ax = plt.subplots(figsize=(12., 5.))\n", + "U_autocorr = autocorr(U)\n", + "lags = np.arange(len(U_autocorr)) - len(U_autocorr) / 2\n", + "ax.plot(lags, U_autocorr)\n", + "ax.set_xlabel(\"Lag [ms]\")\n", + "ax.set_ylabel(\"Autocorr[U]\")\n", + "ax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Integrating Ornstein-Uhlenbeck noise into a NESTML integrate-and-fire neuron\n", + "\n", + "Now, the O-U noise process is integrated into an existing NESTML model, as an extra somatic current $I_{noise}$. In this example, we use the integrate-and-fire neuron with current based synapses and an exponentially shaped synaptic kernel, and no refractoriness mechanism.\n", + "\n", + "This neuron can be written in just a few lines of NESTML:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "iaf_psc_exp = '''\n", + "neuron iaf_psc_exp:\n", + "\n", + " state:\n", + " V_m mV = E_L\n", + " I_noise pA = mean_noise\n", + " end\n", + " \n", + " equations:\n", + " kernel psc_kernel = exp(-t / tau_syn)\n", + " V_m' = -(V_m - E_L) / tau_m + (convolve(psc_kernel, spikes) + I_e + I_noise) / C_m\n", + " end\n", + "\n", + " parameters:\n", + " E_L mV = -65 mV # resting potential\n", + " I_e pA = 0 pA # constant external input current\n", + " tau_m ms = 25 ms # membrane time constant\n", + " tau_syn ms = 5 ms # synaptic time constant\n", + " C_m uF = 1 uF # membrane capacitance\n", + " V_theta mV = -30 mV # threshold potential\n", + " mean_noise pA = 0.057 pA # mean of the noise current\n", + " sigma_noise pA = 0.003 pA # standard deviation of the noise current\n", + " tau_noise ms = 10 ms # time constant of the noise process\n", + " end\n", + "\n", + " internals:\n", + " A_noise real = sigma_noise * ((1 - exp(-2 * resolution() / tau_noise)))**.5\n", + " end\n", + "\n", + " input:\n", + " spikes pA <- spike\n", + " end\n", + " \n", + " output: spike\n", + " \n", + " update:\n", + " integrate_odes()\n", + "\n", + " I_noise = mean_noise \\\n", + " + (I_noise - mean_noise) * exp(-resolution() / tau_noise) \\\n", + " + A_noise * random_normal(0, 1)\n", + "\n", + " if V_m > V_theta:\n", + " V_m = E_L\n", + " emit_spike()\n", + " end\n", + " end\n", + "\n", + "end\n", + "'''\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + ], + "source": [ + "with open(\"iaf_psc_exp.nestml\", \"w\") as nestml_model_file:\n", + " print(iaf_psc_exp, file=nestml_model_file)\n", + "\n", + "generate_nest_target(input_path=\"iaf_psc_exp.nestml\",\n", + " target_path=\"/tmp/nestml-target\",\n", + " module_name=\"nestml_iaf_module\",\n", + " suffix=\"_nestml\", logging_level=\"ERROR\",dev=True,\n", + " codegen_opts={\"nest_path\": NEST_SIMULATOR_INSTALL_LOCATION})\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, the NESTML model is ready to be used in a simulation." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def evaluate_neuron(neuron_name, neuron_parms=None, I_e=0.,\n", + " mu=0., sigma=0., t_sim=300., plot=True):\n", + " \"\"\"\n", + " Run a simulation in NEST for the specified neuron. Inject a stepwise\n", + " current and plot the membrane potential dynamics and spikes generated.\n", + " \"\"\"\n", + " dt = .1 # [ms]\n", + "\n", + " nest.ResetKernel()\n", + " try:\n", + " nest.Install(\"nestml_iaf_module\")\n", + " except :\n", + " pass\n", + " neuron = nest.Create(neuron_name)\n", + " if neuron_parms:\n", + " for k, v in neuron_parms.items():\n", + " nest.SetStatus(neuron, k, v)\n", + " nest.SetStatus(neuron, \"I_e\", I_e)\n", + " nest.SetStatus(neuron, \"mean_noise\", mu)\n", + " nest.SetStatus(neuron, \"sigma_noise\", sigma)\n", + " \n", + " multimeter = nest.Create(\"multimeter\")\n", + " multimeter.set({\"record_from\": [\"V_m\"],\n", + " \"interval\": dt})\n", + " sr = nest.Create(\"spike_recorder\")\n", + " nest.Connect(multimeter, neuron)\n", + " nest.Connect(neuron, sr)\n", + " \n", + " nest.Simulate(t_sim)\n", + "\n", + " dmm = nest.GetStatus(multimeter)[0]\n", + " Voltages = dmm[\"events\"][\"V_m\"]\n", + " tv = dmm[\"events\"][\"times\"]\n", + " dSD = nest.GetStatus(sr, keys='events')[0]\n", + " spikes = dSD['senders']\n", + " ts = dSD[\"times\"]\n", + " \n", + " _idx = [np.argmin((tv - spike_time)**2) - 1 for spike_time in ts]\n", + " V_m_at_spike_times = Voltages[_idx]\n", + " \n", + " if plot:\n", + " fig, ax = plt.subplots()\n", + " ax.plot(tv, Voltages)\n", + " ax.scatter(ts, V_m_at_spike_times)\n", + " ax.set_xlabel(\"Time [ms]\")\n", + " ax.set_ylabel(\"V_m [mV]\")\n", + " ax.grid()\n", + "\n", + " return ts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we stimulate the neuron with a constant current of 1 µA alone, it does not spike:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "spike_times = evaluate_neuron(\"iaf_psc_exp_nestml\", mu=1E6, sigma=0.)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, for the same $\\mu$=1 µA, but setting $\\sigma$=2 µA/√ms, the effect of the noise can be clearly seen in the membrane potential, and the occasional spiking of the neuron:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "spike_times = evaluate_neuron(\"iaf_psc_exp_nestml\", mu=1E6, sigma=2E6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To further quantify the effects of the noise, we can plot a distribution of interspike intervals:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "426 spikes recorded\n", + "Mean ISI: 58.56682352941177\n", + "ISI std. dev.: 77.18486566391813\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "spike_times = evaluate_neuron(\"iaf_psc_exp_nestml\",\n", + " mu=1E6,\n", + " sigma=2E6,\n", + " t_sim=25000.,\n", + " plot=False)\n", + "\n", + "ISI = np.diff(spike_times)\n", + "ISI_mean = np.mean(ISI)\n", + "ISI_std = np.std(ISI)\n", + "\n", + "print(str(len(spike_times)) + \" spikes recorded\")\n", + "print(\"Mean ISI: \" + str(ISI_mean))\n", + "print(\"ISI std. dev.: \" + str(ISI_std))\n", + "\n", + "count, bin_edges = np.histogram(ISI)\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.bar(bin_edges[:-1], count, width=.8 * (bin_edges[1] - bin_edges[0]))\n", + "ylim = ax.get_ylim()\n", + "ax.plot([ISI_mean, ISI_mean], ax.get_ylim(), c=\"#11CC22\", linewidth=3)\n", + "ax.plot([ISI_mean - ISI_std, ISI_mean - ISI_std], ylim, c=\"#CCCC11\", linewidth=3)\n", + "ax.plot([ISI_mean + ISI_std, ISI_mean + ISI_std], ylim, c=\"#CCCC11\", linewidth=3)\n", + "ax.set_ylim(ylim)\n", + "ax.set_xlabel(\"ISI [ms]\")\n", + "ax.set_ylabel(\"Count\")\n", + "ax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Further directions\n", + "----------\n", + "\n", + "* Calculate and plot the time-varying expected variance of the OU process when its initial value is unequal to the process mean ([1], eq. 2.26; see Fig. 2 for a visual example)\n", + "* Make an extension of the neuron model, that stimulates the cell with an inhibitory as well as excitatory noise current.\n", + "* Instead of a current-based noise, make a neuron model that contains a conductance-based noise." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "References\n", + "----------\n", + "\n", + "[1] D.T. Gillespie, \"The mathematics of Brownian motion and Johnson noise\", Am. J. Phys. 64, 225 (1996); doi: 10.1119/1.18210\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Acknowledgements\n", + "----------------\n", + "\n", + "Thanks to Tobias Schulte to Brinke, Barna Zajzon, Renato Duarte, Claudia Bachmann and all participants of the CNS2020 tutorial on NEST Desktop & NESTML!\n", + "\n", + "This software was developed in part or in whole in the Human Brain Project, funded from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under Specific Grant Agreements No. 720270 and No. 785907 (Human Brain Project SGA1 and SGA2).\n", + "\n", + "License\n", + "-------\n", + "\n", + "This notebook (and associated files) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.\n", + "\n", + "This notebook (and associated files) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details." + ] + } + ], + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/doc/tutorials/stdp_dopa_synapse/stdp_dopa_synapse.ipynb b/doc/tutorials/stdp_dopa_synapse/stdp_dopa_synapse.ipynb new file mode 100644 index 000000000..d3892e2d3 --- /dev/null +++ b/doc/tutorials/stdp_dopa_synapse/stdp_dopa_synapse.ipynb @@ -0,0 +1,1961 @@ +{ + "cells": [ + { + "attachments": { + "4e99976a-4885-4d3a-8890-52f95a78a055.png": { + "image/png": "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NVSFgEJAIaAQUAgoBBQCCgGFgDIA1BpQCCgEFAIKAYWAQkAhoBBQCCwhBJQBsIQmWw1VIaAQUAgoBBQCCgGFgEJAIaAMALUGFAIKAYWAQkAhoBBQCCgEFAJLCAFlACyhyVZDVQgoBBQCCgGFgEJAIaAQUAgoA0CtAYWAQkAhoBBQCCgEFAIKAYXAEkJAGQBLaLLVUBUCCgGFgEJAIaAQUAgoBBQCygBQa0AhoBBQCCgEFAIKAYWAQkAhsIQQUAbAEppsNVSFgEJAIaAQUAgoBBQCCgGFgDIA1BpQCCgEFAIKAYWAQkAhoBBQCCwhBJQBsIQmWw1VIaAQUAgoBBQCCgGFgEJAIaAMALUGFAIKAYWAQkAhoBBQCCgEFAJLCAFlACyhyVZDVQgoBBQCCgGFgEJAIaAQUAgoA0CtAYWAQkAhoBBQCCgEFAIKAYXAEkJAGQBLaLLVUBUCCgGFgEJAIaAQUAgoBBQCygBQa0AhoBBQCCgEFAIKAYWAQkAhsIQQUAbAEppsNVSFgEJAIaAQUAgoBBQCCgGFgDIA1BpQCCgEFAIKAYWAQkAhoBBQCCwhBJQBsIQmWw1VIaAQUAgoBBQCCgGFgEJAIaAMALUGFAIKAYWAQkAhoBBQCCgEFAJLCAFlACyhyVZDVQgoBBQCCgGFgEJAIaAQUAgoA0CtAYWAQkAhoBBQCCgEFAIKAYXAEkJAGQBLaLLVUBUCCgGFgEJAIaAQUAgoBBQCygBQa0AhoBBQCCgEFAIKAYWAQkAhsIQQUAbAEppsNVSFgEJAIaAQUAgoBBQCCgGFgDIA1BpQCCgEFAIKAYWAQkAhoBBQCCwhBJQBsIQmWw1VIaAQUAgoBBQCCgGFgEJAIaAMALUGFAIKAYWAQkAhoBBQCCgEFAJLCAFlACyhyVZDVQgoBBQCCgGFgEJAIaAQUAgoA0CtAYWAQkAhoBBQCCgEFAIKAYXAEkJAGQBLaLLVUBUCCgGFgEJAIaAQUAgoBBQCygBQa0AhoBBQCCgEFAIKAYWAQkAhsIQQUAbAEppsNVSFgEJAIaAQUAgoBBQCCgGFgDIA1BpQCCgEFAIKAYWAQkAhoBBQCCwhBJQBsIQmWw1VIaAQUAgoBBQCCgGFgEJAIaAMALUGFAIKAYWAQkAhoBBQCCgEFAJLCAFlACyhyVZDVQgoBBQCCgGFgEJAIaAQUAgoA0Ct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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NESTML dopamine-modulated STDP synapse tutorial\n", + "\n", + "Some text in this this notebook is copied verbatim from [1]. Network diagrams were modeled after [2].\n", + "\n", + "Pavlov and Thompson (1902) first described classical conditioning: a phenomenon in which a biologically potent stimulus–the Unconditional Stimulus (UC)—is initially paired with a neutral stimulus—the Conditional Stimulus (CS). After many trials, learning is observed when the previously neutral stimuli start to elicit a response similar to that which was previously only elicited by the biologically potent stimulus. Pavlov and Thompson performed many experiments with dogs, observing their response (by monitoring salivation) to the appearance of a person who has been feeding them and the actual food appearing (UC). He demonstrated that the dogs started to salivate in the presence of the person who has been feeding them (or any other CS), rather than just when the food appears, because the CS had previously been associated with food.\n", + "\n", + "
\n", + "\n", + "
Image credits: https://www.psychologicalscience.org/observer/revisiting-pavlovian-conditioning
\n", + "\n", + "\n", + "In this tutorial, a dopamine-modulated STDP model is created in NESTML, and we characterize the model before using it in a network (reinforcement) learning task.\n", + "\n", + "\n", + "## Model\n", + "\n", + "Izhikevich (2007) revisits an important question: how does an\n", + "animal know which of the many cues and actions preceding a\n", + "reward should be credited for the reward? Izhikevich explains\n", + "that dopamine-modulated STDP has a built-in instrumental\n", + "conditioning property, i.e., the associations between cues, actions and rewards are learned automatically by reinforcing the firing patterns (networks of synapses) responsible, even when the firings of those patterns are followed by a delayed reward or masked by other network activity.\n", + "\n", + "To achieve this, each synapse has an eligibility trace $C$:\n", + "\n", + "$$\n", + "\\frac{dC}{dt} = -\\frac{C}{\\tau_C} + \\text{STDP}(\\Delta t)\\delta(t - t_\\text{pre/post}) \\quad \\text{(1)}\n", + "$$\n", + "\n", + "where $\\tau_C$ is the decay time constant of the eligibility trace and $\\text{STDP}(\\Delta t)$ represents the magnitude of the change to make to the eligibility trace in response to a pair of pre- and post-synaptic spikes with temporal difference $\\Delta t = t_\\text{post} − t_\\text{pre}$. (This is just the usual STDP rule, see https://nestml.readthedocs.io/en/latest/tutorials/stdp_windows/stdp_windows.html.) Finally, $\\delta(t − t_\\text{pre/post})$ is a Dirac delta function used to apply the effect of STDP to the trace at the times of pre- or post-synaptic spikes.\n", + "\n", + "The concentration of dopamine is described by a variable $D$:\n", + "\n", + "$$\n", + "\\frac{dD}{dt} = − \\frac{D}{\\tau_d} + D_c \\sum_{t_d^f} \\delta(t - t_d^f) \\quad \\text{(2)}\n", + "$$\n", + "\n", + "where $\\tau_d$ is the time constant of dopamine re-absorption, $D_c$ is a real number indicating the increase in dopamine concentration caused by each incoming dopaminergic spike; $t_d^f$ are the times of these spikes.\n", + "\n", + "Equations (1, 2) are then combined to calculate the change in\n", + "synaptic strength $W$:\n", + "\n", + "$$\n", + "\\frac{dW}{dt} = CD \\quad \\text{(3)}\n", + "$$\n", + "\n", + "When a post-synaptic spike arrives very shortly after a pre-synaptic spike, a standard STDP rule would immediately potentiate the synaptic strength. However, when using the three-factor STDP rule, this potentiation would instead be applied to the eligibility trace.\n", + "\n", + "Because changes to the synaptic strength are gated by dopamine concentration $D$ (Equation 3), changes are only made to the synaptic strength if $D \\neq 0$. Furthermore, if the eligibility trace has decayed back to 0 before any dopaminergic spikes arrive, the synaptic strength will also not be changed." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "from typing import List, Optional\n", + "\n", + "import matplotlib as mpl\n", + "\n", + "mpl.rcParams['axes.formatter.useoffset'] = False\n", + "mpl.rcParams['axes.grid'] = True\n", + "mpl.rcParams['grid.color'] = 'k'\n", + "mpl.rcParams['grid.linestyle'] = ':'\n", + "mpl.rcParams['grid.linewidth'] = 0.5\n", + "mpl.rcParams['figure.dpi'] = 120\n", + "mpl.rcParams['figure.figsize'] = [8., 3.]\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import nest\n", + "import numpy as np\n", + "import os\n", + "import random\n", + "import re\n", + "from pynestml.frontend.pynestml_frontend import generate_nest_target\n", + "\n", + "NEST_SIMULATOR_INSTALL_LOCATION = nest.ll_api.sli_func(\"statusdict/prefix ::\")\n", + "\n", + "# NESTML base directory is computed on the basis of the notebook's absolute path.\n", + "# The notebook is in ``doc/tutorials/stdp_dopa_synapse``, so the base directory is\n", + "# three levels up in the directory tree.\n", + "BASE_DIR = os.path.join(os.path.abspath(\"\"), os.pardir, os.pardir, os.pardir)\n", + "os.chdir(BASE_DIR)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generating code with NESTML\n", + "\n", + "To generate fast code, NESTML needs to process the synapse model together with the neuron model that will be its postsynaptic partner in the network instantiantion (see https://nestml.readthedocs.io/en/v5.0.0/nestml_language/synapses_in_nestml.html#generating-code).\n", + "\n", + "In this tutorial, we will use a very simple integrate-and-fire model, where arriving spikes cause an instantaneous increment of the membrane potential.\n", + "\n", + "We first define a helper function to generate the C++ code for the models, build it as a NEST extension module, and load the module into the kernel. The resulting model names are composed of associated neuron and synapse partners, because of the co-generation, for example, \"stdp_synapse__with_iaf_psc_delta\" and \"iaf_psc_delta__with_stdp_synapse\".\n", + "\n", + "Because NEST does not support un- or reloading of modules at the time of writing, we implement a workaround that appends a unique number to the name of each generated model, for example, \"stdp_synapse_3cc945f__with_iaf_psc_delta_3cc945f\" and \"iaf_psc_delta_3cc945f__with_stdp_synapse_3cc945f\".\n", + "\n", + "The resulting neuron and synapse model names are returned by the function, so we do not have to think about these internals." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import uuid\n", + "\n", + "def generate_code_for(nestml_neuron_model: str,\n", + " nestml_synapse_model: str,\n", + " post_ports: Optional[List[str]] = None,\n", + " mod_ports: Optional[List[str]] = None,\n", + " uniq_id: Optional[str] = None,\n", + " logging_level: str = \"WARNING\"):\n", + " \"\"\"Generate code for a given neuron and synapse model, passed as a string.\n", + " NEST cannot yet unload or reload modules. This function implements a workaround using UUIDs to generate unique names.\n", + " The neuron and synapse models can be passed directly as strings in NESTML syntax, or as filenames, in which case the NESTML model is loaded from the given filename.\n", + " \"\"\"\n", + "\n", + " if uniq_id is None:\n", + " uniq_id = str(uuid.uuid4().hex)\n", + "\n", + " # read neuron model from file?\n", + " if not \"\\n\" in nestml_neuron_model and \".nestml\" in nestml_neuron_model:\n", + " with open(nestml_neuron_model, \"r\") as nestml_model_file:\n", + " nestml_neuron_model = nestml_model_file.read()\n", + "\n", + " # read synapse model from file?\n", + " if not \"\\n\" in nestml_synapse_model and \".nestml\" in nestml_synapse_model:\n", + " with open(nestml_synapse_model, \"r\") as nestml_model_file:\n", + " nestml_synapse_model = nestml_model_file.read()\n", + "\n", + " # generate unique ID\n", + " if uniq_id is None:\n", + " uniq_id = str(uuid.uuid4().hex)\n", + "\n", + " # update neuron model name inside the file\n", + " neuron_model_name_orig = re.findall(r\"neuron\\ [^:\\s]*:\", nestml_neuron_model)[0][7:-1]\n", + " neuron_model_name_uniq = neuron_model_name_orig + uniq_id\n", + " nestml_model = re.sub(r\"neuron\\ [^:\\s]*:\",\n", + " \"neuron \" + neuron_model_name_uniq + \":\", nestml_neuron_model)\n", + " neuron_uniq_fn = neuron_model_name_uniq + \".nestml\"\n", + " with open(neuron_uniq_fn, \"w\") as f:\n", + " print(nestml_model, file=f)\n", + "\n", + " # update synapse model name inside the file\n", + " synapse_model_name_orig = re.findall(r\"synapse\\ [^:\\s]*:\", nestml_synapse_model)[0][8:-1]\n", + " synapse_model_name_uniq = synapse_model_name_orig + uniq_id\n", + " nestml_model = re.sub(r\"synapse\\ [^:\\s]*:\",\n", + " \"synapse \" + synapse_model_name_uniq + \":\", nestml_synapse_model)\n", + " synapse_uniq_fn = synapse_model_name_uniq + \".nestml\"\n", + " with open(synapse_uniq_fn, \"w\") as f:\n", + " print(nestml_model, file=f)\n", + "\n", + " # generate the code for neuron and synapse (co-generated)\n", + " module_name = \"nestml_\" + uniq_id + \"_module\"\n", + " generate_nest_target(input_path=[neuron_uniq_fn, synapse_uniq_fn],\n", + " logging_level=logging_level,\n", + " module_name=module_name,\n", + " suffix=\"_nestml\",\n", + " codegen_opts={\"neuron_parent_class\": \"StructuralPlasticityNode\",\n", + " \"neuron_parent_class_include\": \"structural_plasticity_node.h\",\n", + " \"neuron_synapse_pairs\": [{\"neuron\": neuron_model_name_uniq,\n", + " \"synapse\": synapse_model_name_uniq,\n", + " \"post_ports\": post_ports,\n", + " \"vt_ports\": mod_ports}]})\n", + " mangled_neuron_name = neuron_model_name_uniq + \"_nestml__with_\" + synapse_model_name_uniq + \"_nestml\"\n", + " mangled_synapse_name = synapse_model_name_uniq + \"_nestml__with_\" + neuron_model_name_uniq + \"_nestml\"\n", + "\n", + " return module_name, mangled_neuron_name, mangled_synapse_name" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Formulating the model in NESTML\n", + "\n", + "We now go on to define the full synapse model in NESTML:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_stdp_dopa_model = \"\"\"\n", + "synapse neuromodulated_stdp:\n", + "\n", + " state:\n", + " w real = 1.\n", + " n real = 0. # Neuromodulator concentration\n", + " c real = 0. # Eligibility trace\n", + " pre_tr real = 0.\n", + " post_tr real = 0.\n", + " end\n", + "\n", + " parameters:\n", + " the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called \"delay\"\n", + " tau_tr_pre ms = 20 ms # STDP time constant for weight changes caused by pre-before-post spike pairings.\n", + " tau_tr_post ms = 20 ms # STDP time constant for weight changes caused by post-before-pre spike pairings.\n", + " tau_c ms = 1000 ms # Time constant of eligibility trace\n", + " tau_n ms = 200 ms # Time constant of dopaminergic trace\n", + " b real = 0. # Dopaminergic baseline concentration\n", + " Wmax real = 200. # Maximal synaptic weight\n", + " Wmin real = 0. # Minimal synaptic weight\n", + " A_plus real = 1. # Multiplier applied to weight changes caused by pre-before-post spike pairings. If b (dopamine baseline concentration) is zero, then A_plus is simply the multiplier for facilitation (as in the stdp_synapse model). If b is not zero, then A_plus will be the multiplier for facilitation only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_plus will be the multiplier for depression.\n", + " A_minus real = 1.5 # Multiplier applied to weight changes caused by post-before-pre spike pairings. If b (dopamine baseline concentration) is zero, then A_minus is simply the multiplier for depression (as in the stdp_synapse model). If b is not zero, then A_minus will be the multiplier for depression only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_minus will be the multiplier for facilitation.\n", + " A_vt real = 1. # Multiplier applied to dopa spikes\n", + " end\n", + "\n", + " equations:\n", + " pre_tr' = -pre_tr / tau_tr_pre\n", + " post_tr' = -post_tr / tau_tr_post\n", + " end\n", + "\n", + " internals:\n", + " tau_s 1/ms = (tau_c + tau_n) / (tau_c * tau_n)\n", + " end\n", + "\n", + " input:\n", + " pre_spikes nS <- spike\n", + " post_spikes nS <- spike\n", + " mod_spikes real <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " onReceive(mod_spikes):\n", + " n += A_vt / tau_n\n", + " end\n", + "\n", + " onReceive(post_spikes):\n", + " post_tr += 1.\n", + "\n", + " # facilitation\n", + " c += A_plus * pre_tr\n", + " end\n", + "\n", + " onReceive(pre_spikes):\n", + " pre_tr += 1.\n", + "\n", + " # depression\n", + " c -= A_minus * post_tr\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, the_delay)\n", + " end\n", + "\n", + " # update from time t to t + resolution()\n", + " update:\n", + " # resolution() returns the timestep to be made (in units of time)\n", + " # the sequence here matters: the update step for w requires the \"old\" values of c and n\n", + " w -= c * ( n / tau_s * expm1( -tau_s * resolution() ) \\\n", + " - b * tau_c * expm1( -resolution() / tau_c ))\n", + " w = max(0., w)\n", + " c = c * exp(-resolution() / tau_c)\n", + " n = n * exp(-resolution() / tau_n)\n", + " end\n", + "\n", + "end\n", + "\"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Generate the code, build the user module and make the model available to instantiate in NEST:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[7,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [61:4;61:22]]: Variable 'G' has the same name as a physical unit!\n", + "[8,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [82:4;82:22]]: Variable 'h' has the same name as a physical unit!\n", + "[13,neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:root:PyGSL is not available. The stiffness test will be skipped.\n", + "WARNING:root:Error when importing: No module named 'pygsl'\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[22,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [61:4;61:22]]: Variable 'G' has the same name as a physical unit!\n", + "[23,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [82:4;82:22]]: Variable 'h' has the same name as a physical unit!\n", + "[25,neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[44,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml__with_neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [61:4;61:22]]: Variable 'G' has the same name as a physical unit!\n", + "[45,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml__with_neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [82:4;82:22]]: Variable 'h' has the same name as a physical unit!\n", + "[49,neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml__with_iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[56,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [82:4;82:22]]: Variable 'h' has the same name as a physical unit!\n", + "[60,iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml__with_neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [82:4;82:22]]: Variable 'h' has the same name as a physical unit!\n", + "[64,neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml__with_iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[68,neuromodulated_stdpc037ef42f5f04013b8a99109f147d77b_nestml__with_iaf_psc_deltac037ef42f5f04013b8a99109f147d77b_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n" + ] + } + ], + "source": [ + "# generate and build code\n", + "module_name, neuron_model_name, synapse_model_name = \\\n", + " generate_code_for(\"models/neurons/iaf_psc_delta.nestml\",\n", + " nestml_stdp_dopa_model,\n", + " post_ports=[\"post_spikes\"],\n", + " mod_ports=[\"mod_spikes\"])\n", + "\n", + "# load dynamic library (NEST extension module) into NEST kernel\n", + "nest.Install(module_name)" + ] + }, + { + "attachments": { + "image-2.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running the simulation in NEST\n", + "\n", + "Let's define a function that will instantiate a simple network with one presynaptic cell and one postsynaptic cell connected by a single synapse, then run a simulation and plot the results.\n", + "\n", + "
\n", + "\n", + "![image-2.png](attachment:image-2.png)\n", + " \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def run_network(pre_spike_time, post_spike_time, vt_spike_times,\n", + " neuron_model_name,\n", + " synapse_model_name,\n", + " resolution=.1, # [ms]\n", + " delay=1., # [ms]\n", + " lmbda=1E-6,\n", + " sim_time=None, # if None, computed from pre and post spike times\n", + " synapse_parameters=None, # optional dictionary passed to the synapse\n", + " fname_snip=\"\",\n", + " debug=False):\n", + "\n", + " #nest.set_verbosity(\"M_WARNING\")\n", + " nest.set_verbosity(\"M_ALL\")\n", + "\n", + " nest.ResetKernel()\n", + " nest.SetKernelStatus({'resolution': resolution})\n", + "\n", + " # create spike_generators with these times\n", + " pre_sg = nest.Create(\"spike_generator\",\n", + " params={\"spike_times\": [pre_spike_time]})\n", + " post_sg = nest.Create(\"spike_generator\",\n", + " params={\"spike_times\": [post_spike_time]})\n", + " vt_sg = nest.Create(\"spike_generator\",\n", + " params={\"spike_times\": vt_spike_times})\n", + "\n", + " # create volume transmitter\n", + " vt = nest.Create(\"volume_transmitter\")\n", + " vt_parrot = nest.Create(\"parrot_neuron\")\n", + " nest.Connect(vt_sg, vt_parrot)\n", + " nest.Connect(vt_parrot, vt, syn_spec={\"synapse_model\": \"static_synapse\",\n", + " \"weight\": 1.,\n", + " \"delay\": 1.}) # delay is ignored!\n", + " vt_gid = vt.get(\"global_id\")\n", + "\n", + " # set up custom synapse models\n", + " wr = nest.Create('weight_recorder')\n", + " nest.CopyModel(synapse_model_name, \"stdp_nestml_rec\",\n", + " {\"weight_recorder\": wr[0],\n", + " \"w\": 1.,\n", + " \"delay\": delay,\n", + " \"receptor_type\": 0,\n", + " \"vt\": vt_gid,\n", + " \"tau_tr_pre\": 10.,\n", + " })\n", + "\n", + " # create parrot neurons and connect spike_generators\n", + " pre_neuron = nest.Create(\"parrot_neuron\")\n", + " post_neuron = nest.Create(neuron_model_name)\n", + " \n", + " spikedet_pre = nest.Create(\"spike_recorder\")\n", + " spikedet_post = nest.Create(\"spike_recorder\")\n", + " spikedet_vt = nest.Create(\"spike_recorder\")\n", + "\n", + " #mm = nest.Create(\"multimeter\", params={\"record_from\" : [\"V_m\"]})\n", + "\n", + " nest.Connect(pre_sg, pre_neuron, \"one_to_one\", syn_spec={\"delay\": 1.})\n", + " nest.Connect(post_sg, post_neuron, \"one_to_one\", syn_spec={\"delay\": 1., \"weight\": 9999.})\n", + " nest.Connect(pre_neuron, post_neuron, \"all_to_all\", syn_spec={'synapse_model': 'stdp_nestml_rec'})\n", + " #nest.Connect(mm, post_neuron)\n", + "\n", + " nest.Connect(pre_neuron, spikedet_pre)\n", + " nest.Connect(post_neuron, spikedet_post)\n", + " nest.Connect(vt_parrot, spikedet_vt)\n", + " \n", + " # get STDP synapse and weight before protocol\n", + " syn = nest.GetConnections(source=pre_neuron, synapse_model=\"stdp_nestml_rec\")\n", + " if synapse_parameters is None:\n", + " synapse_parameters = {}\n", + " nest.SetStatus(syn, synapse_parameters)\n", + "\n", + " initial_weight = nest.GetStatus(syn)[0][\"w\"]\n", + " np.testing.assert_allclose(initial_weight, 1)\n", + " nest.Simulate(sim_time)\n", + " updated_weight = nest.GetStatus(syn)[0][\"w\"]\n", + "\n", + " actual_t_pre_sp = nest.GetStatus(spikedet_pre)[0][\"events\"][\"times\"][0]\n", + " actual_t_post_sp = nest.GetStatus(spikedet_post)[0][\"events\"][\"times\"][0]\n", + "\n", + " pre_spike_times_ = nest.GetStatus(spikedet_pre, \"events\")[0][\"times\"]\n", + " assert len(pre_spike_times_) == 1 and pre_spike_times_[0] > 0\n", + " \n", + " post_spike_times_ = nest.GetStatus(spikedet_post, \"events\")[0][\"times\"]\n", + " assert len(post_spike_times_) == 1 and post_spike_times_[0] > 0\n", + "\n", + " vt_spike_times_ = nest.GetStatus(spikedet_vt, \"events\")[0][\"times\"]\n", + " assert len(vt_spike_times_) == 1 and vt_spike_times_[0] > 0\n", + "\n", + " #dt = actual_t_post_sp - actual_t_pre_sp\n", + " dt = 0.\n", + " dw = updated_weight\n", + "\n", + " return dt, dw" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def run_vt_spike_timing_experiment(neuron_model_name, synapse_model_name, synapse_parameters=None):\n", + " sim_time = 10000. # [ms] -- make sure to simulate for much longer than the eligibility trace\n", + " # time constant, which is typically the slowest time constant in \n", + " # the system, PLUS the time of the latest vt spike\n", + " pre_spike_time = 1. # [ms]\n", + " post_spike_time = 3. # [ms]\n", + " delay = .5 # dendritic delay [ms]\n", + "\n", + " dt_vec = []\n", + " dw_vec = []\n", + " for vt_spike_time in np.round(np.linspace(4, 5000, 12)).astype(float): # sim_time - 10 * delay\n", + " dt, dw = run_network(pre_spike_time, post_spike_time, [vt_spike_time],\n", + " neuron_model_name,\n", + " synapse_model_name,\n", + " delay=delay, # [ms]\n", + " synapse_parameters=synapse_parameters,\n", + " sim_time=sim_time)\n", + " dt_vec.append(vt_spike_time)\n", + " dw_vec.append(dw)\n", + " \n", + " return dt_vec, dw_vec, delay" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "for A_vt in [1., -1.]:\n", + " dt_vec, dw_vec, delay = run_vt_spike_timing_experiment(neuron_model_name,\n", + " synapse_model_name, \n", + " synapse_parameters={\"A_vt\": A_vt})\n", + " ax.plot(dt_vec, dw_vec, marker='o', label=\"$A_{vt}$ = \" + str(A_vt))\n", + "\n", + "ax.set_xlabel(\"Time of dopa spike [ms]\")\n", + "ax.set_ylabel(\"Weight at $t = \\infty$\")\n", + "ax.legend()" + ] + }, + { + "attachments": { + "image-2.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Learning through dopamine\n", + "\n", + "In this section we simulate the spiking activity of a group of neurons with the learning rule as described above. Here, we perform the simulation on 10 `iaf_psc_delta` neurons in which each of the neurons receives input from an independent Poisson source of 50Hz. These neurons are also connected to a single dopamine spike source. These dopamine spikes are delivered to the neurons as reward and punishment signals at specific time intervals.\n", + "\n", + "
\n", + "\n", + "![image-2.png](attachment:image-2.png)\n", + "\n", + "
\n", + "\n", + "_Single dopamine source, multiple independent pre-post cell pairs (3 pairs shown)._" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Labels for x and y axes for traces used in plotting functions\n", + "labels = {\"c\": {\"x_label\": \"Times [ms]\", \"y_label\": \"Eligibility \\ntrace (c)\"},\n", + " \"w\": {\"x_label\": \"Times [ms]\", \"y_label\": \"Weight \\ntrace (w)\"},\n", + " \"pre_tr\": {\"x_label\": \"Times [ms]\", \"y_label\": \"Presynaptic \\ntrace (pre_tr)\"},\n", + " \"n\": {\"x_label\": \"Times [ms]\", \"y_label\": \"Doapmine \\ntrace (n)\"}\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Plot trace values for a neurons or set of neurons\n", + "def plot_traces_for_neuron(log, recordables, neuron_numbers=None, pos_dopa_spike_times=None, neg_dopa_spike_times=None):\n", + " \"\"\"\n", + " Plots the trace values for the given list of neuron IDs\n", + " \"\"\"\n", + " times = log[\"t\"]\n", + " trace_values = {}\n", + " # Initialize the list if \"neuron_numbers\" is None, which corresponds to all neurons\n", + " if neuron_numbers is None:\n", + " neuron_numbers = np.array([i+1 for i in range(10)])\n", + "\n", + " # The actual neuron numbers are -1 of the given numbers\n", + " neuron_numbers_actual = np.array(neuron_numbers) - 1\n", + " \n", + " # Get the values of recordables for the given neuron IDs\n", + " for recordable in recordables:\n", + " trace_values[recordable] = np.array(log[recordable])[:, neuron_numbers_actual]\n", + "\n", + " n_neurons = len(neuron_numbers)\n", + " palette = plt.get_cmap('tab10')\n", + " \n", + " for i in range(n_neurons):\n", + " fig, ax = plt.subplots(nrows=len(recordables), sharex=True, squeeze=False)\n", + " ax = ax.flatten()\n", + " fig.suptitle(\"Trace values for Neuron \" + str(neuron_numbers[i]))\n", + " for j, recordable in enumerate(recordables):\n", + " ax[j].plot(times, trace_values[recordable][:, i], label=\"neuron \" + str(neuron_numbers[i]), color=palette(neuron_numbers_actual[i]))\n", + " ax[j].set_xlim(xmin=0)\n", + " ax[j].set_ylabel(labels[recordable][\"y_label\"], rotation=0, ha=\"right\", va=\"center\")\n", + " ax[j].legend(loc=\"upper right\", labelspacing=0.)\n", + " if pos_dopa_spike_times is not None:\n", + " ax[j].scatter(pos_dopa_spike_times, np.ones_like(pos_dopa_spike_times) * np.amin(trace_values[recordable][:, i]), marker=\"^\", c=\"green\", s=20)\n", + " if neg_dopa_spike_times is not None:\n", + " ax[j].scatter(neg_dopa_spike_times, np.ones_like(neg_dopa_spike_times) * np.amin(trace_values[recordable][:, i]), marker=\"^\", c=\"red\", s=20)\n", + " fig.tight_layout(rect=[0, 0.03, 1, 0.95])" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_spiking_activity(neuron_spike_times, pos_dopa_spike_times, neg_dopa_spike_times, source_ids, total_t_sim):\n", + " fig, ax = plt.subplots()\n", + " palette = plt.get_cmap('tab10')\n", + " \n", + " n_neurons = len(neuron_spike_times)\n", + " y_ticks = [i * 10 for i in range(n_neurons, 0, -1)]\n", + " for i in range(n_neurons):\n", + " ax.scatter(neuron_spike_times[i], np.ones_like(neuron_spike_times[i]) * y_ticks[i], color=palette(i), s=1)\n", + "\n", + " if pos_dopa_spike_times is not None:\n", + " ax.scatter(pos_dopa_spike_times, np.zeros_like(pos_dopa_spike_times), marker=\"^\", c=\"green\", s=100)\n", + " if neg_dopa_spike_times is not None:\n", + " ax.scatter(neg_dopa_spike_times, np.zeros_like(pos_dopa_spike_times), marker=\"^\", c=\"red\", s=100)\n", + "\n", + " ax.set_xlim(0., total_t_sim)\n", + " ax.set_ylim(ymin=0)\n", + " ax.set_xlim(xmin=0)\n", + " ax.set_yticks(y_ticks)\n", + " ax.set_yticklabels(source_ids)\n", + " ax.set_xlabel(\"Time [ms]\")\n", + " ax.set_ylabel(\"Neuron ID\")\n", + " plt.tight_layout()\n", + " fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we setup the network with 10 neurons each connected to a Poisson source. The neurons are also connected to a volume transmitter that acts as a dopamine spike source." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# simulation parameters\n", + "resolution = .1\n", + "\n", + "# network parameters\n", + "n_neurons = 10\n", + "tau_n = 50.\n", + "tau_c = 100.\n", + "pre_poisson_rate = 50. # [s^-1]\n", + "initial_weight = 5.6 # controls initial firing rate before potentiation\n", + "\n", + "# stimulus parameters\n", + "pos_dopa_spike_times = [2000, 3000, 4000]\n", + "neg_dopa_spike_times = [8000, 9000, 10000]\n", + "A_vt = [10., -10.]\n", + "\n", + "\n", + "nest.set_verbosity(\"M_ALL\")\n", + "\n", + "nest.ResetKernel()\n", + "nest.SetKernelStatus({'resolution': resolution})\n", + "\n", + "# Create the neurons\n", + "neurons = nest.Create(neuron_model_name, n_neurons)\n", + "\n", + "# Create a poisson generator\n", + "poisson_gen = nest.Create(\"poisson_generator\", n_neurons, params={\"rate\": pre_poisson_rate})\n", + "parrot_neurons = nest.Create(\"parrot_neuron\", n_neurons)\n", + "\n", + "# Spike generators\n", + "vt_sg = nest.Create(\"spike_generator\", params={\"spike_times\": pos_dopa_spike_times + neg_dopa_spike_times})\n", + "\n", + "# Spike recorder\n", + "spike_rec = nest.Create(\"spike_recorder\")\n", + "spike_rec_vt = nest.Create(\"spike_recorder\")\n", + "spike_re_pt = nest.Create(\"spike_recorder\")\n", + "\n", + "# create volume transmitter\n", + "vt = nest.Create(\"volume_transmitter\")\n", + "vt_parrot = nest.Create(\"parrot_neuron\")\n", + "nest.Connect(vt_sg, vt_parrot, syn_spec={\"weight\": -1.})\n", + "nest.Connect(vt_parrot, vt, syn_spec={\"synapse_model\": \"static_synapse\",\n", + " \"weight\": 1.,\n", + " \"delay\": 1.})\n", + "\n", + "vt_gid = vt.get(\"global_id\")\n", + "\n", + "# multimeters\n", + "mms = [nest.Create(\"multimeter\", params= {\"record_from\": [\"V_m\"]}) for _ in range(n_neurons)]\n", + "\n", + "# set up custom synapse models\n", + "wr = nest.Create('weight_recorder')\n", + "nest.CopyModel(synapse_model_name, \"stdp_nestml_rec\",\n", + " {\"weight_recorder\": wr[0],\n", + " \"w\": initial_weight,\n", + " \"the_delay\": delay,\n", + " \"receptor_type\": 0,\n", + " \"vt\": vt_gid,\n", + " \"tau_n\": tau_n,\n", + " \"tau_c\": tau_c,\n", + " })\n", + "\n", + "# Connect everything\n", + "nest.Connect(poisson_gen, parrot_neurons, \"one_to_one\")\n", + "nest.Connect(parrot_neurons, neurons, \"one_to_one\", syn_spec=\"stdp_nestml_rec\")\n", + "\n", + "nest.Connect(neurons, spike_rec)\n", + "nest.Connect(vt_parrot, spike_rec_vt)\n", + "\n", + "for i in range(n_neurons):\n", + " nest.Connect(mms[i], neurons[i])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a helper function that runs the simulation in chunks of time intervals and records the values of the synapse properties passed as `recordables`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "def run_simulation_in_chunks(sim_chunks, sim_time, recordables, neurons):\n", + " sim_time_per_chunk = sim_time / sim_chunks\n", + "\n", + " # Init log to collect the values of all recordables\n", + " log = {}\n", + " log[\"t\"] = []\n", + "\n", + " # Initialize all the arrays\n", + " # Additional one entry is to store the trace value before the simulation begins\n", + " for rec in recordables:\n", + " log[rec] = (sim_chunks + 1) * [[]]\n", + "\n", + " # Get the value of trace values before the simulation\n", + " syn = nest.GetConnections(target=neurons, synapse_model=\"stdp_nestml_rec\")\n", + " for rec in recordables:\n", + " log[rec][0] = syn.get(rec)\n", + " \n", + " log[\"t\"].append(nest.GetKernelStatus(\"biological_time\"))\n", + "\n", + " # Run the simulation in chunks\n", + " nest.Prepare()\n", + " for i in range(sim_chunks):\n", + " # Set the reward / punishment for dopa spikes\n", + " # Set the punishment signal only when the timed during simulation == the first negative dopa spike time\n", + " # Otherwise set the reward signal\n", + " sim_start_time = i * sim_time_per_chunk\n", + " sim_end_time = sim_start_time + sim_time_per_chunk\n", + "\n", + " if sim_end_time > neg_dopa_spike_times[0]:\n", + " syn.set({\"A_vt\": A_vt[1]})\n", + " else:\n", + " syn.set({\"A_vt\": A_vt[0]})\n", + "\n", + " nest.Run(sim_time//sim_chunks)\n", + " \n", + " # log current values\n", + " log[\"t\"].append(nest.GetKernelStatus(\"biological_time\"))\n", + "\n", + " # Get the value of trace after the simulation\n", + " for rec in recordables:\n", + " log[rec][i + 1] = syn.get(rec)\n", + " nest.Cleanup()\n", + " \n", + " return log" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Run simulation in NEST\n", + "Let's run the simulation and record the neuron spike times and synapse parameters like the eligibility trace `c`, the presynaptic trace `pre_tr`, the dopamine trace `n`, and the weight `w`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [], + "source": [ + "# Run simulation\n", + "sim_time = 12000\n", + "n_chunks = 400\n", + "recordables = [\"c\", \"pre_tr\", \"n\", \"w\"]\n", + "log = run_simulation_in_chunks(n_chunks, sim_time, recordables, neurons)\n", + "\n", + "times = spike_rec.get(\"events\")[\"times\"]\n", + "senders = spike_rec.get(\"events\")[\"senders\"]\n", + "\n", + "times_vt = spike_rec_vt.get(\"events\")[\"times\"]\n", + "\n", + "connections = nest.GetConnections(neurons)\n", + "source_ids = connections.get(\"source\") # source IDs of all neurons\n", + "source_ids = list(set(source_ids))\n", + "\n", + "neuron_spike_times = [[] for _ in range(n_neurons)]\n", + "for i in range(n_neurons):\n", + " neuron_spike_times[i] = times[senders == source_ids[i]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Spiking activity" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + ":23: UserWarning:Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the spiking activity\n", + "plot_spiking_activity(neuron_spike_times, pos_dopa_spike_times, neg_dopa_spike_times, source_ids, sim_time)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From the spiking activity of the neurons, we can see that the firing rate of the neurons increases after the dopamine spikes or reward signals (green triangles in the plot) are applied to the synapses. Consequently, when the punishment signals are applied (red triangles), the firing rate decreases. In order to understand the dynamics, let's plot the different trace variables of the synapse." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot the trace values\n", + "\n", + "Let's plot the trace values and the weight for each synapse. Note that the dopamine trace is the same for every synapse." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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zLv27s5nKaXmmv+f0Fo/2FLPL4QQQoJZIYTwG1rr15VSFRhBxiSMjLE/ALdhTB9TI+jTWn+llBqNkbToQuASjC6fO4Hn3dZdqpQ6BXgQo+vsWIyWxsMYAd9njSxvqVLqE4yWWfDcxbhJx1XLfsqVUhdidJO9GDgd2IoRsObhIZjVWmcppUZhTDXzK6ozLh/FCMReoXq88X6MlsrxGN1YO5j73YURWLlM79MUWus8pdRZwGPAdcCfMF6PdcBMrfV3zX2OBpbDppR6CFhcy+NVZjB3C8aY4SsxWqePA/swgtb33TZ7CqNr8J0Y2ZKPYrxm06knQ3YtZfD1a3UqbtNPAX3MG8ABjHNJCCFEC1G15xkRQgghhBBCCCHaJhkzK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC70gwK4QQQgghhBDC74T5ugAiuCmlEoFxwCGg0sfFEUIIIYQQQvhOBNAd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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7MAAAFcCAYAAAAak+kRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAABJ0AAASdAHeZh94AADDeUlEQVR4nOydd3wUZfrAv08avRdBRDpIsaDYC1jRU1TUw/NOBc+Gp/dTzo4FPCynnHreiXqnIpbj7KCIooKCoihiBaSFGmqAhBASQkjy/v54ZzKzm91kk2yy2ezz/Xz2s7Oz78w87zw7s/O8T3nFGIOiKIqiKIqiKIqixBNJsRZAURRFURRFURRFUSqLGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqLEHSJiRGRurOWoKiLSS0SmichWpy+7Yi2ToiiKosQbaswqiqLUII6hUpnXqFjLrNQsIpIMTAd+A3wAPAD8LQZyjPL97h4L02aI8/1rtS1fXUZE2ojINc6ARLqI7BWRHBGZLyJXi4g+XymKotQCKbEWQFEUpZ7zQIh1twAtgKeAXUHf/VSz4ih1gG5AP+B5Y8x1sRbG4f9EZJIxZn2sBYkTfgs8C2wBPgc2AAcAFwEvAOeIyG+NMSZ2IiqKotR/1JhVFEWpQYwx44PXOd7XFsA/jDHralkkJfYc6LxvjqkUHulAT+Bh4A8xliVeWAmcD8w0xpS4K0VkLLAQuBhr2L4TG/EURVESAw2DURRFqSOIyFwnpDNNRO4XkRUisk9EpjjftxCR20XkMxHZKCKFIrJdRN4XkePL2e8hIjJZRNY5+8sUkS9F5IYwbaeISIaz/20iMlVE+kTYh985fXgyzPcNRCRbRLaISEp1+hVi31OcY3cN8Z0bLjs+xHetReQREVnmCxedIyJnhWibJiL/JyI/OP3Id87reyJyRgQyGmCe83GcL8x3vK9NC0eeFSJS4Bzn41D79/dLRI4RkZkikhXuPIThTeBH4DIRGRThNohIioj8SUS+EZHdzrn4UURuCg6zLe/8O9+vE5F1QevcMOhRInK2c33kOOfQbVPVc3WEc652OXLPE5ETIu27MeYzY8wMvyHrrN8KPOd8HBLp/hRFUZSqocasoihK3eMd4E/A18A/gMXO+r7AQ0AJMBN4AvgUOA34QkTODt6RiJwL/ACMBJY627wDJAN3BLU922n7B+A759hzsB6mhSJyZASyTwdygN+7xmoQFwAtgf8aY4qq2q9oISJdgO+Bu4DtWEPkDUemWSJybdAmU7Dh4anAK8A/gS+AQ4FI5HwAeNlZnud8fgCY68jTEqv3u7Dn8R9YfR0PfCIi14fZ7/HAl0BDYLJzjMII5AEwwG2AAH+PZAMRScXm+07C6nMq8B/sc8W/8PoYDS5xjpWLp5/qnKtBznYNsSHBHwAnAXMiHbSpgP3Oe1G5rRRFUZTqY4zRl770pS991eILWIc1ILoGrZ/rrP8FaBtiuxZh1h+EDVldFrS+LfYhvxAYHGo733IrIBvYAfQLajcA2AP8EGH//u3047wQ3810vju0qv1yvjPA3KB1U0KdV+e7Ic5340Oc8xLgd0HrW2Lzl/cCB/jkLAEWAckhjtEmwvMTUpagc/dvQHzrezm63Ofvn29fBri+kr/DUc52DzqfP3A+nx9i/68FbTveWf8v/7nADpK86Hx3QSR99l0T68LIVwKcHeVzNSpoX9c765+pzDkMIVMKdvDJAEOrsy996Utf+tJXxS/1zCqKotQ97jPG7AheaYzJCbN+I/A2cIiIHOz7aiTQHHjWGDMvzHYuV2INuHHGmF+D2i0BngcGiki/COR3vXIj/StFpAMwFPjRGON6m6vSr6ggIocDg4F3jDGvBx17FzAO67272F2N9V7uwxpYwfLurKY8acDl2IGDu40xpeG0xphVWC9wGlZXwfxkjPl3dY6P9dQXA4+G8aq7ciYBfwa2AmOMMcU+OYuBW7HnKlr5t+8ZY2YFyVCdc/WVMWZK0LrJWE/qMdWU9W/YwZ8PjTEfV3NfiqIoSgVoAShFUZS6x8JwX4jIicDN2FDK9tgHdj+dsJVVAY5z3j+K4JhuburhYfIaezvvfYFfQ3xfijHmaxFZCQwTkVbGmGznqz9gPXdTgrepZL+ihdvnFmH63M557wtgjNktIjOAYcBPIvIONrT3W2NMfhTk6QM0xhpbWSG+/wy4FxgY4ruwv5lIMcb8KiIvAtc5r2fCNO0NtAZWAfeKSKg2e3HOWxQI1bfqnKtFwSuMMftFZBs2QqFKiMj/YQ355cAVVd2PoiiKEjlqzCqKotQ9toZaKSLDsZ7KAmxO6WogD+slHIL1MjbwbdLSed8UwTHbOO/BOaLBNI1gX2C9sw8Bv8NOYQLWU7sfm19ZShX6FS3cPp/pvMLh7/OlwJ3A7/GmXSoQkbeB24wx26ohTwvnfUuY7931LUN8F/I3UwXux/ZtnIi8GqaNe956Yb3X4Yj0t1IRofpWnXO1K8w2RdjBlkojIjdhc6l/BU4PY2AriqIoUUaNWUVRlDqGP2QyiAnY/NdBxphl/i9E5N9Yo8/PLue9E14RqXDkOO+HG2N+iVzasLyKlXck8KyIDMQWSXovREhxZfsVDjf0N9R/W8sQ69w+32yM+WckBzDG7MXmi44Xkc7AKdjczsuBrsDJEcoaCleeDmG+7xjULkC0ahzX24kx20RkItZQvws7uBCMe/xpxpiLItx1eboBq59d4cQqR4aqnKuoIiK3AE8CS7CGbGZNH1NRFEWxaM6soihK/NAT+DWEwZeErcYazDfO+zkR7NttWx1jrBRjTAY21PNYp0Ksmz8bqsptZfsVDjecuXOI70JNOVOtPhtjMowx/8XmAacDJ4lImwo2K48VQD421LtliO9Pdd5/qMYxIuHv2MJbY7BFuIJZjjU8j3OqGkdCWN2ISE88T2uk1IlzJSJ3Yg3Zn4BT1ZBVFEWpXdSYVRRFiR/WAb1E5EB3hdiExfFAqMJMLwO7gRtE5JTgL0XEb6i8hDVQxolImSI4IpIkIkMqKe8U5/1q4DJspeQPQrRbR+X6FQ43tzIgVFpEDsXm4wZgjFmEzXm9SET+GGqHInKoiLR3lts5+wqmCTaktojIp8MpgzGmEPgv0AzrrfbL0QP4P2yYdrjw36jg5P/eBzQiRBixsVMq/Qvr/fyniDQKbiMiHYOKhS3H/hYvcM+n064RtlhTZWWM+bkSkfuwBZ++x3pkyxQxUxRFUWoWDTNWFEWJH57EzrP5o1N8aD9wItbgcwsTlWKM2SEiv8fmo34uIh9hp/1pDhyG9ZJ1c9ruFJFLgGnANyIyBzsvrXHaHY/NlWxYCXmnYQ2YW7Dzsv7LGLM/RLtK9asc3sMWJbrMMdS/BQ7Gzm37HjAixDa/x3qQX3QK+HyLNeoPwp6jAdi+Z2LDtX8UkcXY85iBPZfnYcNd/2mMyY1Q1nDchfUU3yQiRwOfY6dYGoE13G4yxqyt5jEiYQpWb6GMd7AG5OHAaGyhr8+wudntsbm0JwL34BQLcwosPYU1kn8UkWnYZ5AzsV7gzVWQMWbnSkRGAn/FVn/+Evi/EIWw1oWomqwoiqJEETVmFUVR4gRjzL9FZB/WyBiJrRj7JXAVdvqYMkafMWamiAzCFi06HTgLG/K5HHgkqO0cETkMuA0bOnsy1tO4GWvwvVNJefNF5C2sZxZChxhXqV9h9lMgIqdjw2TPBI7G5jH+HsgihDFrjNkoIkdhp5q5GK/i8lasIfYvvHzjdVhP5RBsGGtbZ78rsIZVwPQ+VcEYkyUixwN3AxcBf8Gej4XARGPMJ9U9RoRylIjI7cCsMN/vF5ELsbnCo7AGfVNgO7AWa7T+N2izcdjQ4Gux1ZK3Ys/ZeCqokB1Ghlieq27OezL2dxuKeYSo3K0oiqJEDwlfZ0RRFEVRFEVRFEVR6iaaM6soiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqIoiqIoiqLEHSmxFkBJbESkBTAYyAAKYyyOoiiKoiiKoiixIw3oDMwzxuRU1FiNWSXWDAbei7UQiqIoiqIoiqLUGS4A3q+okRqzSqzJAJg+fTo9e/aMtSyK4mEMLPwPJKfCUVeBSKwlUhRFURRFqdekp6dz4YUXgmMjVIQas0qsKQTo2bMn/fv3j7UsSg0zcuRIXn755ViLERkZ38EGR9aho6DDgJiKE2/Ela6VaqG6ThxU14mD6jpxqMO6jij9UAtAKYpSazz55JOxFiFy9mwLvaxERFzpOh4o2B1rCcKiuq4kG76FF8+CJe/EWpJKo7pOHFTXiUO861qNWUVRao0XX3wx1iJETmGebzk/dnLEKXGl67rO9Bvh0a6waHKsJQmJ6rqSfDMJMr6FeRNjLUmlUV0nDqrrxCHeda3GrKK4pM+Ghc9DSXGsJam3HHPMMbEWIXL2+43ZvPDtlJDEla7rOj+9BqYYPhgD21fGWpoyqK4rye4t9j1/Z2zlqAKq68RBdZ04xLuu1ZhNMETkaBF5WkSWikieiGwQkTdFpHcE244SERPm1aE25K8x9u6C//0ePrwNVs6KtTT1lr1798ZahMgJ8MzuiZ0cVWVvNkw61oYz7q/98x5Xuq7LFAWlDL13Y/kDbjmb4MfXoKDC2Qyihuq6kuRl2vda1FG0UF0nDqrrxCHeda0FoBKPO4ETgbeAX4AOwE3ADyJynDFmSQT7uB9YG7RuVzSFrHX2bIPifXZ5x0rg3JiKU19ZvXp1rEWIHH9ocTx6Zpd/CNuX2+UVH8KAi2v18HGl6+pSUmwNk8ato7/vvVmBnzcuhKXT4NBLQrd/9zpYPx82/wTn/j368oQgoXQdDfZst+/F+2B/AaQ2jK08lUB1nThEQ9fGGHJzc9m9ezf79+/HGBMFyZRok5SUxJo1a2r0GCJCamoqzZs3p1mzZkgUZ4hQYzbxeAL4vTGmdLhfRN4AFgN3AZdHsI+PjDGLaki+2LAv11t2HzSUqOOUWo8P/N7YeDRmN//oLS+fWevGbFzpurpMvwF+eQMueAYG/iG6+w4ViprxbWhjtjAfNiywy2s+j64c5RCRro3R6a3A3kv8KQwFOXFlzCbUdZ3gVFfXRUVFbNq0ifx8OzCckpJCUlJSVI0YJTp07969RvdvjKG4uJiCggJyc3Np3LgxnTp1IiUlOmaoGrMJhjHm6xDrVonIUqBvpPsRkWZAvjGmfiSY7vNVCs1TY7ammDBhAs8991ysxYiM/fmhl+MFvzG78hMo2gcpDWrt8HGl6/IoyLGVhFt2Dv19fhYsfssuf/YgHDbCzk0cLUIZs9uWQu5WePl8aN0dfvdfSEqGLT/Z3FqAnelWtprwFgdRoa4/vseeo9++DF2Or3F56jR7MgM/F+RAswNiI0sVqDfXtVIh1dV1dnY2+fn5tGjRgvbt20fNcFGiz/r16+nSpUuNH6eoqIjMzExycnLIzs6mXbt2Udmv5swqiB0mOwDYEeEmnwO7gXwReV9EetWYcLWF3zOblxm+nVIt4uohKB5yZosK4df3IC/I4CneD1sXe58Lc2Htl7UqWlzpOhz798Kk4+Afh8L8f1jvYjBrvwBTYpdzN8PPr9tCTdNuiE4VbL8x22mQfd+2xB5nxwpY+RFs+sGu3/hd4Lbu+hompK7zdtrzVZADC562qRwf3V4r8lSb4iJY9akdDIg2wYOlBbuif4wapF5c14lIYT6sX2D/GyKkurres2cPycnJdOzYUQ3ZOk5tGLJgvfMdO3YkOTmZPXui91wV98asU3xovO+zW6SoaxX2NcTZdohv3VwRqTCPVES6OtuO8q0bLyImqN06EZlSWdlqmD8AnYA3KmiXD0wBbgSGA48BpwNfi0gYt4WHiLQXkf7+F9CjWpJHCw0zrhWGDRsWaxEipzAOqhm/9yd480qYdn3g+u3LvRxwl+Uf1J5clKPrVZ/Ctl9rVZYqs/lHa6BiYPY4mHV32TarPwv8/P6f7RQ6P0+Fr/9VfRn8xmy3U+x7QQ4sedtb74YWBxuzwZ9riDK6/vE1mNjdyd9d4K3PCi61UMPsWFV5g9QYeGsk/PcSmDY6+jKF8szGEXF1DzcGFkyysxQkOtOug5fOhi8iz6Ovrq6NMaSkpGhYcRywatWqWjuWiJCcnBzV/Ok6acxWUDXXiMhxsZYxWohIP8fo7Rqj4x8CTAIWAC+X19YY86Yx5ipjzCvGmOnGmPuAoUAb4J4IDvcnYEnQ6z2A+fPnM2/ePCZOnEhWVhYjR44EvJvpmDFjSE9PZ/LkyUybNo2FCxcyYcIE8vPzGTFiREDbsWPHsnjxYqZOncrUqVNZvHgxY8eODWgzYsQI8vPzmTBhAgsXLuSX774qFXL31jUBbUeOHElWVhYTJ05k3rx5zJo1i0mTJrFp0yZGjx4d0Hb06NFs2rSJSZMmMWvWrJj2adq0aUyePJn09HTGjBlTJ/o0Y8aMuOnT9994nsw92Zl1Tk8TbrrUC29d/Rk333B1aZ8Wf/JqqezFLZwR1xUfcv6w82rttzd8+PCyfVr8Nvz3EswLZ/LkYw/X+G/v9b+OouRfg3jympMD2v7nnlGsnzWJqf99rbRPE8feCHP+yqc39Yb3/8z/XX4uhRuCSgN8+ywZC6b5+nQerLa5qQb3gc37gy756h/cdsOoavVpZ4b3kLF8X3tPFr/nfcM3jB17N/vXBmaRrPx8aoV6qvb1lD6H4T0K2bRxY2mfdnxl/0rM4rf45vm/eAK17V1r972NX70BTw+C507i4vN/U36fMtYx87YTYN5jvHrdEd7Az6qPmfT001G9l0//738CdLRhVd2671XUpzfeeCOqetqwaBaP3jqqRvr01+vPh4/H2lkKNnyTkP+5pW032bSTvCUzI+7TfffdV+0+5eZaR8H69espLCwsDTHNzc1l69atFBUVsXatHeRyDaqMjAwKCgrYsWMH2dnZ5OXlsXnzZoqLi0uLUrltN27cSH5+Pjt37mTnzp3k5+ezcePGgDarV6+muLiYzZs3k5eXR3Z2Njt27KCgoICMjIyAtmvXrqWoqIitW7eSm5tLTk4OmZmZFBYWsn79+oC29alPLrXVp+LiYhYvXhz2t+d+FylSFyuLOd7NlwhdNRdgljFmh9PWAA8YY8Y7n5OBVGCfqWTnRCQJSAMKjbFxYyIyF2hrjBlQwbYCNAD2u3mkjsd4nDFGfO0aACXGmP3O50uwlYVPNcbMrYy81cWZTucr7Pk6zhizuYr7WQC0M8b0rKBdeyA4QL4H8N6SJUvo379/VQ4fHeY9Bp8/ZJclCe7bYXPQlKgyevTo+AlTm3y25/HqdgqMnBH9Y2z8HpJToOPhkW+TuxWKCmweot/bevm70PN0u/zBGOsdTG0CZz5gH+YARs+HDodGT/5yCKnr8S285f/70eZ71hRFhTY8eM9WaNkFbvnFrl81G/7rFMPqdRacfJudY/rrf9rz6tJrKDRpCz/9N3C/Q8bCkDvt8s7V8K8j7fLxN1kPUPE+aHeIV0n6uD/B2Y9UvR8f3QnfPgcNmsPNP8Nj3cq2adQarv8C/uH8TSWlQsl+aNgS7lgLSTU0bp2zCZ46DEqK4PdvQu+hdv2k42D7srLtDxgAN3xVdn1NMPNW+O4FuzxyhufVDsXS6dYbG4o71kY373juozD3Ye/zuY/D0ddEb/81TFTv4RkL4aXf2MJgN3wNbaOcsbRosr0XAgy+E04da8PfG7WquWuirvLwQTbdpFEr+5uOwFtaXV271XFruriQUn1qK2fWpaLfxtKlSxkwYADAAGPM0or2V9ev5o+MMa+FeIXN7TTGFBtjCipryDrbljjbllRhW+NsW25BJGPMPteQjSUi0gL4CGgJnF1VQ9YhA6jw394Yk2mMWep/AXWjzr8/zNiU1EyulMJ9990XaxEiJ6CacQ0UgEqfDS+cDi+cCVkRlsTfuhie7A9PHV42bHjdfG9580/2veNh0OM0b/2aebDoJZjYC2beZudXrizG2EJH791ki0qFoYyug9vuL6BG+fU9a8gC7FoPuzJsf9//s9dm1Scw+Sz44jHPkE1tYt/XfQkbHc9st8HQto+33sUfYnzE7+Hyd+Dsv8G1n0NX6w3muxcgb4c9bztXQ0kl/17ce1GjVtaoanZg2TZ7s+Dn/3mf+w+37wW7IKsGb7Gbf7SGLHjzcxsD2etCtw9VzKqm8F8P/uVQ+IulBROuL5FQUgyfjoN3rrFRCYV5ZWsyRDPMOHMZPHeyvT5riKjdw0tK7EBNyX4oLqyZNAj/fXXtl1YHE7vD26Oif6y6THGRNWTBzj+eF1l5lLj6v1aqRceOHWMtQrWo68ZspQmVMysiSU4o72YRyReRz53w3oD81VA5s77vjhKRr0Vkr4isFZHRQd+XyZkNI1/pMZ22Tpwgn/vCqIeIyMsiskNEypTFFJFPRGRFhKcklAwNgRlAb+A8Y0x1E9i6A/GdaOo3ZkErGtcQ06dPr72Dbf7JPtQF56hFSjTnmV01G6Ze6j00FxXaBzmM9eQt/zD8trsyYP3X1khYOs0zHgCSUqD5QXZ5vePx2rnaFggCOHCg9X62cFLaV8+x5yQvE757Hp4+GrZX8lay+jP4YiL8+KrNjQxDGV37jUCofIXonattDuPqCKec+fbZwM/rv7I5r7nOuF37oEiQAw6FP34C5//Tk2+Hc246Hg7dHOM0Y6FniK+Za9+bHgDt+9k2x90AaY3hFKfYUXGhPWfzn7Be3BfPqFxevmsANm7jyOmTW3zRIwud8NWklEBPX03mzWb6vK9r5tn3PZlQtDd0+/ys0EW0os2e7Z5nHCo2Zt3rBawnffBd3ufqGLMLn4ev/mHTAd65Gp49wV7PfsozZrevrNz9a/Z42PqLvT63/FIVia2RWVwU9uuo3cN/eQM2+wqURXpdV4adPmN243dWB2AHuhIJ/2wN4N3XKqBW/6+VmLJr165Yi1At6rox20JE2ga92lRhP48A44BFwO3AKuBjoEmE27cCPgS+B+4ANgLPisgfqyCLny8A58mJh4ErnNcy4FVsLupQ/wZOaPBpQPinyHJwwrDfAI4HfmuMWRCmXUcROcRvTItImRraIvIb4ChgVlXkqTOUMWa1onFN0KNHLdb7mn6Dfaib92jVto9mAajPJljP1dy/2c/fPmenTnFZPcdbLimBrUts1cn9BdZ7+9I5sGwGbPjWtml2IBw6Ai76D/Q7367b9IMNYXzmOGtAARx8vA0nc0MsV38G+b5R+bxMT6ZI+X6Kt5w+O2yzMroONtgra8x+MdF6H0MVYQom4zvY9H3guu+n2KJMAD3PsCHXI16Bi56Hm76H0V/CwcdaL2wwHQ/3PK3F+2DjQrvsVgt2z7OfLidAWjO7vOpTWOiEvG763hq02YG5SmEpz5jtcRo0cEK33QG4g46BTkd5Hua1X0R2nKqQ6Yv+yloNuzZAdjlFnor3lb2WCnLgyydsyH20WB9kvG5cVH4kwDanHwMusSHhx//J+25XhHoKZvfmsh7S7HXeAIhLOGP266dh0tHwRF94+2p7bgG+eRb+fUrZStU5G22kgctX/6ia3NNHw4S2sCL0X3pU7uHFRTDnr4HrNnxjq4dHE79ntiQoIK6yERLxzN7swM87Vka0Wa3+XysxpUGDyk3bV1JSwpQpUzj//PPp3LkzTZo0YcCAATz44IMUFNRw1FUI6roxOxvr8fO/NlVmByJyAPAXYLox5nxjzCRjzHXAC0DbCHdzIPCoMebPxph/YSv4/gQ8EspzGinGmDWA66741BdGvQ34DGs0Xx602WVYvVXJmAUeB87Hhhi3FpHL/S9fu0ewRnUn37qvReRNEblDRK4XkX9jCzhlYI3x+CXYmNWKxjVCo0aNaudARYWeZ8YNua0sfmOrulPz5DrhrlsXw749Nkfbz/qvvQe5j8fCcyfCrLsg4xs7pQnY3E3XQOtzNlz8PAy4GLqcaNeV7Le5eMWFgMAx10FfpxplsIGW2gR6OPm1az634ZDl8d0L1ou7YBKs8Bmla+bZcx2CAF0bAys+CmxQ2dBt19OUu6XitovftO9JKdDhMLu8wTdud/ajNmeu3wV2Xti2PT1jtGk7m9vpx2/MgjUQ92R6Xt4DjygrQ3KqN4iw9F2vLVij5pNIaubhhRmXGrM+2bqcYA1wl0atbQ5mcgp0d3S+6tOae3DPDMqLXTMv0JPpGtp+9galcHz9NMx5AKaOqNS0IQHMfRSePsa71oM9scX7wnuo83Z6v6kOzrlt2MKeS6i6Z3bW3V5o5wWTAmXxExzqbwz8NNX7fZQU2crVUy+1AwGzx8OWn+Hbfwdu98Mr3hRRYKM4XGMub4c1Fivyimcusx5TjJ1OKQRRuYdnrfauh+5D7HvxPnsfjBYlJeUPrNTV6dZqguDpn7ZHZsxWqOvCvNqJtFBqnKRK5pDn5+dz1VVXsX37dkaPHs0//vEPjjnmGMaNG8c555wT1UrFkVDXjdkbgTODXudUch+nAynAM0HrKzNnQhFQ+s9hjCl0PrfHeiWjjpO3+1/gfBFp5vvqD8DXxpiqznFwhPM+DOv9DX6VxxtAL2As9vydDTwPHO0Y4PGLemZrhYULF0ZnRz/9zz7UhTGk2LXBe7DbvqLyf7jGBOXMVsMza4z3AL97k/XCug+5/S+y70UF3oOc+yD+8+uw8mNvPytneeGbnX0GTJcTAo/XojNcMxt+M9Ez0LqdHNim3wX2BXbUfsvP5cs/91E7mv/x2MAw5/15gUaijwBdZ/4aaMy520ZKcRHsdKr6FuRUbHy7XqtOR3n5oy69hlrjtTz8xn9qE2jdA5q08UKT134ZGMbZ8YjQ++np5Cu750ySvIf3VbPLGvTbfoXH+8Lrf/AM0GDP7MHH2QJPiC1g1cdW6qVRKxj5PhzQz352izHl7wgM54wWRfsCowvAeh39xt8V78KRI+H0cd664LzZjG88Od1Q+cqwv8DmPO9YAV8+bte511D7fl67cKHG/hBj/0BBK6cYSkXG7P691uu/w3cuNv8Ev063y/0vgoGXh851Bs8zawx8/ojNiZ9+g13XoAV0P9UuZ/4KC57xcrszfdlBxUXWmAVocbCzvxL44nFryD53MkweWraYWTDf+yY0WP91yNoRUbmH+6doOu5Ge12AHViLFrmbAwu6BZNQxmyQ9z/CMONydZ0+Gx7taqeGU+oEBQUFlFRx4DIvr3LPOGlpaXz11VcsWLCAe+65h2uvvZbJkyczbtw45s6dy5w5cyreSRSp68bsQmPM7KBXZe92bnmugH9dY0wWkF22eUg2G2OCNe0ObXWtpDyV4RWgEXZOV0SkD9Z4rsjoDIsxZogxRsK9fO1GOevW+dbda4wZaIxpaYxJM8Z0Mcb8Ke4NWdCc2Vri6quvrv5O8rPgvRth/pNe2Ggw/vCywlwb8lcZivYFejmK95WbR1YuhXle2C/Aj74HylPHenmPbjGh3U7wSeEeW40zFH5jtnFrOOhou9yqK1z1IRw0KLB98wOhja9S6BGXBRaGWl3OH8/uzWUHd1p39x5Aw4QaB+g6Z2PZBpUJKcxa4zuHpvw8w+L93rQ1Bx4JXU8K/P64COYOdQ1OsN46d9TaHRTYtCgwBzhcNWrX++3S5UQ4+lq7XLS37MP73EfsQ/jyD+wx9u/1jH63om7LznDd53DNHCvbkSPhiulw48LAStW9zvKW/YMi0WJneqmRbpKdELU1c71rr9mB9nd4/j9tGLaL30AyJnAgpbzccf82G761huv2FTZE2B0sSJ9tw7fdqIx+F9jK0mCNy1CDNmGN2a72vaJw8Ll/gxk3w3+GeKHSXz1l3yUZzhhvlzsdGXp797e8/iuY9zfv+k9pBJf9D4Y95bX90jdH6PYV3qDOyo887/Lg26H32Xb5p9dgyrneQJJr8IZifwH88rr32RSHvLajcg/3e0w7Hm4HnQBWz63+vj970Hrp/XmxwZEWYCNkEoVg7/+OyOYULVfXyz+09+Rl70dcUKq+MX78eESE9PR0Ro0aRcuWLWnRogVXXXUV+fllI49ee+01jjrqKBo1akTr1q353e9+VzqNjkvXrl0ZNWpUmW2HDBnCkCFDSj/PnTsXEeH111/n3nvvpVOnTjRu3Jjdu21+9FtvvVV6rLZt23L55ZezaVNgYOuoUaNo2rQpmzZt4vrrr6dp06a0a9eO2267jeLi8geM09LSOOGEE8qsHz7cDh4vWxaimn0NUteN2YTGKcz0PV6o8eVAIfBmzISqrwQXSNAw4xrBnaeuWuRstA9a4OWQBhNcHdhfDCYSQnliK+NJ9BOcr5T+qX1vfpCdisI1PNPn2AdKfxhmKM9C0wO8B22Xi563obPXzIGWB4eWo6+dY5Y2vaDLSdYoatvbriuv+EqoSq+n3O49gIYxZgN0HXwOoHJhxsHTvASHzfnJXOaFch440L5SG9vP7Q7xPF3l0eUEx/tJoNe15xn2vaTIm/alxcHhp25p3S1w+qH+F9pBhBQnfG/5TO+7nI2Bn5dOCzT8XM8sWKP1IOf8JyVBj1OhqW8OWrADGK5xuypCY3bh83agKJIKu9s8z+DcbKcSZv4OL2/T/xv1nx9/n3atDzzW8pnlR1Hs2mCNxsln2ZzLN68M9Drvz4dp13ufu53ihXpvX25zTb8OCp/d6hizjVpDsw7e+pbOOHhORuBAVnGRjQr57CG77M71XJgLrw2HH171vLIDLvY8vBUZswucUOSUhjD0EbjpO+h6ot3e1aP/flC8z7vPuSHHDVrYY57zmBcm7b/3ZXwbfmBv2Yyy1+mKsoMLlbqH7y8IPQjoertTm9jfrXtNblsc2UwC2etCF8ba9qvNrd+xwlaRdjnjATu1lZ/CoAHs+kzw9ZyTEZExX66u/QOcGWH+hxOEESNGkJubyyOPPMKIESOYMmUKDzzwQECbhx56iCuvvJJevXrxxBNPcMsttzBnzhxOOeWUahVfmjBhAjNnzuS2227j4YcfJi0tjSlTpjBixAiSk5N55JFHuPbaa3n33Xc56aSTyhyruLiYoUOH0qBBA/7+978zePBgHn/8cf7zn/+EPmAFbN1qU6rato00izM6JIIx6w6rBsSVOYWkWkW4jwNFJLhYlPMUyLqqiwZARfGPrwCniUhH4PfATGNMpB5lJVI0zLhWePnllytuVBF+3WxaFLpNdY3ZUIZrVUONg3MEXY9vp4H23fXebV8WGDrop5HvVtX52LLFhlp3sx7HJuX8gQy5Gy581oZ+up5G1zub8W3Za8Bly0/OgsAtS+Caz+DwyzzDLvNX+OWtMpsF6DqUMRvJ4MCOdFv9NTNIf6H25+I3vg8caHNXT70HWnULDL0ujwZN4Zy/2fPj9+R2H+IZCW6Y4oEVzBHsnidJgr7n20rHPZyH9xUfeQ/7i17yBmnAepb8xbr8xmyk9HJCjbf87OVthyNno52P+MfX4Kt/lt8WvN+qJHPqPe8Cznl1ddPaNx+uX3b/9RDsKd290VbjDccPr/p+j9jreun0wDZu2Hv7/tD5ODj5Vps77kYSzHs0MCrA9cx2GBD423CN8ZIiz1sK8OMrNirki8ds2L3/u4IceP8m7xo/6RbvuwODjNlmHb1tdqR7OeWH/84WoGrZ2Wt7yHllzwVYHWxd4kUJHHkFpDWxBvBvX/L6nOp7fFnmzJe9bw/MuMWrSP6j47Vt1NrLtV81u0wqR8T38IyF8LfO8MoFZXO23TDjVl3tOe/g85y6ha4AvnsRnj3J5vuW9nk5/HMgTDqmrEH7tS97zC34lJxmr7e7NgTOFZ5IntlQg387K/bOlqtr/4C/Xz8JyMCBA3nnnXe44YYbeP755xk+fDgvvvhi6ffr169n3LhxPPjgg7z++uvccMMN3H///Xz++eds3LiRZ54JzoKMnIKCAr7++mvGjBnDXXfdRWpqKnfeeScDBgzgiy++4JZbbuGRRx7hrbfeYt26dTz55JNltr/00kt58803GT16NG+//TYDBw4MkL8yPPbYYzRv3pxzzqlsRmj1SKnVo8WGOdic1xuAT33rb6rEPlKA64EnAEQkzfm8Hes5rQ7uE13LMN//D1u06SnsFDi3V/N4SjDGaJhxLTFs2DBmzJhRccPy8P+J7lhpQ6gatQxsE1z4Ixqe2aoas+E8De7DrZvjCKELoKQ0hBNvgdmOp+Hg46omR0oDOxeqnx6n28rKJUU2RNR9iPXjGodte9kHbPche8AlNtSzuBDevcZeM74qsAG6DmnMVhBmvPkneOEM+3Duhoq6lDc/ruupS2sKbZwxzBNusq/KcPQ1gVPcgDWM+10A37/krQsXYuxyyh22iFeP0z3v6SHnWq/X3iw7kHDQIPjBeXBMSvEMqJW+6rThvL/l0XuoF5q69ks47Lfh2/qvkUhyV93iT216MGzULcy4+KTA0Gu/Z7ZhS2/ZnzNbaswKpeO6y2eGP6eujJLsGf7BlYtdBt9hB22adYBLX4Ml78LbV9konBUfWg9m8X5vn8GhqH75d623BmJxkRdCDLDQLaUhNmXgyye8vPZeZwVWnj5wYOD+2/S0ocEFOfDNM17/j/sTZTjkXBuCHkzmMl9khMAx13rfdR8Cw/9t83lPuw/evQ5yNljj/9jr4et/2t/x9y/ZnPC1ju4OG2HTFpbNsN7L9fMDUhKuuuhMXnrrQ3stlMc3z9h7w/r5sHZuYFqDe392Bzzc6cXA/u4PPMKel4/HWm/0rLvgurn2+/Xz7WDB3mxbV+DE/3O22+x5yf206gpJTipHA1/5kXCDd352pNt+tjw4skGwukqoSIsdq8r+JoMo9//aP6hcFWP2o7u8dJBY0+FQO3hZRUaPDkxdOfnkk5k2bRq7d++mefPmvPvuu5SUlDBixAh27PAGKDt06ECvXr34/PPPGTt2bJWOPXLkyIBCXYsWLSIzM5Px48fTsGHD0vXnnnsuhxxyCDNnzizjNR49ejSrVq2iV69epfK/+mrlsxkffvhhZs+ezTPPPEPLli2r1J+qUteN2XNE5JAQ6792KgFXiDFmm4g8BdwqIu9jp5A5HFtIagcVe0YBNgN3OnPXrgQuxRZSus4YU8Xyi6X8BBQ7+28B7AM+M8ZkOvJvF5FZwG+BXcDMMPtRqkrRvrJl+zXMuEaotiELZb3mm38IfFCCEJ7ZSs6lGioEtqoFQ4I9sy5u2KH/oTlUMaWDj7cPmF9MtL9VNx8uGnQ90Rp9hXvsQ/oh5wU+tBnjVYgNfvBp2xP+8Da8cQXsy7EVaQddBan2jzVA167x2bCFM+VQfsWDA7+8Ya/Lgl1ekaDS/UXgme14hOeBjiYDLg4yZst/IKRpOzsFkJ/eZ1uvmSmxIal7tnkDaKePswMXpsQLZYaqeWY7HOYdp6IBHb9HzB9u66ekxDun7rQ87fsyY8YrNh8znDGbnGIN2oJdgYM7rjHbtrcdbNn6iw15PzXMg507pUjP022RL7/nuuXBXh/a97NecD+HnOvJ8PPrVo+Zy7xcbL/hCV54MNiw1m6nWF2FKgh18HHWeD7mOjt91M50b55hl0YtrQHrFs1q28uer5L93u+p55nQrk/Z/R8wwOtf6x52m10bbFErt0pzn9+UTT84bIR9gZ3Ca8HT9h6TuzUwP/mdayh9FBpwCbTxTcmy+Sfv/rrkHV46bCG8OhxGfVBWTpf9BYEDMT+86u2jpMTLQ3blbeGbNCFnU+mxSsOqN/9oC651PCzwd/rja3DCn+0969vnvP9x954GgWH+aT5jtqL7+fIP4fXLHPk629znQy8pf5u6inv/bdDC9tsU29+N+9sIQ7n/1/5npC0/WZ2nNgzbvAxbF4cfiIozDj44MLWnVSsbSZWdnU3z5s1ZtWoVxphSYzGY1NQqT4pCt27dAj6vX2+vrT59yt5HDjnkEObPDzznDRs2pF27drRr58282apVK7KzKxcA+sYbb3Dvvfdy9dVXc8MNN1Rq22hQ143Zv4ZZfxUQkTHrcCeQD1wLnAEsAM4C5gORTIiUDYzEVvC9FtgG3GSMeb4SMoTEGLNVREYDdwMvAsnAqYD/if0V4DzgTWPMvrJ7UaqFf4Q2tYkNf8zLtA/y8TwaWwcZM2ZMmTCXShMcWrbp+0BjtriobNGW7csrp89QDzpVDjMO86fg5mL6H0D9ntnDfmcfno+/yeY/3vSdNQT9D9nVJa2J9dJ8+bh9uFn1KfT2FQ7K2egZDKEq9nYfDEMfhPf/bB88czaVVgoO0LV7Dhq1stfb/vzyPbOhpvLxE+6c7i/wcjlDTZcTDbqcAE07wB4nbLfjYZXfR5O2tmLyms9h8dteQZaGLaxBtOoTa+i4x4CqGbOpDW3uZ/baiueW9Ffj9Ye1u/zwCrz/f9ZoO+xSz6g4YIDV9cPjYOZtXr5yq8CHLBq3doxZxzPrHyjpeLj1gG39xebzhaK4CHautsvt+tgcyCVve9+ffBt8/pC9P5x2X9mBjJQG1oBd9KLNT8/d5uWvQ2CRKrAGjDsQkL3Oyjvf+T03bmuvxX2Ox8utDN6oJRxXzoPcgUd6xqwbNQBeWHKoyAiw962hj9j+nXoP/PiqY8z6Bg+OvT70ti79LnSm2zHwxd9tfqrLbqdAW4uDbZSAiD2/+3YHToXl5uau+9LeD9OCs68c1nwemEaw/AM7iNG4tS1GVfob6Wrfm7S3Oeol+z1Z3PBnlx9fhY4TA+/tO1bY+1anQXaAAqweOx3lTS3U2meYN2jqLVfkmfV7eXMy4ON77O8nHp8JXM9s03bQ/AhYO8+mMZz9N89rHYKw/9eF+YE5x8WFdsChy/Fl24bDX6wu1lRTluTk0OfQnZ6mpKQEEeGjjz4K2bZpU+93KWF+X8XFxSG3re5UWe4+MzIy6Ny5cwWtQ/Ppp59y5ZVXcu655/Lcc89VS56qUieNWWPMFGBKhG0l6HOZbY0xxcD9zgsAEWkJtMHO5eq2m0tp4k/puiG+j2VLd3nt1oXYdjwwPmhd1xDbvoCd9zYcbtJKVeeWVcrDX/ypdXf7J19caP8AgsNXlWpx4403Vn8nwZUT3QqiLrs3eiP07Q6xhmxBjvV+hfM4BbM/lGe2kvOiuuSHMLxa9/B+Ww2a2Yfj/B2eFze1MQx/Di7yzSXZPMzUHtXl+Jts4Z99u+3Dcq8zvQc2f35iOOPQb4zv3lhqzAbo2jU+G7Z08ud2hj7HLttXlD9HZLgCUJlLPd1XEEJXZZKS4fBLrSe7be+yhZci5fDL7EP/3iyvqnH/i6wBevhlgYYKhDYwI6Ftb8eYrSBHzm/sBv/WjYF5EwFjBz783sl+F3Bjp2T7e+5ztldFNthL2LiNjZhwf+O5W3wDJYd7v5E926zhmrPBGtju7zF7rafbtn3ste03ZrudYvOT92YH5mD6Ofwya8yaYuv5d6s8t+kV6I0Ea1y3OMgajVlrrRfXza89brQdjPnycScXOowRGky/C+wcyAcdHfpeVN5Ddd/zvCJumxbZqbpcDhzoFboKx0GDoF1fm5v/XZhx+AHDvWu/+YGwfbdXMGrXhsBCP1lrwsvr5uW6FBfCN89aQ98/LY8bZpyUBM072mPkbLIDUu6c2u6Awi9vwJl/tSHffn581Yadu/NxH/pbG/XiGrP+abjSfMZseZ5ZY8pGyezZagci2ob2rtVp3Ptlw5bWIF87z56vdfO9+ahDEPb/OlRNkYxvKmfMViOsN97o0aMHxhi6detG7969y23bqlWrkAWh1q9fT/fu3ctuEESXLnawe8WKFZx2WmDE2ooVK0q/D8bvma0M3377LcOHD2fQoEG8+eabpKTExqxMhAJQiEiooYtbnPe5tSdJlbkW64muHzEZdQ3/CK2/aEmClpuvSb744ovq7yT4j3TTosAKqP4Q4z6+IgSVyZsNmTNbzTDjJN9NPriyafCDf7OOtecBaNwajnceWrb8FFhR1/WcITZkNRTN/SGC3hQ8Abr2e2bTnMrC5Xm6V/q8su60L37C5cz6px4JVz02Ggy+y06ZctnrFbcNR9/zAh+uwctpPvQSW7XapUGLinMUw+E+fGetLn96Kb8xG+y12vKzNS7B5vP+8oZd7nwstOvj6fqEm22l5p5nlC1G5hbOcj2z/uJPHQ/3BmtMifXevXwBTP2tV9THL1/b3oFVqRu2tNdQi07hDVmwBp07RdWCp22RIrBGeCjceYU3fhdo3BwyzOZCn3IHXPKSNXojoe95cPMvMGqm9cL7kSRo3zey/fjnzwU46S8V3y9EAnLaAesR9Vf5HXCxt+zqwy1wtXRa4LaulzyY4v1eFeQ+53pVob94DB7rbouMufi99y06e8fzz4d72n32vSDH3pv8YcYAi9+xUxC59DnHRpEMvst6o/19SmtCqc+hvAJQ2es8j/QRl3vrgweY4gV/mkffYV6l9iXvlLtZ2P/rUGlYoeo9KABcdNFFJCcn88ADD5R6a12MMezc6dUR6NGjB9988w2FhV7htQ8++KDMFD7hGDRoEO3bt+e5555j3z4vkPOjjz5i2bJlnHvuuSG327On8s837v66du3KBx98UG0vcXVICGMWuFRE5orIHSLyJxGZCowDPjHGVGGW9tpBRH4nIg8D5wJPmeCrQIkO/ge3tr5Rs1BTkijVws0lqRbBf6R52wMfcPwj/31+4y2Hm8YnFDVRAKpZR+jqzFPaf3hgm2Bjtqa8sOE47gavSM/nD3vVR91CQG17B4bo+QkwZr3KrgG69huzTk5tuWHGbohxm562QivYBzDXOxnKmF3xkS12A/Y8B4e5RpO0xnDUqLLevErto4l92HZp3cObLzilgQ03dnHDWauCe08rLizr1XLZXxB4DQVPW7Ls/dDbDbS6KdX1QUfZqrF/eLusceWGSbuRCv77a4dDA3/zGxd5xvOn91l9+/Pe2/W2hqtbGKzTUZEN/ojAiTfb5T3bKM0TDZeH3sUJxsrJsOHgYK+Ttr2tB/20e+x0S5WhVRerX39RLHD2GeHDoN/obds7fLXjYA4dYaNAXPqcDUdeaZc7HBY4YFVqzDqe2WDDJyuMMbv+K+9673cBnOSf3sX4ingleQYsePeRnI2e0dj5WDvQ5lZjXvWJNxji3kv353nzcR840MotAqfeDSNeDhw0EPEGkIIHJ/cX2D4umxFY0GjQH72BmHVx6k9ww4wbtbSDlz2dCvrL3i9TrdpP2P9r/4CyWzgtfU7l53NPEHr06MGDDz7I1KlTOemkk5g4cSLPPfccd955J3369OGll7waDNdccw3btm3j7LPP5rnnnuP222/n2muvpUePyP5rUlNTefTRR/nll18YPHgwTz31FGPHjuWSSy6ha9euYadbChcqHY7c3FyGDh1KdnY2V1xxBTNnzuS1114rfS1YEKL+Rw2SKMbsL9iKxncA/wBOxlYHvricbeoC/wP+jM2lrXrtbqV8/MZszzO8h67SSpVKtOjUqVPFjSrC/SP1Vx9dO89bdj2zyQ3sQ24758FvwSTI81VSLY+QYcbVzJlt1AqumA63rrTFaPy0DjK8atuYbdjCqwqaudTm6u7e7Hmj/Hm0waQ2hCZOiNJuzzMboOsAY9Z5MA0XZpy30+cxOweGjLWhg+c+7j3wBufM7s22ebtgPU0XPhMfuW1HXBa47Jd50B+jcwz/AF24UOOs1QTUQvR7rYyBXx1j1m8YpDUtHZQJ0HVKWuhz3zjIM7vJqTrdpqd9yPb/5oNDPBc87Xlmm7T3BjXOfcKGZp8xLnS/QnH47zxvodunzmEqhHc9ySeT43k6+LjoFBYL9swGV1Muj7Z9vAGwU8dGLk9qw8AK3b3PsXOwjngFfv9moN7ca21Ppg2xDp5GKZxn1v2tJKXYatqDrrJTep0XlHvZ4iD7Wyn97Bxv92avUnanQdbwd8OZV/hCq48cWTbP2T94GQ53UM7/G//uBXiyH7z9R3jjcptuAfZe1fFwWygPrDEbjz6F0jBj5zfneqv3ZsOK8DVFw/5f++tWDL7Dvptib1BBKcNdd93FO++8Q1JSEg888AC33XYb77//PmeddRbnn+8Vqxs6dCiPP/44K1eu5JZbbmHBggV88MEHHHRQhNEfwKhRo3jjjTcoLCzkzjvv5N///jfDhw9n/vz5YasMp6WlhVwfjp07d5KRkUFJSQl33XUXV1xxRcDr3/+u3efnhDBmjTE/GGPOMMa0NcakGWM6G2NuMcbU6YnGjDFijGlmjLnGGFNOfJhSLfzGbJN2cNRVdnnjd2XzMZVq8fHHH1dvByUlXvh3rzM9L8NK337dB/ZWXWx+45lOGfp9OTAvwjydkAWgqhlm3Li1rera7ICybUKFGdc2x1zvnc+5jwQWQOl/Ufnb+r0qDqW6LinxHqb8ntlwgwObFlFqWPU4HZq0gYtfgKNGet6sYGN26TSvGvBvJtrKr/FAlxPtPKgDLoFjA6d3oHFrOP1+68Ea+nDVjxFgzAYVgSrMt+GBrvFQut73W9++3JuT8qQx1sAA65V1DIOIrmvXmC3aa4/rTqHkTlHVzGfMrg8yZr95FtY5UQL+ar9dT7TzqVY0PZKf5FR7zl16nmmvy1B0OCywAi5Yb2E0CPbMVqYITUoa/PETGD2/bJRHRRx3g72u+g+399DkFOtBbR50zykdXDABYb+7cYzBYGO2pMS+ljtVjrsN9uoCtOxsB2fcObVD4d5DTLFXYdo9J65+/REKrbrAafcG7iMiY9bRpxt9sC8XPrwjcMootwhZ56Pt+XG9wHu2VZx7XtcwxvPMur+5Pr/xBoQ+eyhs+kHY69o/dWHvs717wqKXrIc7QRg/fjzGGNq2DUypGDVqFMYYunbtGrD+oosu4ssvv2TPnj3s2bOHZcuW8fTTT5fJo/3LX/7Cxo0bKSgoYP78+Rx11FHMnTuXuXPnlrYZMmQIxhguuSR0he0RI0bwww8/UFBQwM6dO3nttdfKDE5MmTKlNLw4J8e7ttx+lUfXrl0xxoR9TZkypdzto01CGLOKUi7+AlANmsHRV9uCEqDe2eqyYJKtAFpi54S89dZbK9igAvZmefNLNu1g53IEO53H/gIbMuXm7rjVd3udZR+sAL57EbYtrfg4bgGcpBTvt1BewaLycMOM3VC1UJQJM46CB7uyNGgKJ91il3eshDkT7HLLLhUXU3JzBn1hxqW6Lsz1qrX6c2bDhRm7Hjsoe1z34Ti4AJTrDWrawYZSxgsi1mC95MXAOTBdTr4V7tnm5TRXhSZtvN/ejqApqmbdBS+dA+9cHbje77Xy51D3uwD+8JbNFT5rQunqiK5r/+9/y0+e8dDpKPveuI2Xy+cWWnIp3OOFHUejAM/hl9njJqWUnUvYT3JK2XmdqzrPczANmwd+Li/XNxTNDqhaFdZGLeGKd+G3U8rPw/bfg1Y5c9k2aEHjAU5USdZqa7wueReeOR4e7WoHC91CTKGKYp1+v7d8cFA9zVB5x27/QhWfa9nFes67D7GfW3cvO71SKNKCPLOZy73/lN7nBLZ1Pb9+D3285c0W5tk8d/AVHWxqq3+DHaj6MfScomGva9cz27CF9Zy7lbTzd8DSd6Mjt1KrHHBAiEH2OEKN2TqAiIwQkSwRCZOUFna7b0TksZqSK2Hwe2YbNLMj0u5UC0vehe0VTGmhhGbDN3bS+9njS3MZR40aVb19+keEm7S1YWxg86bWzbcVFd0Rd9fQFYGhDzlVMYvtnIrl5WuC5zVMa+LLsapqmLHPMxuO4PzOYC9JbXHM9XCA8wDpVo7tP7zikN1SY3ZjaRheqa79XtRIwozdXEo3/NSP+9m/z/wsWOsUKuk7rGbmlo0lKZUL/wqJ650N9ir98HLo9n7P7NZf7HvLg63B0Li1Df/2GUIRXdf+qYVW+abEcQt1uRVtgVLPfIvOZeeLbRtiHtbKkpIGV30Ed6ytuAKrG2IKkJzmeZKrLUNQYbMDqmCY1iR+Y3a747lv35c35ziDTXnbYdp18PZVkPmrE/nyqLOBlE2lAGuUnvWg9eSd/JfwxwN7rt3fbbDnPaWhV0X84sl2Tt8Rr0SWWuCGGbu/8e2+qISzHvS8sOANXLTr6w3G/PByfHkfC3zebH9o+9HXeDnLcx8JnP/ZIex17ab6NHF00O9Cb3nOhMBjKnHBunXrYi1CtYjrf30ROUFExjvT7MQlIpIMPAD8qwphz48CN4pIhPONKCFxjVlJ9kIgT7wZEPtA/8GY+MyTiTX+IhpzH4GC3bz55pvV26c/V6dpezu/rFsleOUs30OyeEUuwI7wn3K7Xc78FT4JCk8Lxp0jMbWJN5diVcKMS4q9YkXlTa3SrKN9eCv9XMs5sy4paXDRfwJlGVBBiDF4D6L780q9pqW6LmPMugWgQhizxnjGbChvcKgCUMtnep4VdxBKCcT1Zm5f4d3Lyptqal+u184tvOTmnocgouvaP5iT7nj6klICvYvBv/tWXW3VaD/typ/aImJSGpT1joaii88r1/EIm3daE4RKP4glofL22/fl9zf57p1uKkJw/u/Bx4efsuqEP8O1cwLDxaGsZ7bdId5ATts+1oB1aXmwZ7g2aWPDjSP1Urth46WeWceYTW5gaxec9w87327n4zzvcVISDPyDXd7yc3w9E/ijWPyh7akNvTDtPdvgzSttJWofYa9rtwijq+OUNDjdqTqduxk+vT/0dkqdJdICU3WVuDZmsfO+jgNaxliO6jAM6AP8pwrbvgfsBv5UUUOlHFwjpUEz7w/ywCPgmGvt8vr58NPUmIgW1/irleZth6/+wbBhEc7HGI4Az2x7+zDaxfGcrJzl5c4eNKisJ/SUO7x8t+9egLl/C/9AUuqZbewzZqvgmS3IodTLVF6YcVJSYFGa2i4A5eeAfl6O5sHHh5+Sx4//QdQJNS7VdbAxWzo1Twhjavdmb9Q/lDHrPowV7fW8626l3cZtveqzSiCuh6tgl1e1eGd6ORsY+3sv3u+1CzY+fER0Xfs9s663t33fwAq+wb/7Vl3tdXzFNGtsNG7rhSXXFgce4Rlr3U4ut2m9omELL4rC5YD+/PmBp8q2HTkjsPq2Ox9uZWjUyk7r5OK/7ySnBIYQVycnvtQz6wxiu8Zsu962xkLbnnDLL3D1x4FREafd74Ud/zwV5jwQHwZtOM8s2JQMt6L6ui9hxi2lKUFQznVd6pn1zU068Aov5Pv7KRVO+6PULVatirNc8CDi3ZiNGBFJEpEaGlKtFlcBXxljNlXYMghjTAnwNnClSDyU7qyjuJ7ZBkGj9Kfda3PwAD64BX4InVeihGHzD4Gfv3qKGfedX70HgGDPLHjhbDkZXk6gG2LsJzkFLnreC4ea+wjMCxOl7xpaaU2qZ8z6DbnywozBq2gsyeG9GrXFMdfaCqRXTI8sdC/AmLVFoGbMmGE/l/HMOsZs0V5vCiAX/wBIeZ5ZsN7Zgt02XxqcEOPKTS+QMPhzDl8eZlMn/MWgznoIjrvRVo52Kdxji/y4+XbuNDghKNV1eTTrEDjXMpQN2Q1lzIKNwPi/H+Cm78o+kNc0yak2hPWkMdarGE0uftEa56M+jO5+o4FIWX2078u/XguqfnvgkTYM+KwH7ZysfX7jTfdT2eO18IUadwwaRPOHGvsH/ipLmZxZN4TaN3dvqHteSpr9HTR37nXzn7QV1IO8mXUOfxRLcNpGUhJc+Kx3r/3pNeuhdf7/wl7XwZ5ZsOds2FPeAMjbV9uBsHgw+BV69YpCLYIYErfGrIiMByY6H9eKiHFeXZ3vjYg8LSJ/EJGlwD7gbOe720TkaxHZKSJ7ReR7EQlZEkxELheRhSKSLyLZIvKFiJwV1OYcEflSRPJEJFdEZopIhZUIHOP6bGB2VY8NfAp0AY6o6Hi+/TYQkUdFZLPT/29F5MwIt+0kIm+KyC4R2S0i74lI90iPXScpNWaDCrA0bAHn/9M+gBUXwvs3wfQ/RT69SyKTt8PzAPU514atlhTBh7fZnNXcrVXcr2PMJqV4XrqBV3jVFF16nhF6+1ZdbK6cGxb7xcTQ+bOFocKMq2DM+vOQyvPMglewqn3fumGUtewceUil35h1pucZO9YxjAKM2ZaeMQvWoPXjDoBIUmiPsP9hrGCXncLHze0NN1eoYvMAB15ul3eth9cuDqxgPOgqOPvhwEJk+/Z4c4ICtA9vzJbqujwatYIhdwWu6xShMQv2N1bRgFBN0X0InDG+/FSBqnDoJXDtZ4F5uXWJMsZsP8aOfzAwHPyoUfY9pQFcOAku+1/oYmYRHc9nzAaHDQcYs9HwzO6x9+c9zn9ROYM1pTRtD6NmeL/LH1+FVy4sO/d5XSIgzDjEQFBaY1vQzU0jWP4BvHA6bFwU+rreX+BVlW4SNOjaqiv87jVnwMDA1sU29aSuG/wKGzdurLhRFKmoWnJliVtjFngXOw8rwBjgCuflv6ucBjwJvAHcDKxz1t8M/AjcD4zFzkH7logEVCwQkXHAq8B+p+04IMPZr9vmCmAmsAe4E5gA9APmu4Z1ORwFpAE/BH8RybEd3LljKvNvOAX4C/Bf7LkoBj4UkZPK28gpUPU5MBh42JFpIDBPRNqUt22dxq1mHOoPuPdQuPJ9L0Tup//C00fBl4+XnR5E8dj8k7d89NUwaqbn5V7yNvxrEHz+SOUfAtww48ZtvUI/aY1tdU7XoG1xsGcYhqJtTzjdmZeyZL83L62f/f4CUNXxzPqM2YoexE/8Pztv5m+nVP44sabpAZ7XzQkzvuwyZw5V/3XSsKV3PqFsqLHrmW3bx3vo9BPgmc325v5Eoldltj4iAuc/DSc4cwnnbIBf3rDLLQ72dOI/54W5Xr4sBE7xE0SprivilNvh/H/Z30pKw7JTtQRPSRVc5VupXfzGZdMO0Li11XUbJ78urZk3Z2k08A+KBVcm9g9YVqeitZszW1zohbuDHUSMhNbd7bRIrnG9fj48e4Kt3F9eHnqsCAgzbhm6TbMO8MdZXvGrzF/hhTO4vccq2BpUWdyf6tO0HWXocVrp/70UF1JUWIDZ9ivs3qJGbR2mdevaGyg0xlBcXEw0A0rDTK5W9zHG/CIiPwCXAdONMetCNOsDHGqM+TVofW9jTKlLQESexhqUf8EapohIT6wROQ24xAnpdduL894U+CfwgjHmOt/3LwMrsIayL5GkDO5Q4Fr/ykiO7TsPm0SkEGtAV4iIHAP8DrjdGPN3Z90rwBLgMWwecjj+BPQCjjHGfOds+5Gz7a3Y/sYf4TyzLl1PhOvm2aIP6Z/ah+g5f4V5E62x2+98WySkrhXwiCX+EOMDB1pD7vp5ZDw3gs55P9sH5Xl/s6Favc6EQ86z+WihpmfwUxreFPQn2rAFXPmeLUjS5YSKK9r6i8jsWFn2wcmfMytJgesqQ3CIbXm400LFI0nJ1hDJySgNM168eDGHHnqoF+aW2th6ev05kv4iUBUVf4Kyxqw7H+kB/cuG0CmBiNgw2a//aT+7c2n6DQP/PdDvmW3RuVxvW6muI+HIKx0j1pS93oMr2qoxG1v8ntkD7CPG4sWLOfSY6+wg4EljQg86VZWep9sB4+5DynoROwyw3vHcbdBraNWP4Zd343fecqTGLNj/+qtm2fSjX96wEUMfj7UDtH2H2WrfXU+qvUiC9QusF/SgQdbI9kf2+MOMywvRb9QSLn8XvvqHjVgqLqRVxifw3Cd2cLj/hVYvvpxamoZ55jnwCLjhK5p+8SI78nezJbc17Uu2kLJnm03natTCDiokp0aWxqLUOHv37qVx48YVN6wmRUVFZGZmUlxcTKtW0Yt0iVtjNkLmhTBkCTJkWwHJwJdYw9jlQqzn+q9+Y9LZ3vWPn4ktPvU/EfHPmlwMfAucWoF8rjcz2MUXybH9ZANtQ6wPxSWOfKUFp4wxBSLyIvCwiHQ2xmSUs+13riHrbLtcROYAI6ivxizYkMs/vAXLZtjCQZlLbYjkr9PtC2wuTbve1oPRpqd9EGjSzk4h06i19X6UN69ffcI1StwCLgDNOvBlp9H8/pj2tnz/lp+geJ8Na1r+gdOmo324btsb2vSyOVSN29rz2Li1N4dhcHgT2IeUQVdFJl8b3wN88HQl4MuZber92VY7zDjKIYp1jRYHWQNp0yL48nFOz/gfPP0PrzKy239/mLHfmN2Z7hn/weGnLn7Pwp5tsMkJTHELsyjl07S9Dd/cuthb5/e4pvk9sz5jtpziT1WiRafQ6/1TUqU1DSwapdQ+fmPWn1Pa73z7ijYDLrZF+twonmBOGlP9Y/h/4xsX2ffUxjZCoVL7aQzD/w09z7QDszvT7SDtz1PtC2w4dLtD7PXTuoc1/pq2t88EbpRKdZ8Jfn4dpt/gzeXd7EA7n+9hl9pBXdcz26B5xekrKWkw+A5bFGruI5QsnUYSxv5Xb/nJtvHnvYf6Hy79ri2tzvgL+b9+S072TnLympCSkkJScjZS+sgrViZJdt4FSLLvIvZ7UIO3Fti3bx85OTU3pZIxhpKSEoqKbA2Gxo0bqzFbCdaGWiki5wH3YvNM/ZO9+Q3FHkAJUMYY9uE+EX8W5vvdEUlZesVW6tjB20cagD4QWGmMCZZtofN+BDacOfAAIknAYcDkEPtcCJwlIs2MMbkhvq+YD++AX2q5sIeL40mqMM9HxP6B9x0Gaz6Hn/4HKz70qiHv3mhfq8P9HICkVMdD1cj+GSal+m7mSb6buvue5H2WcryNYW/2YdbXdPu1zsTyQR62Qw89FHoeaj0z67+CH/9rz6Gb15O7xb7ceUPDUd0CSQ2a2j/93M1hjFlHp6mNvQeA6oQZS1L4EK/6QsuDYcMC67GZ81cOAPCnxIYyZv1heRsWeMvhQob9AwKrP7ODIVDxXKGKR4/TgozZMJ7Zvbu8a6OCfMKIvbIV0bQDpX9nrbrqQ2ys8XvKHWM2aroOR0XROdUllGe23SFVm59aBA77rZ2+bPlMWPwmrPzEuy/t2mBfqz4Jv4+kVPsskNrERq64zwSlzwEpzucU53kgxTP0TAmsmUvA41/uZpg+Gj66w95r3cH6yvz/tOsNv32JlQddyiEFP9jKxG5Vc7cgHFQ4H3pKaioHH3Yiubt3s3vjcvZnrcXs3ubVOYgI8Z2DZEqNXSTQ6HWfj6r0nBR0vIjEql/3pqT9+6FDXzvQUgOICCkpKTRq1IjmzZvTrFkzDTOuBGUqu4jIycD7wBfYsNkt2LzUq4DfV3L/7lVzBRCqok1RiHV+3EpCrYDqZF+3BHZE2LYjts/BuOvCzQnSGmv4V7TtihDfAyAi7YHgJAubfLN2HuTFuOhNpF4AEftA2OM0KNpnvUPrv7IFVXastBVAQ82hCfYmvi/HK6BQ3wmaRuN///uffRgSsWFYXU+yeTSbf7L5j1uXwM5V9iG6vHldo+EpatvLMWZXlv3O1V9aE1+Y8R4bChvJDbikxHrvXQ91w5ZVe1iKJ465zvZ3ZzqYEopMEiniCyxxDdG0MJ5Zd17iBs0DvUB+GjSn1NhZ7qsA684HqVRM91PhK9/0KuE8s1t/8R46KzBmS6/r6pKSZgeq9myrXsVaJTp0OsoaWaYYug8GoqjrWJHmG7DJdx7BKhNiHIqkZM9bXZgPGd/Ahm9tZMP2FfaeGM6AK9lvvacF1XgmSGsKw5+zhRW/+LstarVvt1cPBMJHQ5TDKzO+4OGHH4Yhd9vCcWu/tPf4HSuh2ykRTSEnIjRv0YLmLY4FjrVhylt+svf7zF/tc1Pmcq9OhRI7Ln4Ruh8TaymqRLw/XVWlHNbFQAEw1Bgz2RjzkTEmVDXh1djzU14u6mrnPdMYMzvEa24FsrilIrtV4diArS6MLSK1rKK2Do2wlZ2DKfB9H247qrity5+w+bX+13sAexoeyJ6m3chMOoCitn1Zv685HHAoa/KbwAGHsqm4Nfta9WZn6oHsatiZvGbd2Uo7Str3Z11Bs4C2m0vasLdFT7IbHER2g4PY26Inm0vaBLRZV9CMkvb92Uo7u69mh/Lmmsakp6czZowNZXLnWBs5ciRZWVlMnDiRefPmMWvWLCZNmsSmTZsYfdPN0OUEhk38Ai6ZzOifBrBp5EKmtL6Trwc8wuLDxvFh2jDyT7qHd7L7wkljeH/bgXDklXxf2J09B5/OukaHsqX5QHa1O5Z0ulLc9RQW57WGLiexNLc5HHQMGSXtyW/Vl50NurCzQRfyW/Ulo6Q9HHgkq/KawoEDSd/bnOIOh7OZA9jTojfZjbqyI+0gClr3JaOoDXQ8wrbteDjr9rWgqN0AtiZ1ILdpD3KadGN7yoEUtunLhv2toMNhrM5vCh0OY8P+lhS2OYTtKR3Z3bgruU27sS0CPW1uPpDvTT8mTJhAfn4+I0aM4OGHHy49r2PHjmXx4sVMfeMtpn65isXNT2Ps9+3gurkMWzAQbl3BnWuOp+C3U5kuv2F93xv49YDhfNPyQla3Ob1yeho9OqDt6NGj2dPI/rkXbVvOvLlzmThxIllZWfxx5BW2OAhAWhNmzp5nl00x7737FgsXLgzoU+l+S0p4/p6RZL10GXsf6gLPnQTpzq2lSdvSY48YMYL8/HwmTJjAwoULmTZtGpMnT678by9EnzZt2sSkSZOYNWsW8+bNK+3TyJEjA9qOGTOG9PR0Jk+ezLRp08L3ya+nqVOZOnUqixcvLq1yGdCn1v2YkH0+3w39gJn9/sncdqMCLv6vf7S3qAce/nvpusU/fFvap6I1jje/8zEMu+DC0H368kv20rBUHwBb9jWE5h1rpk/1UU/tDme/bxz7f7O/9/rk81qtmvt66fIPG/PL7VNWVlb0+nTkSPKLk+GI3ye2nupCn7bmMLX9nXzY+28sXLGZCRMmcO+998Z1nzZu30UwhS17RK9Pr71OujmYMe9nwoiXGTarHdyzlb9knEXOpdN5p8GlrOhzE8u7XME3jc8g9/Br+CyvNwy8nHlZ7aDfBfxYcBB7Dz6VdWl92N7icLJbHc6GpC7sP3AQ6QWtoNMgVuQ1gwOPZOn+zmSc/iyTF2xn2qa2LDrh33wiQ9h/5B+Zk90JDruUOTvbw9CHK92nCy+80PbppZdI31nEmFd/gPOeYNg7AoPvqJqenn2OWYu3M69wABNXdiXr4rcZtfIMuG0Vf/71SLj8Xabmn8z2QbezqMW5LG8/jK1dh/ODHEpR3+F8ndMB+g7jm11toNdQVpYcTG77QWxr1JvMRj3Ib92fDSUHwEFHs3xPM+g0iJX5LSjuOJBNdGBPi0PIatSN7WkHU9CmPxuK2sKBA51noyNYu68lRe0PZWtSx9Jno8wyz0ZNoMOh9tmodR92JHdkd+MuMX2G3dWwMztTD2Rfq95sKm4d0Hb9vuYUte1LZtIB7Gnajd2Nu7AjuSOFrfuQsb+l17Zhizpz31u82Bc9FAES7fLItYmIjAaeBQYaY34K+s4Ak4wxNwWtfxwYDbQzxuQ767oCS4HGxhi3uFNPrJfxPUIUYTLGGBFpjg3J/RE40xizP+hY7YwxYcu1OlPz5ACPGmPu962v8Ni+z+c77Y4yxpSpihzimEuAbcaY04PW93POwWhjzL9DbNcWWyn6fmPMhKDv/gRMAg4xxlTFM/vekiVL6N+/wtmMlDhn2LBhkc1JWRt8+x/46Ha7/Jdl3ihz9np4ypkW5qyH7JQTH95mP9+woLQQSinFRTa87MvHvVAsPw1a2GlP3KlREoRLzv8Nbx/zgzf9zpFX2kq2236FZ52w4EtesiF6udvgccdDeNp9cMpt4Xf81BGQ7csgOfz3MPzZGulDveXVi2D1HPvbvGu9F21QUgJ/bQ0YG6Loes7vWFtuMZuoX9clxXVjeiqlDHXqHl4Vti6B54Imf/jDO9ArzHRuCUzc61qJmLqm66VLlzJgwACAAcaYpRW1j/cwY3damodE5HVsuPAMY0x58QozsVWLZ4nIVKA9cCOQjs0JBcAYky4iDwH3AV+KyLtYr+TRwGbgbmPMbhG5ATuFzg+ODNuBg4Fzga+AAGPaj1N46RPgDGz14oiP7dvNmcAGrEEdCVuAUPEmbvLD5jDbZTkyhEqSqGhbAIwxmUCmf100Y+aVuk9dulnStqe3vGOlnSrkoztsfpBLg6bedAUAP7wM5zzqfd78I0y7Abb7AiOSUu08t73OtGHUbXrV/xDjELz9/ofwv8tsTjQ4IcIEhRk7hm7GN966ioo5tTjIM2abdoBjyysYr4TkxJvtb37QVYFh80lJNmSxMNcXat+0wuJlUb+u1ZCts9Spe3hVCFV9uZw5lBOZuNe1EjHxruu4fsJyqureBxyOnTv1f5T1/AVv8xlwNdAB+Ae2gvGd2GlwgtveD/wRGz77EPBXoAswx9dmKnA6sAm4HXgKO/XNT8BLEXRjMnCciHSu7LGdokwXA6+EqXIcip+A3o5X2c+xvu/L4HiHFwODQnx9LLCmysWflITBDT2pE/hzBX98zYYFL37LqwrZorMtVNWmh80zBPhpqi0EZYydVuiFMzxDtmkHOOtBuHUF/P51O81Ouz4JaciCo2v3vIEthAKhqxm7+bJJqeErGbuc/Tc4djRc+hqMWRJ+Gh8lPN0H23N38q1lvwt+2G/RucI88Tp1XSs1StzrukHzsp+Dp4RSgHqgayVi4l3XcR1mXB8QkWRs1eI3jTH3VXLbC4GpQA9jTKjCTKG2ORb4hsB5Zhtg81d3GmOOc9YdjA27Xu7b9k7gb8DRxphFzro+2PDkvxtj7qqM/M72/YElGmacGOTn59fKXGYRUVICjxxUtvBE77PtfJydj4NkJ3hl2Qfwxh/s8im3W8Pslzfs56QUOOUO6+1KbVh78tdx8vPzaVyc64UPX/qarQS+bw884jw8nvlXOOx38MLpdlqfg46Baz6NndAK/GuQLcLm0ussOy1ZOdSp61qpUeJe10WF8KDP56H3nLDEva6ViKlruq5smHFiugzqEMaYYmyI8Y0iUtnZx+8Eno7UkHWO9y3wFvCIiDwmItdhpxbqCtzha/oKZYtKPYMtTjVTRG4XkVuAT4FtwOOVlF1JQB5/vA79TJKSAqcWkGT4zd/hstdteHCyLwuj99ne6P0XEz1DtuXBcM0cGHKnGrJBPP7449DsALj6UzsfY5/f2C/8ntldG+CV860hC9D/wlqXUwkilGe2AurUda3UKHGv65Q0b+5r0BDjcoh7XSsRE++6jvec2XqBMeYN4I0qbFfVyRWvBCZgpxRqBfwCnGeMKXdyT2NMrogMAZ7EztObBMwFxpRX6EpRXIYOHRprEQI5+DivaNOIl63nMBTJKXD8TfCxL1394BPg0ldrbF62eKdU152PsS+XpCSbn1xUAN+94K0/8ko49obaFVIpS/B82y0rNmbr3HWt1Bj1QtdpTb05wMNNA6bUD10rERHvulZjNgExxhRg83tvL6fNkDDrNwK/rRnJlPrOpk2bYi1CIEPuhkat4ZDz4OBjy2973A22TWEeNGwBBxyasPmwkVCurlMbW2PWpcuJcN5Tej7rAmlBxmwEntk6d10rNUa90HUDnzFbwRzKiUy90LUSEfGuazVmFUWpNbKzs2MtQiAtDoKzJlTcDmwRnE5H1aw89YhydZ3a2HuYBOg2WA3ZukJwmHHLgyvcpM5d10qNUS907R+wUc9sWOqFrpWIiHdd69ODoii1ximnnBJrEZRaolxdpwUVmuh4eM0Ko0ROWuVzZvW6Thzqha7dAZtGraBp+9jKUoepF7pWIiLeda3GrKIotcakSZNiLYJSS5Sr69RgY/aw0O2U2sfvmU1KhaYHVLiJXteJQ73Qdauu9v2goyucdiqRqRe6ViIi3nWtU/MoMUWn5kksjDFIAj48JGK/y+3z5HNgw9d2uUk7uG2VPlTWFb6YCJ89aJdbdYWbf46pOEodw5j4v1Zzt8KSd6Dv+REVOAPqR78rSyL2WakT6NQ8iqLUSWavmU1K3xRmr5kda1FqldlrZtPooUYJ1e8Kde0PM+54uD4w1SX8+YQRhBgDDBsWpgq4Ur+YPZthKSkwO87vZc06wPE3Rm7Izp4NjRrFf78rQ33RtRIR8X4PV2NWUZQaxxjDXbPvouSyEu6efTeJEhHi9ntf8b6E6Xeldd1BQ4zrFP4w4wiKPwHMmDGjhoRR6gzGwF13MaOkBO6+235OBJx+s29f4vQ7UXWdwMT7PVyNWUVRapyZq2by/ZbvYRos2rKID1d9GGuRaoXSfpM4/Y5I11lrvWUt/lS38BeAitAzO3LkyBoSRqkzzJwJ33/PSIBFi+DD+n8vA0r7DSROvxNV1wlMvN/D1ZhVFKVGMcYwfu54BIGhIAjj546v917KgH6TGP2OWNdZq71lLf5UtwjwzEZmzD755JM1JIxSJzAGxo8HEZ4EmxYwfnz999j5+g0kRr8TVdcJTrzfw9WYVRSlRnE9dQYDP4LBJISXMqDfJEa/I9b18Td5y6261a6QSvm07OItRzgH54svvlhDwih1Atc7aQwvgjVsEsFj5+s3kBj9TlRdJzjxfg9XY1ZRlBoj2DtJJ/tW372UZfrtUJ/7XSldn3IbnHov/PETLf5U12jbCy56Hi58FjodGdEmxxxzTA0LpcSMIO9kqabru8cu2CvrUp/7nai6VuL+Hp4SawGUhCcNID09PdZyKDXA3HVz+f7n770V24HGjscucxHPfvgsg7sOjpl8NUWZfjvU535XWtdtfwO5wNIKq+4rtU1yf0gmYt0sX76ctm3b1qxMSmyYO9fLGQWWA23B89g9+ywMrl/3MqBMv0upz/1OVF0rde4e7rMJ0iJpr/PMKjFFRK4AXom1HIqiKIqiKIqi1BkuMMa8X1Ej9cwqsWal834JdiBQqb/0AN4DLgBWV9BWiW9U14mD6jpxUF0nDqrrxKEu6joN6AzMi6SxGrNKrNnjvC83xmi8YT1GvNyj1arr+o3qOnFQXScOquvEQXWdONRhXf8YaUMtAKUoiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrBJrtgMPOO9K/UZ1nTiorhMH1XXioLpOHFTXiUPc61qn5lEURVEURVEURVHiDvXMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3pMRaACWxEZEWwGAgAyiMsTiKoiiKoiiKosSONKAzMM8Yk1NRYzVmlVgzGHgv1kIoiqIoiqIoilJnuAB4v6JGaswqsSYDYPr06fTs2TPWsiiKUhvs2Q5Lp0Hb3tB9MIjEWiJFURRFUeoA6enpXHjhheDYCBWhxqwSawoBevbsSf/+/WMti1LDjBw5kpdffjnWYii1QFhd//oezL0Z9mbDBmDrkdB7KDQ9AEwJFO+H4n1QXOgs74eSIvtdSZHzKq71/ijh+ezzzznt1FNjLYZS0/Q8nZF/e1vv4QmC/l8nDnVY1xGlH4oxpqYFUZSwiEh/YMmSJUvUmE0AsrKyaN26dazFUGqBkLpe/Tm8emFM5FEUpZpIEruu/JyW3Y6ItSRKLaD/14lDXdP10qVLGTBgAMAAY8zSitqrZ1ZRlFrjxRdf5Pbbb4+1GEotEFLX3zxj31Mbw3n/gJ2r4Mf/Qu7m8DtKSvG9ku27JAEamlxXyMvPo0njJrEWQ6kxDORtB1PCz1PHM/ie6bEWSKkF9P86cYh3XasxqyhKrXHMMcfEWgSlliij610ZsOpTu3z4ZXD4pXb5tHthfwHk74CkVEhOheQ0SGngGK5qtNZ1Fs2bx+DBg2MthlKTTDoWti/nqAbrYi2JUkvo/3XiEO+61nlmFUWpNfbu3RtrEZRaooyuf3wVcNJajhoZ+F1qQ2hxEDQ7ABq3hgZNrVGrhmxcoNd1AtD/IgCa7lkLO1bFWBilNtDrOnGId12rZ1ZRlFpj9erVsRZBqSUCdJ29Hn541S4fOBA6Hh4boZQaQa/rBGDARTD3Ybu85F0Ycmds5VFqnGhc18YY8vLy2L17N/v27UPr9NRNkpKSWLNmTY0eQ0Ro0KABzZs3p0mTJkgUB6vVM6soSq3hlFpXEoALL7gA1n4Br/8B/nmElxd71KhYiqXUAHpdJwBte8EBh9rlpdNiK4tSK1T3ujbGkJmZSUZGBjk5ORQXaxX6ukr37t1r/BjFxcXk5OSQkZFBZmZmVAc21DOrKEqtMWHCBJ577rlYi6HUAhv/9Rs6NVofuPKQ82y+rFKv0Os6Qeh3AWxbDNuXQc5Gmxqg1Fuqe13n5eWRlZVF48aN6dixI2lpaVGUTokm69evp0uXLjV+nMLCQrZs2UJWVhZNmjShadOmUdmvemYVAETkaBF5WkSWikieiGwQkTdFpHeItn1FZJaI7BGRLBF5VUTaxUJuJb7QB94EIW8nxzbaYJdTGsLAK2D0fPjdf21hJ6Veodd1gtDDN5fwmnmxk0OpFap7Xe/evRtADdk4oDYMWYC0tDQ6duwIeL+PaKDGbA0hIlNEZF01tt0TZZEq4k7gYmAOcDPwH+AU4AcRGeCT7SDgC6AnMBb4O3Au8KmI6N1KKZdhw4bFWgSlNljzOaXFnn7/BlzwNHQ4NKYiKTWHXtcJQscjyCtOtstr1Zit71T3ut63bx+pqalqyMYBq1bVXlG3tLQ0UlNT2bdvX9T2mVDGrIiMEBEjIsNDfPez892pIb7bICJf146UkSMijUVkvIgMicLungC6GGP+zxjzgjHmQeBkbCj6Xb52Y4EmwGnGmH8aYx4GRgCHA6OiIIdSj5kxY0asRVBqg/Q59j21CRx8QmxlUWocva4ThOQUmvQbapfXzAMt5lOvqe51bYwhKSmhzIy4pVevXrV6PBGJas5sov3K5jvvJ/lXikhzYABQBJwY9F1noLNv20i5FuhTNTEjpjEwDhhS3R0ZY742xhQGrVsFLAX6+lZfDHxgjNngazcbWIk1ahUlLKNHj461CEpNYwys/swudzsZUnRUvr6j13Xi8MZ3W+3Cnq2wY2VshVFqFL2uE4f169dX3CiKRLOSMSSYMWuM2QysJciYBY4HBHgrxHfu50oZs8aY/caY6PnQY4DYX9sBwA7ncyegPbAoRPOFwMDak06JR+67775Yi6DUNJm/2gddgB6nx1YWpVbQ6zpxGHLVOO+D5s3Wa/S6ThzcPNZ4JRGrGc8HficijYwx7izBJ2I9kB8B/xKRJGNMie87A3zl7kBELgfGAP2AvcAnwO3GmAxfmynAEGNMV9+6NsA/gAuAEuA9bHjvT8BVxpgpfkEd43EScIZznJeBO40xxSLSFWuYA4wTEfcf5gFjzPjKn5aQ/AHoBNzvfHZ/7VtCtN0CtBaRBuGMeBFpDwQXiuoRDUGV+GD69OnceOONsRYjvsjPgtytULQX9hfA/r3esil2Qv2ccB13Odx7bbB+gbfcU43ZRECv68Th7XlLuLHpAbBnGyx5x061pdEX9RK9rhOHXbt20b59+1iLUWUSyjPrMB9IBY71rTsR+Np5tcCGHPu/W26M2QkgIvcArwCrgL9gjdPTgS9EpGW4g4pIEjADuAxrlN6DNQ5fDrNJMvAxsBO4DZgH3Apc53y/HbjBWZ4GXOG83g3f9cgRkUOwhvQCn4yNnPdQxmpBUJtQ/AlYEvR6D2D+/PnMmzePiRMnkpWVxciRIwGvAMGYMWNIT09n8uTJTJs2jYULFzJhwgTy8/MZMWJEQNuxY8eyePFipk6dytSpU1m8eDFjx44NaDNixAjy8/OZMGECCxcuZNq0aUyePJn09HTGjBkT0HbkyJFkZWUxceJE5s2bx6xZs5g0aRKbNm0qDcNx244ePZpNmzYxadIkZs2apX0K6lOPHj3qXZ+iqadbx9wMy2Yw58+94PnT2XNfW3isGzx7PDx/Gkz5Dfz3Ynjjcnj3Gph2PUwfDdNvsK/3/gTv3Qjv3wTv/xlm/B/MuBk+uAU+GFM7r8VvArCzpCnpWSX1Uk/ap8A+ffjhh/WuT/VRT9HoU6eDDuLTDakAkPENvH0V9469M677VB/1FI0+FRUVVbtPubm5gA1jLSwsJDMzk5ycHHJzc9m6dStFRUWsXWv9Mm4RooyMDAoKCtixYwfZ2dnk5eWxefNmiouLWb16dUDbjRs3kp+fz86dO9m5cyf5+fls3LgxoM3q1aspLi5m8+bN5OXlkZ2dzY4dOygoKCAjIyOg7dq1aykqKmLr1q3k5uaSk5NDZmYmhYWFpaG4btv61KedO3dWqk8lJSU88cQTnHfeeXTq1IkmTZrQr18/7rjjDvLy8irsU1FREYsXLw7723O/ixSJZgJuPCAi/bBe2PuMMQ+KSAqwC/iTMeYVEdkK/NUY84yINAOygcnGmOtEpAuwGrjfKXzk7nMA8CMwzl0f7JkVkYuAd4BbjDFPOeuSgE+B0/B5Zp1tRzrHmeA7zg9AiTFmkPO5LdaojaY3FhHpgPVEpwLHOeHZiMgg4DvgSmPMq0HbPAbcDjSsgmf2vSVLltC/f/9odUGpo8ybN4/BgwfHWoy6ybIZ8OEdkLs51pJEASG95x/pefkTsRZEqQX0uk4c5s2bx+Bjj4BXL4JNTsbRUaNg2FOxFEupAap7Xa9ZswaA7t27R0skpYbIzc2lWbNmEbffs2cPzZo147jjjuO8886jffv2LFiwgJdffplTTjmFzz77rNy82Ip+G0uXLmXAgAEAA4wxSyuSJxHDjJdhvZ1uLuzh2Oq8brXir7He2GewubTJePmyF2G92W86hqTLVqyn9lTgYUJzNrAfeN5dYYwpEZFJWGM2FMGTfH2J9b7WGCLSAhtu3RI42TVkHdzw4lDB9R2BrPLyhI0xmUBm0PGqJa8SXyxcuFAfeoMpLoJP74dvJnnr0ppBx8OhTQ/7anGQrQyc2hBSGkFqIzt/a1IyiADivONbDvdeC6Q0ZNrTz3N77RxNiTF6XScOpbq+4l145ULY/AN8PwW6nQIDLo61eEoU0es6vigoKCAtLa1KFaTz8vIqZcympaXx1VdfccIJ3mwF1157LV27dmXcuHHMmTOHM844o9JyVJWECzM21hX9NXCc4xk9Ecg0xqQ7TVxjFt+7a8z2whaKWoX1iPpffbHFkcLRBdhijMkPWp8eqjFQYIzZHrQuG2hVzjGqhYg0xIZC9wbOM8b86v/eGLMJ29dBITY/Bpv7qyhhufrqq2MtQt1j1p2eIdugBZz3JNy2Aq6aCef/E0682T4k9jkbug+Bg4+FjodBu97W0G3dHVp3g1ZdnVcXaHkwtOxsjeAWnaD5gdC8IzTrUDuvRi1V1wmE6jpxKNV1wxZw6WvQqLX9/P7NsOHb2AmmRB29rstn/PjxiAjp6emMGjWKli1b0qJFC6666iry84Mf9eG1117jqKOOolGjRrRu3Zrf/e53pSHBLl27dmXUqFFlth0yZAhDhgwp/Tx37lxEhNdff517772XTp060bhxY3bv3g3AW2+9VXqstm3bcvnll7Np06aAfY4aNYqmTZuyadMmrr/+epo2bUq7du247bbbKC4uLrfvaWlpAYasy/DhdubTZcuWlbt9tEk4Y9ZhPjY39lC8fFmXr4EuTvGlk4DNxpg1zndJ2CoqZwNnhnhdH0UZy/8lRRkRSQbewHqjf2uMWRCm6TvAec6URe62p2MN4LdqXFAlrnFzbhSHb/8D371gl9v3g+vnwaA/QlqT2MoVBVTXiYPqOnEI0HWLTnDhs3a5MBcmD4UZt8De7JjIpkQXva4jY8SIEeTm5vLII48wYsQIpkyZwgMPPBDQ5qGHHuLKK6+kV69ePPHEE9xyyy3MmTOHU045hV27dlX52BMmTGDmzJncdtttPPzww6SlpTFlyhRGjBhBcnIyjzzyCNdeey3vvvsuJ510UpljFRcXM3ToUBo0aMDf//53Bg8ezOOPP85//vOfKsmzdaudyaBt27YVtIwuiRhmDIHzzZ6ILeLk8j22wNEQbJGoD33frcZ6ZtcaYyo7wdp64FQRaRzkne1Zyf34iWbC8+PA+VjPbGunYrN3IGNecxYfBn4LfC4iTwFNsbmyi4GXoiiPUg95+eVw9c4SkK1LrFcWoGkH+MPb9uGwnqC6ThxU14lDGV33ORvOftSmShTvg+9fguUz4fT7of9waNA0NoIq1Uav68gYOHAgL774YunnnTt38uKLL/Loo48CtqjSuHHjePDBB0sLbgFcdNFFDBw4kGeeeSZgfWUoKChg0aJFNGpka6/u37+fO++8kwEDBvDFF1/QsGFDAE466STOO+88nnzyyQBDu6CggEsvvbR0GqbRo0dz5JFH8uKLL3LDDTeUPWAFPPbYYzRv3pxzzjmnSv2pKolqzC7CVt91p54p9cwaY/Y5hZZuxObS+ueXfRd4BDsVzuXGVz3LmZO1tVv1OAQfA9c6L38BqOrUPXeN4pbV2IfLEc77MOcVzGsAxpgMERmMnVLob0AhMBO4Nd7n1VVqnmHDhjFjxoxYi1E3mP8kmBKQZLhsar0yZEF1nUiorhOHkLo+bjT0OtNWM187D/IybUX1D2+HLidApyOheSdo1BIatYIGzSEpxfdKdvL/kwPX1RWS0xLSKK/R6/qju2Br5SrW1hgdDoVz/lblzd3KzS4nn3wy06ZNY/fu3TRv3px3332XkpISRowYwY4dO7zDduhAr169+Pzzz6tszI4cObLUkAVYtGgRmZmZjB8/vtSQBTj33HM55JBDmDlzZhmv8ejRo1m1ahW9evUqlf/VVwNqvEbEww8/zOzZs3nmmWdo2bJllfpTVRLSmDXGFIrId8DJWC/s90FNvsZOgwM+Y9YYs1pE7sUatF1FZDqQC3QDhgP/Af4e5rDTgYXA4yLSE1iO9YS2dndfhX7sFZFfgUtFZCWQBSwxxiypwr6GVKLtUmBoZY+hKPrA65C9HpZOs8v9h0Ono2IrTw2guk4cVNeJQ1hdt+kBV74Hi9+Cj++xBm3RXlg9x77iGoHBd8Kpd8dakFqlRq/rrYth/fyK28UBBx98cMDnVq1saZvs7GyaN2/OqlWrMMaUGovBpKamVvnY3bp1C/jsTrXTp0+fMm0POeQQ5s8PPOcNGzakXbt2tGvnTTTSqlUrsrMrlyrwxhtvcO+993L11VdXyaNbXRLSmHWYjzVmvw/hUfwKa8zmAj/7vzDG/M0xHMcA45zVGcAnwPvhDmaMKRaRc7Fe2ZFACXZ+2Aec4xWE27YCrgH+BTwJpDn7q7Qxqyi1wZgxY3jyySdjLUbs+eYZME5a/In/F1tZagjVdeKguk4cytW1CBw2AvpdCGvmwrL3IOM72LGS6GZF1TYGfnw14YzZGr2uOxxaM/utCtWUJTk5dBSBG7xZUlKCiPDRRx+FbNu0qef1DzfDR3Fxccht/V7ZquDuMyMjg86dO1fQOjSffvopV155Jeeeey7PPRc8CUvtkLDGrDFmLBDSr2+MmYbNjQ237bvYkOPy9j8qxLod2NDmUkTkQmdxY9C2obYfD4wPWreA0NWFFaXOceON1Ymqryfs3QU/vGKXu59qp+Cph6iuEwfVdeIQka5T0qD3WfYFsH8v5GdBwS5bHKpgtx3MKymCkmL7CvjsvNcFVn1iPcu5W6GkBKow7Um8UqPXdTXCeuONHj16YIyhW7du9O7du9y2rVq1ClkQav369RHN19ulSxcAVqxYwWmnBc76uWLFitLvg/F7ZivDt99+y/Dhwxk0aBBvvvkmKSmxMSsT1piNBSLSyBiz1/c5GfgzsBv4IWaCKUot8cUXX9CzZ3VqntUDfn0P9jvp7sfXXyNAdZ04qK4ThyrpOrWRrQkQj3UBJMkas6YY8rZDswNiLVGtodd1dLjooou4++67eeCBB3jttdcCvK/GGLKysmjTpg1gDd8vv/ySwsJC0tLSAPjggw/IyMiIyJgdNGgQ7du357nnnuOPf/wjDRo0AOCjjz5i2bJl3H///SG327NnT0CObSQsW7aMc889l65du/LBBx9U20tcHdSYrV3+JSKNgAVAA+Ai4ARgrN/IVZT6iptLktD88qZ9b3oA9Dit/LZxjOo6cVBdJw4Jp+tmHbzl3M0JZcwmnK5riB49evDggw9y9913s27dOi688EKaNWvG2rVrmTZtGtdddx233XYbANdccw1vv/02Z599NiNGjGD16tW89tpr9OjRI6Jjpaam8uijj3LVVVcxePBgLrvsMrZt28ZTTz1F165dw063FC5UOhy5ubkMHTqU7Oxsbr/9dmbOnFmmz8cff3yl9lkd1JitXT7D5uKeBzQE0oE/G2OejqlUilJLdOoUhyPz0WRXhlf04tDf1q2KnVEm4XWdQKiuE4eE03XzA73l3K2xkyMGJJyua5C77rqL3r17B0yN07lzZ8466yzOP//80nZDhw7l8ccfL52LdtCgQXzwwQfceuut4XZdhlGjRtG4cWP+9re/ceedd9KkSROGDx/Oo48+GrbKsOsFjpSdO3eSkZFR2rdgRo4cWavGrPhml1GUWkdE+gNLlixZQv/+/WMtjlLDTJgwoXQ+s4TkyydgjlMW//ovoeNhsZWnBkl4XScQquvEIeF0nbMJnuxnl899Ao6+Orby1CLV1fWaNWsAIgqPVWLL5s2bOfDAAytuGCUq+m0sXbqUAQMGAAxwZlApl8TJZFcUJeZUZnSxXrL4Lfverm/dquZYAyS8rhMI1XXikHC6btqe0nqguVtiKkptk3C6TmAOOCC+w+fVmK0jiMgIEckSkWrNzC0iZ4vIHhGpWmkyRalBRo0aFWsRYse+XMj81S73O99OY1GPSWhdJxiq68Qh4XSdnOoYtMDuxDJmE07XCcy6detiLUK1iHtjVkROEJHxItIy1rJUFaeq8QPAv4wxe6qzL2PMLGwubmJNiKbEBW+++WasRYgdO1Z5y+37xU6OWiKhdZ1gqK4Th4TUdbOO9j3BPLMJqesEJdICU3WVuDdmsdWAxwEtYyxHdRgG9AH+E6X9/Ru4XkSaRWl/ihIVhg0bFmsRYoffmG3bK3Zy1BIJresEQ3WdOCSkrt0iUAlmzCakrhOUVatWVdyoDlMfjNmIEZEkEancREq1w1XAV8aYTVHa3zvYqX9+G6X9KUpUmDFjRqxFiB073T8LgdbxPQoaCQmt6wRDdZ04JKSu3el5dm+OrRy1TELqOkHp1Su+B9jj2pgVkfHAROfjWhExzqur870RkadF5A8ishTYB5ztfHebiHwtIjtFZK+IfC8il4Q5zuUislBE8kUkW0S+EJGzgtqcIyJfikieiOSKyEynUm9FfWjoyDQ7aP27IvJD0LoZTp/O96071ll3jrvOGJMJ/AJcUNHxFaU2GTt2bKxFiB07Vtr3Vl0gtS6OqUWXhNZ1gqG6ThwSUtfNHM9swS7YvzemotQmCanrBGXjxo21erxoz6QT18Ys8C7wP2d5DHCF89rua3Ma8CTwBnAzsM5ZfzPwI3A/MBYoAt4SkXP9BxCRccCrwH6n7Tggw9mv2+YKYCawB7gTmAD0A+a7hnU5HAWkAT8Erf8SOFxEmjvHEOBEoAQ42dfuZGfdV0Hbf48NwVaUOsNll10WaxFix450+94mvkdAIyWhdZ1gqK4Th4TUdfOO3nIChRpXV9ciQklJSZSkUWqS1q1b1+rxjDFIFItgxrUxa4z5Bc8InG6Mec155fma9QGGGGP+aox5xhjzk7O+tzHmRmPMJGPMk8BJwBLgL+6GItITa8BOA042xvzdGPNPY8wfcAosOdWH/wm8YIw5xxjztDHmMeA4bD33ioa2DnHe1wat/xKrnxOdzwOAVtgQ4mBj9mdjzO6g7dcAbUWkfQXHd/vaVEQeEJFZTlVlIyKjwrTt67Tb47R9VasnK5GwePHiWIsQG0qKYadjzLbtHVtZaomE1XUCorpOHBJS126YMSRURePq6rpBgwbs37+fwsLCKEmk1BR799ZexEFhYSH79++nQYMGUdtnXBuzETLPGPNr8EpjTKnmRKQV0AJrQB7pa3Yh9hz91RhTErS96yM/E1t86n8i0tZ9AcXAt8CpFcjXxnnPDlr/I9bTe4rz+WRgI/AKcKSINHa8tSc5cgfj7q9tBcd3aYs13PsCP4drJCIHAV8APbGG+t+Bc4FPRSQtwmMpSmKxawMU77PLbXvGVhZFURQlctwwY0goz2x1ad68OQBbtmxRg1YBrCG7ZYu9htzfRzRIidqe6i7BHk8AROQ84F7gCGyxJBd/IHcPbAhvGWPYhxsz+FmY74M9puEI8LcbY4pFZAGeF/ZkrNE6H0jGen63Aa0Jbcy6+4s0MH0L0NEYs1VEBgHfhWk3FmgCHGWM2QAgIguBT4FRRK8is1IPOfTQQ2MtQmxwvbKQMJ7ZhNV1AqK6ThwSUtcJGmZcXV03adKE1q1bk5WVxerVq0lNTUVEohpeqkSHoqIicnJyamz/xhiMMezfvx+wYc1NmjSJ2v4TwTNbxncuIicD7wMFwJ+A32A9rFMJMiojwD2HVzj7CH5VVIRpp/PeKsR384GjnSJRJwNfGmN2YcOhT8YzdEMZs+7+dlTcBTDG7DPGbI2g6cXAB64h62w7G1gJjIjkWEri8r///a/iRvURt/gTJIwxm7C6TkBU14lDQuq6YUtIcYr2JVCYcXV1LSK0b9+ezp0706JFC5KTk9WQraMsW7asRvcvIiQnJ9OiRQs6d+5M+/bto/pbqA+e2aqUxLoYa8gONcbsc1eKyFVB7VZjjdV+wE9h9rXaec90jLrKstx57wYEJyh8iS0OdRnQCc9o/QJryG4DVhpjtoXYbzdghzFme4jvqoSIdALaA4tCfL0QOyigKGF5+OGHYy1CbHDnmG3QApokRnp5wuo6AVFdJw4JqWsRaNYRstdC9rpYS1NrREPXIkLTpk1p2rRpFCRSaoru3bvHWoRqUR88s26xp5aV2KYYawQnuyucqsMXBrWbjg0zvl9EAs6VeEMKH2NDiceKSGrwgSIojPQ9UAgMCvHdt9gqyncCWcBSZ/2X2DDjwYT2yoKtkryggmNXFjfWJtTQ5BagtYiEzegWkfYi0t//woZyKwlCwk7Cvn2FfW/byz4YJQAJq+sERHWdOCSsrg9yHtHSZ0N+VmxlqSUSVtcJSLzruj4Ys9877w+JyBUi8jsRqSgQeybQGJglIqNF5H6s4Zjub2SMSQceAoYDX4rIrSJyk4i8DDzstNkN3ID1lP4gIveIyHUi8qCI/IidyicsxpgC4BPgjBDf5Tv96wN85Ss69QU2b9XvrS3FqWB8GPBeBeehsjRy3veF+K4gqE0o/oQNkfa/3gOYP38+8+bNY+LEiWRlZTFy5EjAu8DGjBlDeno6kydPZtq0aSxcuJAJEyaQn5/PiBEjAtqOHTuWxYsXM3XqVKZOncrixYtL50tz24wYMYL8/HwmTJjAwoULmTZtGpMnTyY9PZ0xY8YEtB05ciRZWVlMnDiRefPmMWvWLCZNmsSmTZsYPXp0QNvRo0ezadMmJk2axKxZs7RPQX2aMWNGvetTRXp6aOwtkPGtvQI6Hl4v+hSJnoYPH17v+lQf9RSNPnXq1Kne9ak+6ikafXrjjTfqXZ8i0dOalk5WV/E+nv/z6fWiTxXp6b777qt3faqPeopGn1zqSp8qXUnbTcqN5xe2kNNGPI9rV2e9AZ4Os80fsXmeBcAybPGi8TiFioPaXoWdAqgA6yGdC5wR1GYIMAvYhc3TTQdewhZKqkj+4VgPcOcQ3z3m9OOOoPWrnPXdQ2wzGuuxblbF8znI2feoMOuvKEfOBuXstz3QP+h1PmCWLFlilPrPb3/721iLUPsseNaYcc3ta93XsZam1khIXScoquvEIWF1XVJizFNH2Pv4v462n+s5CavrBKSu6XrJkiXGsSn6mwjsFjGlzj4lVohIMrZi8pvGmPuisL8fgbnGmDFV3N6tZnyVMWaKb30n7KDBncbOpevf5lXgN8aYNlQCJ9R4yZIlS+jfv39VxFXiiPz8fBo3bhxrMWqXfw+GLT9Byy5w888JE2ackLpOUFTXiUNC6/qrp+DT++3yyA+g28nlt49zElrXCUZd0/XSpUsZMGAAwABjzNKK2teHMOO4xxhTjJ3j9UYRqVaWvIicjZ0u6JFoyObHGLMJ2E7o/N5jCF8kS1EAePzxxyNrWFIChflQsBsKcmDvLtibbXOV8rMgbyfk7YA92yF3G+RutVUmd2+GnE2QsxF2Zdj5XbPX26IdWWshaw3sXA070m1Rpu0ra/a1+jNryAIcflnCGLJQCV0rcY/qOnFIaF0f/ntIckqjvHO1/R+pxyS0rhOMeNd1fahmXC8wxrwBvBGF/cwCarJs3DvASBHpbIzJABCR04HewJM1eFylHjB06FDvQ0kxbPgGVs6CzT9CTgbkZ0PRXiiuhxOsH5ZYM1cF6Fqp16iuE4eE1nXTdnD6fdY7u2cbTPkNnHgLDLgImh5Q7wYrE1rXCUa861qNWaUUEbkJWxX6QGfVMBE5yFn+lzEmB1v46rfA5yLyFNZwvh07rdBLtSuxEm9s2rTJLmSthXeugU2hZnmqh3Q/FdokVuHuUl0r9R7VdeKQ8Lo+8WbYvxfmPmIN2o/vtq+GLa1Bm9YYUpvY99JJMMRn6EpZo1fEri9drgM0aE5uXm845phYS6LUAvF+Xasxq/i5Deji+3yR8wJ4DcgxxmSIyGDgCeBv2GmFZgK3Gt+cvYoSiuzsbFgzD964HPbtdtYKdDwcWne3c7CmNrKvlAaQlIL35x/mvbzvyrRNCvFdDZOcBt0H1/xx6hjZ2dmxFkGpJVTXiYPqGhh8JzTrYHNos9bYdQW77KsecbI0hM0nw4EDYy2KUsPE+3WtxqxSijGma4TtlgLxHZOgxITBJxwD0y/1DNljR8Mpt0OTtrEVTIk6p5xySqxFUGoJ1XXioLrGDoIeNQqOHAkbFtg0mR0rbV2HwnwozIP9+YAB4xZldd/cZbf4qglcrgsYAztWkGYK4NXhcMU0NWjrOfF+XasxqyhKrfHrSzfTo9FG++HsR+G40eVvoMQtkyZN4sknNY0+EVBdJw6qax8i0OUE+6pvfPcCzLzVGugv/QYufhEO+U2spVJqiHi/rnVqHiWm6NQ8CUTeDsw/ByL7dkO7vjB6PiQnxniaMQapK7lQtUQi9llR6j3G1J28ztokEfu98Hn48HZKPcYHHgl9zoE2PaHrybYglqLUADo1j6IodY+cjeS+cIY1ZAHO/GvCGLKz18ym0UONmL1mdqxFqTVmr5lNSt+UhOpzIjNs2LBYi6DUBrNnMywlBWYn2HU9ezY0apRY/Z49m2HHj4a+d0KqM//o5h/g84fg7avgnwNhVQKdj3pOvN/D1TOrxJRSz+zNHeh/QGqsxVFqCFO0F3Gm25nTsCmn3ZGBJNX/sTRjDEc/fzTfb/meQR0HsfDahfXeW5mIfVaUeo8xcPTR8P33MGgQLFyYGJ7KROx3cJ8/fhN++i8seReyVnvtJBmGPgzHXAcJ8H+u1B6V9cwmhmtEqfsU5sK+5FhLodQQ7l//P1fv4y89dvNe+kec2/vcmMpUG8xcNZPvt3wPwKIti/hw1Yf1vt+lfZ4Gi4YnRp8TnZEjR/Lyyy/HWgylJpk5E77/npHAy4sWwYcfwrkJcF07/QYgUfodrOsFv8K598Jp98K+XFjxEbz/ZygqgFl3woqZcNIY6HQUNGwRa+mVKhDv93D1zCoxpdQz++wf6d9F8y/qIwbD/5a8zut5m5mxtwhpLBzV8ah677FzPZQ/bPkBg0Go//0O6HO+SRhdJzpZWVm0bt061mIoNYXrqfvhB7KMobUIHHVU/fdS+vpdmjNb3/sdqa4zvoO3RsHujYHbJ6dBg2bQoLmdYi9gKjwoOzWef37denpO44CioiJSzrwfep4ea1EA9cwq8crJfwEtAFUvmbnyA/6w8DH7P/UjmBNNQngp/V5ZsEZ9fe93QJ8TSNeJzosvvsjtt98eazGUmsLnnXwRuN2YxPBS+r2yYA29+t7vSHXd+Wj40wL49D74/mVKi0QVF0L+TvtS4oYUsJWr4xT1zCoxRasZ12+CvZOsA7pS772UZfrtUJ/7nai6VmDevHkMHjw41mIoNUGQd3IeMBjqv5cy2CvrUp/7XVVd52fBxu9g21IoyLHzyBfstmHI7n79c+4GvBO0rMSCrOwsWg/7K3SrG/PNqmdWiTfSANLT02Mth1IDzF03l+9/9o1sbwcaO17KzEU8++GzDO5a/x6Cy/TboT73O1F1rcDy5ctp27ZtrMVQaoK5cwO8k8uBtuB5KZ99FurjQEZQv0upz/2ulq4PgtYH1byMSo0wf/58TspvA0srtBtrBZ9NkBZJe/XMKjFFRK4AXom1HIqiKIqiKIqi1BkuMMa8X1Ej9cwqsWal834JdiBQqb/0AN4DLgBWV9BWiW9U14mD6jpxUF0nDqrrxKEu6joN6AzMi6SxGrNKrNnjvC+PJC5eiV98+ZKrVdf1G9V14qC6ThxU14mD6jpxqMO6/jHShjrLsaIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqzSqzZDjzgvCv1G9V14qC6ThxU14mD6jpxUF0nDnGva52aR1EURVEURVEURYk71DOrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyhxqyiKIqiKIqiKIoSd6gxqyiKoiiKoiiKosQdaswqiqIoiqIoiqIocYcas4qiKIqiKIqiKErcocasoiiKoiiKoiiKEneoMasoiqIoiqIoiqLEHWrMKoqiKIqiKIqiKHGHGrOKoiiKoiiKoihK3KHGrKIoiqIoiqIoihJ3qDGrKIqiKIqiKIqixB1qzCqKoiiKoiiKoihxhxqziqIoiqIoiqIoStyREmsBlMRGRFoAg4EMoDDG4iiKoiiKoiiKEjvSgM7APGNMTkWN1ZhVYs1g4L1YC6EoiqIoiqIoSp3hAuD9ihqpMavEmgyA6dOn07Nnz1jLotQk+/fBms/hgH7Q8uBYS6MoiqIoiqLUMdLT07nwwgvBsREqQo1ZJdYUAvTs2ZP+/fvHWhalJlnwDPzyV2jTE/78faylUWqYkSNH8vLLL8daDKUWUF0nDqrrxEF1nTjUYV1HlH4oxpiaFkRRwiIi/YElS5YsUWO2vvP+n+GHV+zyHWuhcevYyqPUKFlZWbRurTpOBFTXiYPqOnFQXScOdU3XS5cuZcCAAQADjDFLK2qv1YwVRakd9u7ylneujpkYSu3w4osvxloEpZZQXScOquvEQXWdOMS7rtWYVRSldijY5S3vTI+ZGErtcMwxx8RaBKWWUF0nDqrrxEF1nTjEu67VmFUUpXYI8MyuipkYSu2wNz8P9mTGWgylFti7d2+sRVBqCdV14qC6ThziXddaAEpRlNohwJhVz2x9p/ePf4Vvl8ElL8GAi2ItjlKDrF6taQOJguo6cYiGro0x5OXlsXv3bvbt24fW6ambJCUlsWbNmho9hojQoEEDmjdvTpMmTRCRqO1bPbMJiIg0EJFHRWSziOwVkW9F5MwItusjIk+KyNciUiAiRkS61oLISn0gIMxYH4jqNcbQrcgZsPh1ekxFUWoeZwoFJQFQXScO1dW1MYbMzEwyMjLIycmhuLg4OoIpUad79+41fozi4mJycnLIyMggMzMzqgMb6plNTKYAlwD/AFYBo4APReRUY8z8crY7Hvg/4FdgGXBETQqp1CNKimHfbu/zztVQUgJJOp5WL9m3GynZb5e3Lo6tLEqNM2HCBJ577rlYi6HUAqrrxKG6us7LyyMrK4vGjRvTsWNH0tLSoiidEk3Wr19Ply5davw4hYWFbNmyhaysLJo0aULTpk2jsl99kkwwROQY4HfA3caY240x/wFOA9YDj1Ww+ftAS2PMocB/a1ZSpV5RkBP4uWgv7N4UG1liQfF+2PyTNeoTgbwd3nLWWti3J3ayKDWOGjeJg+o6caiurnfvtgPYasjWfWrDkAVIS0ujY8eOgPf7iAZqzEaAiIwXkfoS6H8JUAz8x11hjCkAXgSOF5HO4TY0xmQZY3JrXkSl3rE3u+y6RMqbnf4n+M9gmPu3WEtSO+Tv9H0wkPlrzERRap5hw4bFWgSlllBdJw7V1fW+fftITU1VQzYOWLWq9opypqWlkZqayr59+6K2zyoZsyIyysmXdF8FTv7lxyLyfyLSLGoSKtFmILDSGBM8JLLQeT+idsVREgJ/8SeXRDJm139t35e9H1s5aou87YGft/4SGzmUWmHGjBmxFkGpJVTXiUN1dW2MIUlTieKCXr161erxRCSqObPV/ZXdD1wB3AD8y1n3D2CxiBxWzX3XJR4EGsVaiCjREdgSYr277sCaOrCItBeR/v4X0KOmjqfUIQpCeWYTpAhUSQns2WqXty8PbdjXN/xhxgBbl8RGDqVWGD16dKxFUGoJ1XXioLpOHNavX1+rx4tmJWOovjH7kTHmNWPMS8aYR4wxQ4EzgPbA+yJSLwxAY0yRE4pbH2gEhPLtF/i+ryn+BCwJer0HMH/+fObNm8fEiRPJyspi5MiRgBfmMmbMGNLT05k8eTLTpk1j4cKFTJgwgfz8fEaMGBHQduzYsSxevJipU6cydepUFi9ezNixYwPajBgxgvz8fCZMmMDChQuZNm0akydPJj09nTFjxgS0HTlyJFlZWUycOJF58+Yxa9YsJk2axKZNm0pv9m7b0aNHs2nTJiZNmsSsWbO0T06f9uV4843uK7G3nRULZsZ1nyLV00P33golRaX9f/BPF8V9nyrS09LvviCArYvjvk/1UU/R6lNeXl6961N91FM0+nTbbbfVuz7VRz1Fo0/nnXdetfuUm2sz09avX09hYSGZmZnk5OSQm5vL1q1bKSoqYu3atYAX6pqRkUFBQQE7duwgOzubvLw8Nm/eTHFxcel0QW7bjRs3kp+fz86dO9m5cyf5+fls3LgxoM3q1aspLi5m8+bN5OXlkZ2dzY4dOygoKCAjIyOg7dq1aykqKmLr1q3k5uaSk5NDZmYmhYWFpQaf27Y+9ckN+a2tPhUVFbF48eKwvz33u0iRqrh5RWQU8BJwtDFmUYjv7wYeBq4zxjzvW38a8ABwJLAfmAfcZYxZ5mvTBbgTOB04GMgHPgNuN8asCyHDYOAP2FzQVGA6cLMxJtvXdh3WcPq78+oPpAN/NsbMFZGLHLl6AUuBa4wxP/q2Hw+MM8aIb50BJgGzsZ7bXs4+bzXGzAo6H52ACcC5QEun3ePGmMkhTm+NIiJLgG3GmNOD1vfD9n20MebfEeznNmAi0M2vlwq2aQ+0C1rdA3hvyZIl9O/fP5LdKPHIdy/AzFvtcteTYd2X0LAl3LEGkpJjKlqNs3UxPHeS93nI3TDkrtjJUxvMuhu+ecb7nNoY7t5Y/3WdoEyaNIkbb7wx1mIotYDqOnGorq7deUtrY9oXpXpkZmbSvn37WjteRb+NpUuXMmDAAIABxpilFe2vpoLZX3Xez3JXiMgZwMdYr+144AngBOCroLlKj3bWv46dBuY5rGE7V0QahzjW00BfZ5+vYA3b6VLWh90TmArMAO4GWgEzROQPwJPAa8A4rHH1pohEcm5OAp5xZL0DaAi8IyJtfP0+APgG67F+GrgZa8y+KCK3RHCMaLMFG2ocjLtuc00d2BiTaYxZ6n8BCRJrmuD4C0D1u8C+F+yCLT/FQpraJXdr4OeMhaHb1SeCw4z359uqxkq9pEcPzRZJFFTXiYPqOnFo0KBBpdqXlJQwZcoUzj//fDp37kyTJk0YMGAADz74IAUFtR/IWiPzzBpjNopIDoH5kBOBLOB4Y0wWgIhMB37EekVHOu1mGmPe9u9PRGYAC4CL8Qxll0LgdGPMfqetO8XMMOxUMi59gBOMMQucdr9ijevngUOMMRuc9dnAv4FTgLkVdLUv0M8Ys9rZ9nPgZ+AyrOEK8BCQDBxqjHFLfD4nIv8DxovIv40xeys4TjT5CThVRJoHFYE61ve9okQXJ0+0OCmN5N5nw4e32fWrP4NOR8VOrtogNyhFfeOi+j/HrlsAKqUhFDl/bFt+grY9YyaSUnM0alQvMoqUCFBdJw6q68ShsoW68vPzueqqqzjuuOMYPXo07du3Z8GCBYwbN445c+bw2WefRT0vtjxq8mlqD9AMQEQ6YqvkTnENWQBjzC/Ap8BvfOtKDTsRSXW8nOnALmx4cjD/cQ1Zh2eBIv8+HX51DVmHb533z1xDNmh9JHERs11D1tef3e62jnf4Yqw3WESkrfvCGtItwvSpJnkba1xf564QkQbAVcC3xpgMZ93BInJILcum1FcKdgGQbxpAy87Qxqmct3puzESqNYI9s/tyYMfK2MhSW+Q7ntnOx0CK80C06tPYyaPUKAsXJkC0gQKorhMJ1XV8UVBQQElJSZW2zcvLq1T7tLQ0vvrqKxYsWMA999zDtddey+TJkxk3bhxz585lzpw5VZKjqtSkMdsUcOckdWfjXRGi3TKgrYg0ARCRRiLyVxHJwBYq2gFsx+aatgixfcDkSMaYPdhQ2q5B7TYEtctxFjOC2rnrW4U4VjAbQqzL9m3bDiv3ddg++F8vOW1qL0gdMMZ8C7wF/9/emcdHVV6N/3sIEAIhLAKCCAYRBMVWlGK1LmhVcKtLbap1AeuGtvaVVkUpVRAERa11rfV9QVR+uKFUEVcUXGoVQa2AQlkFkTVEthASwvn98dxJbiYTMpPMzM3MnO/n83zu3Oee+8x5cnLvnXOf5zmH8SIyQUSuwa1JzsdNlQ7xNM42FYhIKxEZKSIjcVO/AX7v1f0+8dobKYs3MpvTxpvN3v1kt13zKezeEYxOySJ8ZBbguzT/kbDTm4TSqgv0OM19XvI67IlfXjmj4XDllVcGrYKRJMzWmYPZet+MGjUKEWHZsmUMGTKE1q1b06pVK6644gqKi4uryU+ZMoWjjz6anJwc2rZty0UXXVQRrClEfn4+Q4YMqXbugAEDGDBgQMX+nDlzEBGee+45Ro4cSefOnWnevDnbtrkJly+++GLFd7Vr145LL72UtWvXVmlzyJAh5ObmsnbtWq699lpyc3Np3749N910E+Xl5fvse9OmTTnuuOOq1Z9//vkAfPPNN9WOJZKEOLMiciDO8axLIsmHgT8DLwAFuHW3pwGF1E/fmixTU3004+O1nRvSdwquD5HKv6L4nnhzOS6F0mXAQ7jAWWer6gf7OgnnpI/xyiCv7k/e/k0J0dRIDzxndvn3npPT/RS33VsG3wZxCSSR0Mhsu0Nd0CuARdMDUyfhqFZOM27RDg4/z33evQ2Wzw5MLSNxhKKcGumP2TpzMFtHR0FBAdu3b2f8+PEUFBQwefJkRo8eXUXmrrvu4vLLL6dHjx789a9/5cYbb+Tdd9/lxBNP5Icffqjzd48ZM4aZM2dy0003MW7cOJo2bcrkyZMpKCggKyuL8ePHc/XVV/Pyyy9z/PHHV/uu8vJyBg4cSHZ2Nvfddx8nnXQS999/P0888USd9Fm/3v3eadeuXZ37VBcSsmYW5ySBm0oLEEpgdGgE2V7AZlUNjXFfCDylqn8KCYhIM9wIZyR6ALN9srm4YEav10nz+LIJNzqdpaqzglYmhJdm6Gav1CQzIELdKqJz8g2jKt4040N/7C3Nzj8eGjV2KWuWvAE9BwanW6IJjcy26gwHD4C5/3BrhQuXw35pGGBj9zb3kgKgeTvoMbBy7ezX/4RDB+3zdCP1eOqpp4JWwUgSZuvMwWwdHX379mXixIkV+4WFhUycOJF77rkHcOlu7rjjDsaOHVuRCgngggsuoG/fvjz22GNV6mOhpKSEefPmVaxvLisrY/jw4fTp04cPPviAZs2aAXD88cdz9tln88ADD1RxtEtKSvj1r3/NX/7yF8ClhTrqqKOYOHEi1113Xcz6TJgwgby8PM4444w69aeuxN2Z9dLv/AVYCfw/AFVdJyJfAoNFZLyq/uDJ9sGNvE7xNVFOdYfpBtw6z0hcIyJP+tbNXofr1xv17039UNVyEXkJ+I2I9FHVhf7jItJeVTcFpJ5hJA9vZPbdf83n5xcD2S2h20mw/F34z7MuVU3LjoGqmDBCI7MtO8FPrnTOLMC8STDwruD0ShT+SMYt2kN2LvQ4Hb55FRZ7U40bxxY50WjYnHPOOcyYMSNoNYwkYLbOHBJq6zdudWnrGgIdj4Az7q7z6aGcuiFOOOEEpk+fzrZt28jLy+Pll19m7969FBQUsHlz5fOxY8eO9OjRg9mzZ9fZmR08eHCVQF3z5s1j48aNjBo1qsKRBTjrrLPo1asXM2fOrDZqPHToUJYuXUqPHj0q9H/mmfBYu7Uzbtw4Zs2axWOPPUbr1q3r1J+6Ul9n9gwvSFBjYH/gFNzU2W+BX3gjgCFuxjmY/xaRiUAOzkndikurE+I14DIvGvLXwLG4tDaFRKYp8K6IvIAb+b0e+IiqkYyD5FbgZOBTEflfXJ/a4gI/nep9Noz0xhuZ/fnZv6ysO+FPzpndUwL/ehAGjQ9Gt0Sytxx2bHCfW3aE9odW5tn9YgqcMhKapFnEyCrOrDfV6PDznDO7eyt8/jT0vzoQ1YzEYM5N5mC2zhwSauv1C+DbjxLXfhLp2rVrlf02bVzYnKKiIvLy8li6dCmqWuEshtOkSZM6f3e3bt2q7H/7rZsIe+ih1SfC9urVi48+qvo3b9asGe3bt6d9+/ZV9C8qKgo/fZ88//zzjBw5kiuvvLJOI7r1pb7O7J3ethSXdmcBcCPwpKpu9wuq6iwRGYRLw3MnUAa8DwxXVX8Cwv/Bjc5egsvb+i+c0/cWkfm9J3snbu3ns8AfVFXr2be4oKobRKQ/cDtwAc7ZLgQWAcOD0MmLXnwnbjp4G+ArYKSq1hpuVEQ64/Lyno5bEzwbGKaqKxKnsZHSlJdBqQvy9Macf3NGaJZp/s8qHbt5k+BnN0LL/QNTMyHs3ATqRRds6QW/6vdb1+eSH+Cjv8HJtwWlXWIo9jmzzb2U24eeBa27wg+r4d0x0PsX6WfrDGbYsGE88MADQathJAGzdeaQUFt3PCIx7daFeuqSlRV54mjIDdm7dy8iwhtvvBFRNjc3t+JzTelsysvLI55b3/RJoTbXrFlDly5d6tTGO++8w+WXX85ZZ53F448/Xi996kqdnFlVnQxMrsN57wL7jNfsTUH+bYRD+TWcUqyq1wLX7qPNiOeqarX/mkjrQlV1FFVHjyOeW9N3qepGnNPdUCL+TsatTf4bLhr0EOB1ETlZVWt8VeatR56NC+41DvdCYhjwvogc6cujaxiVeFOMAfqdcFrVYwNuhckfutHZl66ES19Krymo/rQ8oWnUvc+B9r1g02J4/x7n1Hc7MRj9EkH4NGOAJs3gzPtgaoEbnX3rNvjlREhiHjojcfzud78LWgUjSZitM4eE2roe03pTje7du6OqdOvWjZ49e+5Ttk2bNhEDQn377bccfHDtGUMPOsglj1myZAmnnHJKlWNLliypOB6Of2Q2Fj799FPOP/98+vXrxwsvvEDjxokKxbRvEpmax2iAeKPEFwG3qerNqvoEbnr4t8CEWk6/Hhdw62xVnaCqoRHaTrioxoZRHW+KMcCiFd9XPZZ/PBx2nvu86kN4+WooKyFtqOLMeiOzWU3gV5O9/KsK034Lqz+NdHZqstMXBqCFL6Jhz4HQ62z3eeFL8NowNw3bSHk++KC2QPhGumC2zhzM1vHhggsuICsri9GjRxM+aVRVKSysHAfq3r07n3zyCaWlpRV1r732WrUUPjXRr18/OnTowOOPP87u3ZWp8N544w2++eYbzjrrrIjn7dgRe4rEUHv5+fm89tpr9R4lrg/BuNBGkFyIm8ZdEXdbVUu8dczjRKSLqtZ01VwIfKaqn/nOXSwi7+LSKNVtBbuR3vhGZpvmRXj7d/7jzulb8wl8/Qqs+w+cOhoOPSP1R2n9OWb9Aa469IYzJ8CrNzjn78kz4NjfubWkrbtWbyeVKHYP5j2Nsmkcvh74zHth3VewdTXMfxI2LYEBw10wMBulTVlCa8SM9MdsnTmYreND9+7dGTt2LLfddhurVq3ivPPOo2XLlqxcuZLp06dzzTXXcNNNLrvlVVddxbRp0xg0aBAFBQUsX76cKVOm0L17dJkPmjRpwj333MMVV1zBSSedxMUXX8yGDRt48MEHyc/PrzHdUk1TpWti+/btDBw4kKKiIm6++WZmzpxZrc/HHntsTG3WB3NmM4++wH9VdVtY/VxveyRQzZkVkUbAj4BJEdqcC5wuIi3D10pHTcm2Kk6PkUZsq0zU3apjfvXjTXLg4mdhyi/h+8+haBW8OBiy8+Cg42D/PpB3ADRv69ZgNmvtRjcbNYGsxm7bqDE0qulmHMFJitZxiigXg9NVtKryc4sOVY/1vQzKdsHbI6G8FD5+CD5+GDr9GDof7Zza3A6u5LSFrKau3xV9bwoSNrmmmr6yj2Phov7j9XAsPQd+T3ab6g+YvAPgyredrTcugtUfw9PnQu7+cNDP3PTr1l0hp7Wzf7M8N4It4uwrWWHbgCYXBeZ4N0yHv2uHVnb/zgSataJz587xb3fvXtByl6pt7x6Xqzpq6hAeJdaQKllNoGmL2L9nX9+/t9ylMAvFVIiol0Z3LOLxetI4O/62rtBRPfXjqXMAYXJCtgv934YIzTjy1d96y030PKQ7Dzz4YEU04S5dunD6aafyi7PPrJAbeNrPuf++Cfz1gQe58cYb6dfvaF579Z/86eZbAK38norvKK/63cCQyy+lebNs7p4wgeHDh9OiRQvOP+9c7rl7PK3zcivlffo3bZLl9qN8phYWFlaMFt96663Vjg8ePDipzqw0kDhJRpIQkYXABlX9eVj9YbigVENV9R8RzmuHy5t7u6qOCTt2PfAo0EtVl+zjuzsA4UNz3YFXFl7XgsM7xPZmyEg9Hmv0W66/vYaAEuV74LP/g9nj3LrKdKJ5O7hleeRj676CmX+E7z6LfDxFWUtHOo+q4XZQshVmj4fPn4Ky4uQqZhhG3cg/gTGr+/OX22+vXba02C0dWfcfNwNj50YoLoJdW9zL69AP/b17CMQRiQlx8R0GVP/RXo3NS2H1J7D+K/dib8cmF9G+ZKsLhlhe6kpD73OjJrymJ3P2HS/WLlu2C1b/G9bMhcJlsHUtlGxlxcGXQZdjOLhNIxp8fw1ofZAbNEgCK1a4mLE1rQNetGgRffr0Aeijqotqa8/WzGYeOcDuCPUlvuM1nUcdzw1xPbAwrLxSyzlGmlBc3pghf/gz55xzDgAjRoxgwYIFTJ06lalTp7Lg628Y8epq+OPX3LOiN/T5Jd/vbo420NGomOj044p+FxQUUFxczJgxY5g7dy7TP1nOpEa/YfWZU3lvdx/o8lN2laf+rXlrTleWLVtWMa0p1P/Bgwezpbicexfux7/6P8HX+VewvOnhlLew6MaG0aBZ9SG/u+QsCgoKACLey1+Z/CA/TLyQ0ru6uIBvs++ChdNg5QewYYGbqVO6HfbsciOTKeHkKKWfTqzIBRp+Lx9752hWvDyWonuOhEf6wau/h7lPwDcz3PKZopXOiS/dDuW7SYk+7y3jhLzvmD59OpMmTYp4L//TlRdSMu06yu46EJ45H+aMhwUvuhk3Gxd5LyqVlOivAbhAU6WlpWzcuJGtW7eyfft21q9fz549e1i50iWeWbp0KeAiIJeUlLB582aKiorYuXMn33//PeXl5SxfvryK7HfffUdxcTGFhYUUFhayZ88eFixweYYj/TYKHYsWG5nNMBrsyOyUP3P4wQfUpUtGKiAC3U6k4IbRvPDCC7Gdu2c3FG9xazGLC90b7r1lbnpNeZn7XF5W/bwa720R6iPKRitXC42zXQTj3A61y/q/p3QH7NjoSskPlW/19+6pfLu/L32qHKttStq+prPVgexcBk+YzlPPTY/tvNKdbv10yVbYvc2N4OzZ7U1BLA/b7q06RS9pBPTMbMDP6slPTWbI4CFBq2Ekik2L3SwK4NYVP+XupyNkSlSFD++H9yd4DpuPvAO9pSL7uZGfZq28pSH+0shtpQ7LB2Ke9h+D/NK3YcVsp9vITU5PP9s3wPRrYMWcqvVNmkOrA90SitwOkNMGsrK9pSLekpGIy2PCdNvX8o99LSupD/95FtZ/xdrdLeg8/vvIMvMnw8ybvBcSPvI6uxG+nDas6Hw+7N+bgzuFRvvEU1HC9E+DF9YpzubCQtod0M1lHkgC8R6ZtTWzcUJECoDHga6qGlNYMBEZigue1ENVI418xpN1QKSFEF6oVWq4c7EFNyrbKcKx2s4FKlIUbfTXVeTUOvJiOPzwfZ1upAExO7LgnMG8Tq5kCiKQ3dKV/aIL/NDQeOq5y2M/qWmLlO1vJjPk2OuDVsFIJN9+XOHM3n3H8Mgy794JH/21cv+wc+GIX7m0Y81aJUHJBCGNnDO7d497mZrrex9f9C1MPM1NIwbnuB49xL287HDYPuI4NHAKl8H6r+jcumn1Y6rOzu/eWVnXYyD0vRS6neCc9hCew0KeDVQ0dNrF8rK9ARL4XDYROU5ERolI66B1qSsikgWMBh6O1ZH1mAw0ZR+5cuPIl0BPEckLqz/Gd7waqroXWAD0i3D4GGBFnYM/GRlDaDqJkf6YrTMHs3Wa43NQ7hl9W/XjHz9c6ci27gq/fRsKnnZOXSo7slA1Cv0OX6q1PaUw7YpKR/ZHF8ENn8PJI6DjEanryEJlSrVdRS6WhZ8FL1Y6sjltYMjrcMkLcNgvqjqyRkoRmg6cqgTuzALHAXcArQPWoz6cAxyKL91NLKhqCfAU8EeRhIfJnAZkAdeEKkQkG7gC+DSUlkdEuopIrwjn/kRE+vnOPRSXpzaKKAFGpjNjxoygVTCShNk6czBbpznNWld8HH7DNVWPbVkB79zhPud2hMtfha7HkDa09M0I8ucNf3c0rJ3vPve/Bi74B2TnJle3RNHclx981xbf5x/grRGVMle8Cfk/S6pqRmLo0aNH0CrUi4bgzEaNiDQSkeRM6I6NK4B/qeraWiVr5gXgIODk+KgUGVX9FOd4jheRCSJyDfAekA/c4hN9Gvgm7PTHgOXATBG5WURuBN4BNgD3J1JvIz0IBdAw0h+zdeZgtk5zclpXfHzrlbClIh/c59awA1w0Fdp2S55eyaClLzBdKG/45mXw70fc504/htPHJl+vRNLC58zu3Fz5efZdLi86wKC7oUP4eIeRqnz33XdJ/b54x2sK1JkVkVHAvd7uShFRr+R7x1VEHhGRS0RkEW7N5iDv2E0i8rGIFIrILhGZLyIX1vA9l4rIXBEpFpEiEflARE4PkzlDRD4UkZ0isl1EZopIrYs4Ped6EDArwrGQ/ueJyEIR2S0ii0RkULisqs7HrUs9t7bvjAOXA38DLgMeApoAZ6vqB/s6yZtGPAD4ABgJjAH+A5ykqpsSqK+RJlx88cVBq2AkCbN15mC2TnOa5LjgRcBRh/kCthQud8GCwE0pPvDoAJRLMLm+acahkdl5kyrrzv+Hi+uQTvid2WLPmS1c7lLnAeSfAEdE/LldBRFh794ggvQZsdK2bXJS8oRQ1cqYOXEg6JHZlwHvTsgwnHN1GS5qbohTgAeA54H/AVZ59f8DfAHcjguetAd4UUTO8n+BiNwBPAOUebJ3AGu8dkMylwEzgR3AcJyTdhjwUcix3gdH49a7fl7D8eNxI5rP4UY+mwEvich+EWQ/BxI+Z0NVS1T1ZlXtpKrNVLW/qr4VJjNAVav9p6nqd6r6K1VtpaotVfUcVV2WaJ2N9CDWcOtG6mK2zhzM1hmAtx5y6/pVlXUf3FcZUXxAhLW06UCTZpVrQbevczlVv/x/br/bidChd3C6JYrmEUZmF75UaetB46OKIJ2dnU1ZWRmlpaUJUNKIJ7t27Urad5WWllJWVkZ2dvxeAgUazVhVvxKRz4GLgX+q6qoIYocCR6jq12H1PVW14q8vIo/gnME/4hxTROQQnAM7HbjQC2IUkhdvm4sbnfw/VfWvI30KWIJzlMMWiVQhNM9iZQ3HewOHqepyr93ZuNHMi4FHwmRX4Jx5wzAMwzCMhkFOa9ixnqZ7i93+nlL42ksT3/sc2D+NsxG07OSCIW3fAIv+6VKlAfT7bZBaJY4qI7OFbrvon27b4XAX4CoK8vLy2Lp1K+vWraNTp040bRohOrKRUZSWlrJunZuun5cXHoe27qRCap73IziyhDmybXBBjT7EOYkhzsONPt/pd2S980MTtk/DBZ961sulGqIc+JTa17CGRliLajg+K+TIet/7lYhsAyIlVyoCckSkuaoW1/K9hpFyHHFEdA9BI/UxW2cOZusMwAsC1TbHm9C35hMo2+k+H3ZeIColjZYdYePXbmQ2NMU4d3/odXaweiWKHN+U052bYfNS2Oil+jz8vKibadGiBW3btmXLli0sX76cJk2aICJxnV5qxIc9e/awdevWhLWvqqgqZWUuL3Hbtm1p0aJF3NoPeppxNEQc8RSRs0XkExEpwa013QRcB/jjwHcH9gLVnGEfoRBe73lt+MvpQLTJl2q6OldHqCsCIsUwD7UR35XR4V8i0lpEnhCRTd4a4dkiclSU5/YXkce8NcplIpJQXY304tlnn61dyEgLzNaZg9k6A/CCQG3b8K3bXxYKEyLQ/ZSIp6QNoYjGhcvgu7nu848vhqwmwemUSLIaV06t3rmpclQWYnpxISJ06NCBLl260KpVK7KyssyRbaB88014vNf4IiJkZWXRqlUrunTpQocOHeL6v5AKI7PVJnKLyAnAq7hARNcD63BrYq8AfhNj+yGH/jJgfYTjeyLU+fHmYNAGiBQOrLyG8yJZsQ1Q7B91jjci0gg3DfvHuOBbm3F/wzkicrSq1pZs6kzgKuAr3LTononS1Ug/xo0bF7QKRpIwW2cOZusMwBuZPaBNc7e/7D237XwUNE9u8JikE8o1u3tbZV23E4LRJVk0b+emVhdvhjWfuroOh0H72H7yiQi5ubnk5qZJ2qI05eCDI00WTR0awshsXUb2fgmUAANVdZKqvqGq1aIJ49LINMIFc6qJ0BTgjao6K0KZU4sui71tPOLRd6N6Opx4cyEut+8QVR2tqo/iIhSXA6OjOP/vQCtV7YdLy2MYUXPOOecErYKRJMzWmYPZOgPwRuqKt3zvovpu8IJ+HXJqgEolCX9EYwAEOvcLRJWkEVo3u2ERbFjoPh+WjGQbRhCk+j28ITiz3qILWsdwTjnOCc4KVXhRh88Lk/snbprx7d6IJD750MjoW8A2YISIVJszIiLta9FlPlAKxOPOdhTwcRza2RcX4vLCvhyq8NLqvACcKyL7DC+mqhsSOXJspDczZswIWgUjSZitMwezdQbgTTNunlUOS9+urO/+82D0SSYtw5zZ9r2q5N5NS5p74WAKfckquv40GF2MhJPq9/CG4MzO97Z3ichlInKRiNS2Kngm0Bx4U0SGisjtuGBNVVLEeClj7gLOBz4UkT+JyO+9SMXjPJltuLW2JwCfi8ifReQaERkrIl/gUvnUiKqWAG8D9Xo9KSJHA22BV+rTThT0BT4PD4gFzMX9TW3asJEwCgoKglbBSBJm68zBbJ0BeNOMgco1lNmtoHMa5pYNJ7RmNkSXnwSjRzLxRzQOsb8FektXUv0eHviaWVX9TET+AgwFBuEc7G5UjthGOuc9EbkSuBX4Gy5I1HAgH/hRmOztIrISuAHn2Bbj1ns+45OZKiLfe+3dDGQDa3HRkZ+MohuTcLlju6jqmijkI/ErXLCo9+p4frR0wq01Dmedtz0ASEjSQBHpAISPdHdPxHcZDZPJkycHrYKRJMzWmYPZOgPwj0Su8YIgdT7KBQtKd8JHZrscE4weyaR5mDPbshO02C+yrJHypPo9vCGMzKKqY1X1QFXNUlUJ5Zv1Pv++hnMmqWpPVW2mqr1VdbKqjlLVaoGVVPVJVT3Kk22rqgPC19iq6hxVHaSqrVU1R1UPUdUrVHV+eHsReBVYSlg+2pr0V9V8VR0S2vem9g4G/upLGVQrItJIRJpFWUJ/lxxgd4TmSnzHE8X1wMKw8grARx99xPvvv8+9997Lli1bGDx4MFA5j3/YsGEsW7aMSZMmMX36dObOncuYMWMoLi6ueKMUkh0xYgQLFixg6tSpTJ06lQULFjBixIgqMgUFBRQXFzNmzBjmzp3L9OnTmTRpEsuWLWPYsGFVZAcPHsyWLVu49957ef/993nzzTd59NFHWbt2LUOHDq0iO3ToUNauXcujjz7Km2++aX0K69P999+fdn1KRzvFo0+XXHJJ2vUpHe0Ujz6ddNJJadendLRTffq0ZM0mKijdDsBrnyxJ6T5Fa6fnZs7Gz3V3PZnyfarNTm99VPWn786W3VK+T+lop3j1qW/fvg2qTwsWxDamJjH4TsY+EJFf44IjdVXVHTGeOxQYAfRQ1UiOZk3nDQBm1yIWoreqLhaRHcDzqnplWFtn4qZvD1LVt6L8/keA30V6gVCDfE0js68sXLiQww9P46TrBgBz586lf//+QathJAGzdeZgts4AVn8Kk06vWjfobvjpdcHok2wmdHeRfZu1hltWQqMGMRaUOL56EV6+qnL/ZzfCadHECDVSkYZ2D1+0aBF9+vQB6KOqi2qTz4D5IclBVZ8Hnq/juY8Dj9fh1MW4dETRsM637RTheKju+zroERWquhHY6K+znGOZxdq1a4NWwUgSZuvMwWydAUQKeNQ2g1YJtcl3zmzXY9PfkYXqU4o72nrZdCbV7+HmzKYwqroemBzjaV8CJ4hIo7AgUMfg1hP/Nz7aGUZ1ioqKglbBSBJm68zBbJ0B+ANAhdgvg5zZQePhi2fg2BuC1iQ5hK+Z3b9PMHoYSSHV7+HmzGYe03DpeS7wPiMi7XABqGb4pzmLSHcAVV0eoR3DiJkTTzwxaBWMJGG2zhzM1hlA+MisZEHrroGoEghd+ruSKfijGWdlw36HBKeLkXBS/R6eAXMljDCmAZ8AT4rI7SJyPTAHl7M3PA3Ru16pQEQOEpGRIjISL7duaF9ELku49kZK8+ijjwatgpEkzNaZg9k6A2icDU2aV+63OQiymgSnj5FYmvumGXfolRlRqzOYVL+HWwCoDERE2gD3Aufhohd/BtykqvPC5FaBi77sqxtAzUGn3lfVATHqcjiw0AJAGYZhGEYD5v7esN0Lq3HIaXDptGD1MRLLPfmwqwj6XgrnprazY6QWsQaAspHZDERVi1T1KlVtp6otvFRF8yLI5fsdWa9ujpdyKFIZkKw+GKlJKAR7ppGJLw0z1daZiNk6Q/BPNc60aacZeA//+5L94MD+8NPfBa2KkWBS/R5uzqxhGElh1opZvHPMO8xaMat24TRi1opZ5NyVk1H9zlRbZyozZswIWgUjGZT4HLpMCv40axbk5LhtpjBrFtdNXQT5w2H/w4LWxkgwqX4PN2fWMIyEo6rcOutWdk/bzW2zbsuYkcqKfpdnTr8z1daZzODBg4NWwUg0qvDf1ZX7bQ8OTpdkogq33gq7d8Ntt2XGCK3X58GZ1OcMJ9Xv4ebMGoaRcGYuncn8dfNhIMxbN4/Xl74etEpJoaLfZE6/M9XWmcwDDzwQtApGopk5E9b50nd8tbpm2XRi5kyY7+7hzJsHr2fA/czr8wOQOX3OcFL9Hm7OrGEYCUVVGTVnFILAFyAIo+aMSvsRuyr9JjP6nam2znQmTpwYtApGIlGFUaOg2LuOyxTGP5r+I3ahfou7hyPi9tO5374+T4TM6LOR8vdwc2YNw0gooZE6RaEzKJoRI3ZV+k1m9DtTbZ3p9O+fQfk3M5HQ6OT8UoqW74G3S2De/PQfsQv1O+TIqab/SKWvz/0hM/pspPw93BJHGUHTFGDZsmVB62EkAFVl+LThsMmr2AR4qQqHTx3OQRcehITeeqcR1frtI137nam2NmDx4sW0a9cuaDWMRKAKw4e7z0XKR1OKOT50bPhwOOigypHLdMLf73DStd9hfV4MVFzV6dpnA2h493CfT9A0GnnLM2sEiohcBjwdtB6GYRiGYRiGYTQYzlXVV2sTspFZI2j+620vxL0INNKX7sArwLnA8oB1MRKL2TpzMFtnDmbrzMFsnTk0RFs3BboA70cjbM6sETQ7vO1iVV0UqCZGQvFNMV1utk5vzNaZg9k6czBbZw5m68yhAdv6i2gFLQCUYRiGYRiGYRiGkXKYM2sYhmEYhmEYhmGkHObMGoZhGIZhGIZhGCmHObNG0GwCRhMxiYmRZpitMwezdeZgts4czNaZg9k6c0h5W1tqHsMwDMMwDMMwDCPlsJFZwzAMwzAMwzAMI+UwZ9YwDMMwDMMwDMNIOcyZNQzDMAzDMAzDMFIOc2YNwzAMwzAMwzCMlMOcWcMwDMMwDMMwDCPlMGfWCAQRyRaRe0TkexHZJSKfishpQetlVEVEfiIij4jIIhHZKSKrReQFEekZQba3iLwpIjtEZIuIPCMi7SPINRKRW0RkpYiUiMhXInJxDd8fVZtGYhCRP4uIisjCCMeOE5GPRKRYRNaLyEMikhtBLuprPdo2jfggIkeJyKvetVUsIgtF5A9hMmbnFEdEeojIcyLynfc3Xywit4tI8zA5s3UKISK5IjLae0Zu8e7VQ2qQDez5HEubRmSisbX3dx7i3dPXiPvNtlBERopIsxravVJEvvHsslREbqhBrrO4334/iMg2EXlFRA6uT5txRVWtWEl6AZ4FyoB7gWuAj73944PWzUoVO00D1gEPAVcBI4H1wA6gj0/uQFyOsmXAH4ARwBbgS6BpWJvjAQWeAK4GXvP2LwqTi7pNKwmx/YHATs/WC8OOHQnsAj4HhgJjgRLgjQjtRHWtx9KmlbjY93RgN/AJMMy7Fu8GJpid06cAXYAiYBVwq2ebJ7177itm69QtQL5nx2+B2d7nIRHkAn0+R9umlfrZGsj16v8N/Nn7W08Cyr1zJEz+Wk9+mif7tLc/PEK7/wU2ALfgnhergTXAfnVpM+5/n6ANZCXzCtDf++e+yVfXzLspfhy0flaq2Oq4CA+mHt4Pkim+useAYqCrr+5Uz87X+Oo6A6XAI746AT7wboxZsbZpJWG2fw54F5hDdWf2deB7IM9Xd5Vnm9N9dVFf69G2aSUuts3DvZR6GWi0Dzmzc4oXnJOhwOFh9U959W3M1qlZgGygo/e5HzU7s4E9n2Np00r9bA00BY6LcO7tnvypvrocYDPwWpjsFNwL7Da+ulu883/iq+sF7AHG1aXNeBebZmwEwYW4N0VPhCpUtQSYCBwrIl2CUsyoiqp+rKqlYXVLgUVAb1/1L3E3sNU+uVm4t3kFPrlzgSa4B2FIToG/4970HluHNo04IyIn4q7TGyMcywNOw73M2OY79DTugeW3TVTXeoxtGvXnN8D+wJ9Vda+ItBCRKr8HzM5pQ5633RBWvw7YC5SarVMTVd2tquujEA3y+RxLm0YNRGNrVS1V1Y8jHJrubf2/2U4G9sNnF49HgRbAWb66C4HPVPUz33ctxr3s9ts6ljbjijmzRhD0Bf4b9oADmOttj0yuOkYsiIjgfghv9vY7Ax2AeRHE5+LsHaIvburqNxHkQsdjbdOIIyKSBTwM/J+qLoggcgTQmDDbeC89vqS6vaO51mNp06g/pwLbgM4isgTnXGwTkb/71laZndODOd52oogcKSJdROTXwHXAQ6q6E7N12tIAns9RtWkklI7edrOvLvR3D7fhfNxLrpCtGwE/iiAHzobdRaRlLG0mAnNmjSDohHsrHE6o7oAk6mLEziW4qUPPe/udvG1NNm0rItk+2Q3em9lwOai0fSxtGvFlKHAQ8JcajtdmmwPCZKO51mNp06g/PXCOxivAW7hRlkk42z/pyZid0wBVfRN3LZ8GfIFb6/Yc8LCqDvPEzNbpS9DP52jbNBLHLbiXl2/46joB5aq60S/ovWwqpNIubXFTnKO95qNpM+40TlTDhrEPcnCBR8Ip8R03GiAi0gs3ZeTfuDVXUGmv2my6m+htH0ubRpwQkf2AO4ExqrqpBrHabJMTJhsPe9s9Ib7kAs2Bx1U1FL34ZRFpClwrIrdjdk4nVuHWKL6E+1F5FjBCRNar6iOYrdOZoJ/P9nsvQERkBG4mzvWq+oPvUA5uLXMk/NdntLaOpc24Y86sEQS7cG96wmnmO240MESkIzAT2ApcqKrl3qGQvaKxabS2j6VNI36MxUWkfHgfMrXZZleYbDzsbbaOL6G/57Nh9VNx0SiPxQV3AbNzSiMiF+HWt/ZU1e+86pe96YP3iMiz2DWdzgT9fLbfewHhLScYC0xU1b+HHd6FCxgVCf/1Gauto2kz7tg0YyMI1lE5TcVPqO77JOpiRIGItMJNUWkNDFJVv41CU01qsukWVd3tk+3orbsNl4NK28fSphEHRKQHLs3GQ8ABIpIvIvm4h1ATb78ttdsm/H8jmms9ljaN+hP6e4YHBQpND2uD2TlduB74wufIhngVNzrfF7N1OhP08znaNo044uV9fho3ADE0gsg6IEtEOoSd1xQXxClkly24Udlor/lo2ow75swaQfAl0NOLdujnGN9xo4HgBYSZAfQEzlbVr/3HVXUtLt9cvwin96eqPb/E/YDqHSZXxfYxtmnEh864Z8JDwEpfOQZn+5W4EP8LcSH5q9jGe2AdSXV7R3Otx9KmUX/me9vOYfWhNU2bMDunC/sDWRHqm3jbxpit05YG8HyOqk0jfojIMbgIxvOAAlXdE0HsS28bbsN+uN8BXwKo6l5gQQQ5cDZcoarbY2kzEZgzawTBNNzD9ZpQhRcs4ArgU1VdE5RiRlW8yLbP46Yd/kpV/12D6EvA2f60SiLyc5wT9KJP7hWgDDdaEJIT3JvDtYA/rHy0bRrxYSFwfoSyCBc05nzcdKWtwCzgUl8UQ4DLcGsx/baJ6lqPsU2j/rzgba8Mq78K54DMMTunDf8F+opIz7D6i3ERRr8yW6c9QT6fY2nTqCci0hs3GrsKN/hQ09Te93CjrteF1V+HW2Iy01c3DfiJiFQ4qSJyKHAKVW0dS5vxJVEJbK1Y2VfB/ZgqAybgHor/8vZPDFo3K1Xs9DdcsuxXgUvDi0+uCy7s+zLgBuA276b2FZAd1uYEr81/4H48v+bt/yZMLuo2rST0f2AOsDCs7ihcQIfPcT9KxuLWw7wV4fyorvVY2rQSF7tO9K6753E/NF/w9seZndOnACfiXlBswEU1vh543bP1/5qtU7sAvwdG4nJ7Ks7JHOmVVp5MoM/naNu0Uj9bAy1xL57LgeFU/812bFh713vtvOjZ5Slvf0SYXEvPzhuAm3H551fjXka0r0ubcf/bBG0cK5lZcOvw7sXNsS/B5asaGLReVqrZaY53I4pYwmQPx6X52AkUAVOA/SO02ch78K3CrcVYCFxSw/dH1aaVhP8PLIxQfzzuR+wu3FrLR4CWEeSivtajbdNKXOzaBLjDuw5LgaXAjWbn9Cu4qZ+ve7YpBZYAI4DGZuvULt71W9MzOt8nF9jzOZY2rdTd1l6p8fcaMDlCm1cDiz27LMM5qhJB7kCcg7oV2I5benZIDXpG1WY8i3hfbBiGYRiGYRiGYRgpg62ZNQzDMAzDMAzDMFIOc2YNwzAMwzAMwzCMlMOcWcMwDMMwDMMwDCPlMGfWMAzDMAzDMAzDSDnMmTUMwzAMwzAMwzBSDnNmDcMwDMMwDMMwjJTDnFnDMAzDMAzDMAwj5TBn1jAMwzAMwzAMw0g5zJk1DMMwDMMwDMMwUg5zZg3DMAzDMAzDMIyUw5xZwzAMwzAMwzAMI+UwZ9YwDMMwDMMwDMNIOcyZNQzDMAzDMAzDMFIOc2YNwzAMwzAMwzCMlMOcWcMwDMMwDMMwDCPl+P/vSAdpGD8q8gAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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5tqrRWQN1uu4E+u1vASruevTxpjCWsZanXuwaopvE5FTgC+wpljKwErcbjPGbG3gOWpjNla5BUrewUogfw2Mxhro63OsvtntsPrS/g74B+7BwtwDLD2FlSSvFpG5WJ9BzsOqBd5TjxjD+Vr9HpgqIsuBrUAO0B6rSfyxWP18a+p/rpRSqoE0mVVKqQhhjPmPiJRhJRkjsEaM/RIYhTV9TJWkzxizUEQGYg1adA5wPlaTzw3AVL9tF4vIr7CmGrkAK1Eox0o0PgferWO8xSLyDlbNLARuYlyv66rmOKUicg5WM9nzgFOAtVgJay4BklljzC4RORlrqpk/cmTE5X1YidgzHOlvvA2rpnIoVjPWNu7jbsRKrCpN71MfxphcETkduBe4ArgT6/VYAUwzxnza0HPUMg6XiNyNNc1MoPUVInI5Vl/hkVgJfRpwACu5ux+r5tTXRKymwTdhjZa8D+s1m0QNI2RXE0M4X6tFWM3jB2ONmNwCa9CyTVi1wU9XM8qyUkqpIJLqxxlRSimllFJKKaWaJu0zq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RSSimllFIq4mgyq5RS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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7MAAAFbCAYAAAAHltmpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAABJ0AAASdAHeZh94AADAwklEQVR4nOzdd3xTVf/A8c9JunfZeyMoOBD3AByPGwf64BbcuMXx4AbEBx8Ft7h+irhwC4ooKCrLhYADUJE9yijdeyQ5vz/uTZqkaZu0SdM03/frFUpv7jg3JzfN955zvkdprRFCCCGEEEIIISKJJdwFEEIIIYQQQgghAiXBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCCCGEEEKIiCPBrBBCiIijlNJKqcXhLkdjKaX6K6XmKKX2mOdSEO4yCSGEEJFGglkhhAghM1AJ5DE23GUWoaWUsgJzgTOAz4HJwP/CUI6xbu+7x+tYZ4T5/NvNXb5Io5S6zO31vCbc5RFCiGgQE+4CCCFEKzfZx7LbgXTgGaDA67nfQlsc0QL0Bg4A/k9rfV24C2O6VSk1Q2u9LdwFiURKqe7A80AJkBLm4gghRNSQYFYIIUJIaz3Je5nZ+poOPK213trMRRLh18X8uSuspaixEegHTAUuDXNZIo5SSgGvA7nAJ8Bd4S2REEJED+lmLIQQLYRSarHZRTFOKfWQUmq9UqpSKTXLfD5dKXW3UupbpdROpVSVUmqfUuozpdTR9ex3oFJqplJqq7m/bKXUMqXUDXWsO0sptcPc/16l1Gyl1AA/z+Ei8xyequP5eKVUvlJqt1Iqpinn5WPfs8xj9/LxnLO77CQfz7VRSj2qlPpLKVWulCpUSn2jlDrFx7pxSqlblVKrzfMoM1/XT5VSJ/tRRg0sMX+d6NYtdZLbOulmedYrpSrM4yz0tX/381JKHaGUmq+UyqvrdajDB8CvwMVKqcP83AalVIxS6kal1E9KqSLztfhVKXWzUsritW6dr7/5/Fal1FavZc5u0GOVUqeZ10eh+Ro612nsa3WI+VoVmOVeopQ6xt9z93IrcCJwJVDayH0IIYRoBAlmhRCi5fkYuBH4AXgaWGMu3x/4L+AA5gNPAl9jfJFeqpQ6zXtHSqkzgdXAGGCduc3HgBX4j9e6p5nrXgr8Yh77G2AUsEIpdagfZZ8LFAKXOINVL+cAGcA7WmtbY88rWJRSPYFVwD3APuAl4H2zTAuUUtd6bTILo3t4LPAm8CywFDgQ8Keck4E3zP8vMX+fDCw2y5OBUe/3YLyOT2PU19HAV0qp6+vY79HAMiABmGkeo8qP8gBojNZEBUz3ZwOlVCzGeN8ZGPU5G3gF43vFc9ScYzBcYB6rmJr6acprdZi5XQLwqrnv44Bv/L1p46SU2h9jvPMzWuulgWwrhBAiCLTW8pCHPOQhj2Z8AFsxAoheXssXm8v/ANr52C69juXdMLqs/uW1vB3Gl/wqYLiv7dz+nwnkAznAAV7rDcYYC7jaz/N72TyPs3w8N9987sDGnpf5nAYWey2b5et1NZ8bYT43ycdr7gAu8lqegTF+uRzo6FZOB7ASsPo4Rls/Xx+fZfF67V4GlNvy/mZdVrqfn9u+NHB9gO/DseZ2j5i/f27+fraP/b/tte0kc/lz7q8Fxk2S18znzvHnnN2uia11lM8BnBbk12qs176uN5e/EMDrF2O+F9YDiV6vyzWB1IU85CEPecijcQ9pmRVCiJbnQa11jvdCrXVhHct3Ah8BA5VSPdyeGgOkAS9qrZfUsZ3TFRgB3ESt9Z9e660F/g8YopQ6wI/yO1vlxrgvVEp1Ak4FftVaO1ubG3NeQaGUOhgYDnystX7P69gFwESM1rvznYsxWi8rMQIs7/LmNrE8ccBlGDcO7tVau7rTaq03YLQCx2HUlbfftNYvN+X4GC31duCxOlrVneW0ALcAe4DxWmu7WzntwJ0Yr1Wwxt9+qrVe4FWGprxW32utZ3ktmwnYgCMCKNdDwBCMwLg8gO2EEEIEiSSAEkKIlmdFXU8opY4FbsPoStkB4wu7u67AdvP/R5k/v/TjmM6xqQfXMa5xP/Pn/sCfPp530Vr/oJT6BxiplMrUWuebT12K0XI3y3ubAM8rWJznnF7HObc3f+4PoLUuUkrNA0YCvymlPsbo2vuz1rosCOUZACRhBFt5Pp7/FngAI4DyVud7xl9a6z+VUq8B15mPF+pYdT+gDbABeEAp5WudcszXLQh8nVtTXquV3gu01tVKqb0YPRQapJQ6ErgPeEJr/aM/2wghhAg+CWaFEKLl2eNroVLqPIyWygqMMaWbMBLOODC6UA4H4t02yTB/ZvlxzLbmT+8xot78nXbkDYxxsBcBL5rLxgDVGOMrXRpxXsHiPOd/mY+6uJ/zhcAE4BJqpl2qUEp9BNyltd7bhPKkmz931/G8c3mGj+d8vmca4SGMc5uolHqrjnWcr1t/jNbrugRrihpf59aU16qgjm1sGDdb6mW2Wr8J/AM82ND6QgghQkeCWSGEaGHcu0x6mYIx/vUwrfVf7k8opV7GCPrcFZg/u1KTRKouhebPg7XWf/hf2jq9hVHeMcCLSqkhGEmSPvXRpTjQ86qLs+uvr79tGT6WOc/5Nq31s/4cwOxOOgmYpIy5RYdhjO28DOgFHO9nWX1xlqdTHc939lrPo2hNOG7NTrTeq5SahhGo34Nxc8Gb8/hztNaj/Nx1fXUDRv0U1FWsesrQmNeqqVKo6alQUUfL9P8ppf4PIzHU7SEogxBCCCSbsRBCRJJ+wJ8+Aj4LRjZWbz+ZP0/3Y9/OdZsSjLlorXdgdPU80swQ6xw/6yvLbaDnVRdnd+buPp7zNeVMk85Za71Da/0OxjjgjcBxSqm2DWxWn/VAGUZX7wwfz59g/lzdhGP4YzpG4q3xGEm4vP2NEXgeZWY19keddaOU6kdNS6u/wvlaVWIkufL1+NVcZ7n5u3RBFkKIEJJgVgghIsdWoL9SqotzgTKahSYBvhIzvQEUATcopYZ5P6mUcg9UXscIUCYqpWolwVFKWZRSIwIs7yzz59XAxRiZkj/3sd5WAjuvujjHVnp0lVZKHYgxHteD1nolxpjXUUqpq3ztUCl1oFKqg/n/9ua+vCVjtNbZ8H86nFq01lXAO0AqRmu1ezn6YsxnWo3R6h0y5vjfB4FEfHQj1saUSs9htH4+q5RK9F5HKdXZK1nY3xjvxXOcr6e5XiJGsqZAyxi210prXa61vsbXA/jMXO0Nc9n7wT6+EEKIGtLNWAghIsdTGPNs/momH6oGjsUI+JyJiVy01jlKqUswxqN+p5T6EmPanzTgIIxWst7murlKqQuAOcBPSqlvMOal1eZ6R2OMlUwIoLxzMAKY2zHmZX1Oa13d1POqx6cYSYkuNgP1n4EeGHPbfgqM9rHNJRgtyK8ppW41tynAaJE8CGNaoqOBbIzu2r8qpdZgvI47MF7LszC6uz6rtS72s6x1uQejpfhmpdThwHcYUyyNxgjcbtZab2niMfwxC6PefAXvYASQBwPjMBJ9fYsxNrsDxljaY4H7MZOFmQmWnsEIkn9VSs3B+A7yL4xW4F2NKGNLea2EEEKEibTMCiFEhDCnXrkSI7nNGIzswDuAI6mjO6XWej5GF9t3MDK73gX8GyNIfdRr3W8wArgXMMZ/jsNoVR2MEfBdFGB5y4APMQJZ8N3FuFHnVcd+KoCTgA/MMt8M9MEIWF+sY5udwFCMwMtuHvtW4BiM7MnXUzPeeCtGS2UORjfWO4BRwBbzGLf7W9Z6ziEPI3h+HOPmwR0Y9bUCY67VujIMB5XW2gHcXc/z1cC5GFPfrMcI6O8ETsP4bvEgxnvO3UTgXoxEX9cBZwAfY3TT9nWTo6EytojXSgghRPiouvOMCCGEEEIIIYQQLZO0zAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgSzAohhBBCCCGEiDgx4S6AiG5KqXRgOLADqApzcYQQQgghhBDhEwd0B5ZorQsbWlmCWRFuw4FPw10IIYQQQgghRItxDvBZQytJMCvCbQfA3Llz6devX7jLIkJs5syZXHXVVSE9Rtlvv5H/zmwyLjif5COPDOmxRN2ao65FyyB1HT2krqOH1HX0aGl1vXHjRs4991wwY4SGSDArwq0KoF+/fgwaNCjcZREhdvbZZ4e8nrc/+ywpmzeTsGAhvVvQh3O0aY66Fi2D1HX0kLqOHlLX0aMF17Vfww8lAZQQotmUl5eH/Bj2ggIAbLt3h/xYom7NUdeiZZC6jh5S19FD6jp6RHpdSzArhGg2mzZtCvkxHCWlANjy8tB2e8iPJ3xrjroWLYPUdfSQuo4eUtfRI9LrWoJZIUSzMcdAhJSj1Ahmsdux5+eH/HjCN/e6dpSVsf2qq9g29kocZWXhK5QIiea4rkXLIHUdPaSuo0ek17UEs0KIZjNlypSQH8NRUuL6v23fvpAfT/jmXtdFX3xB6Q8/UvbTTxR//XUYSyVCoTmua9EySF1HD6nr6BHpda201uEug4hiSqlBwNq1a9e21MHnIoJoh4O/Bw0G83Ot+ysvkzJsWJhLJbZfcy2ly5cDkH7O2XR57LEwl0gIIURzcDgc7N27l8rKShwOR7iLI8JEKUVsbCxpaWmkpqailKpz3XXr1jF48GCAwVrrdQ3tW1pmhRDNZuTIkSHdv6Os3BXIgrTMNhd7UVGt8cnOurYXFFD600+u5aU//IjcRG1dQn1di5ZD6jp6BKOuHQ4H27dvp6CggKqqKvnsb6GKi4tDun+tNTabjeLiYrKysti+fTs2my1o+5epeYQQzWbevHmN2q70hx/Ie+NN2t0wjsRDDqlzPdd4WVNjg9nSn36mOmsn6eedh7LIPb/6lK3+lW1jxpB44IH0fOdt191WZ10Xf/MNuP3Rsu3bR9XGjcT37x+W8orga+x1LSKP1HX0CEZd7927l/Lyctq0aUOHDh3qbY0TrZ/NZiM7O5vCwkLy8/Np3759UPYb8d/SlFJaKTXJ7fex5rJejdjXCHPbEW7LFiul1vqxbS9z27FuyyYppbTXeluVUrMCLZsQrcG4ceMatd32q66mZMkStl50cb3rOUpLPH63ZQcezNqLi9lx/fXsvv8BSpYuDXj7aFOyeDFUV1O+erVrWiSoqeuihQsBUAkJrudKf/ihOYsoQqyx17WIPFLX0SMYdV1ZWYnVapVAtoXbtm1bsxwnJiaGzp07Y7VaKSkpaXgDP7XIYNYtIK3rcVS4yxgsSqkDzKC3V7jLIkSoPfjgg03eR33dlBxeH462nJyA92/buxddWQlA1ZatAW8fbard5vN1v3nw4IMP4igro/RHo4tx+jnnENOpEwAlEsy2KsG4rkVkkLqOHsGoa4fDgdVqlUC2hevcuXOzHUsphdVqDWqX8xYZzLp5CLjcx2NjPdu8BSQCjbnNsNTctjHNMdvMbd9qYL0BwLVuvx8ATAR6NeKYQkSUuXPnNnkftuzsOp+rFcw2opuxvahm7Ii9sCDg7UPFlp/fIscA29yD2Zya8s2dO5eq7duhuhqA5COPIPmYYwAo+3kFRV98IeOnWolgXNciMkhdR49g1bUEsi1fgVuvquYQ7PdESx8z+6XWemUgG2it7YC9wRV9b+sAKhq5rfZnW611ZWP2L0Rr0Ldv3ybvo/Lvv4nt2NHnc/YgjJl1FBfV7K+wMODtQ8FeUMCmk/+Frqqi78IFxHbpEu4iuXi0zLq93n379qV6507X77HdupF2+mkUfvIJuqKCrDvuJHPlKjo9JC09dXGUlVG2ahVJRxyBJT4+3MWpUzCuaxEZoqGutcMBSkV9EBYNdS0M8S3474s/WnrLbMB8jZlVSlnMrry7lFJlSqnvzO69HuNXfY2ZdXtuqFLqB6VUuVJqi1JqnNfztcbM1lE+1zHNdT80n/rOrRv1CKXUG0qpHKVUrI99fKWUWu/nS+K97eFKqeeVUuuUUqVKqe1KqQ+UUvv5sW193b87NaY8IrokJiYGvI02W/acKtb/U+e6jpLawWygrX/24prWXXsz362sS8X6f3CUlqKrqyn79ddwF8dF2+1U793r+t09mE1MTKQ6K8v1e2y3bqQcfzydp07F2qYNAPnvvos9xFkUI42jtBRdVQXArgn3sOPa69jTwucAbMx1LSKTr7re9/wMtl54EVU7doShRMFVvTebjSecyLaLLsZhXofRSq7r6GGJ8ESXLb306Uqpdl6Pto3Yz6MYXXlXAncDG4CFQLKf22cCXwCrgP8AO4EXlVJXNaIs7pYCz5r/n0pNN+q/MLortwVOdd/ADBpPBN5u5DEnAOcD3wC3Aa8Aw4DVSqnBfu7DV/fvgkaWR0SRFStWBLyN3avrcOXff9e5rnc3Y11ZiSPAYMm9ZdbRQlpm3cvUkroa23Jya2UqdlqxYgVVO41gViUlYc3MBCBj1Hl0+d+jxkpaU756da39Vu/NpsqtVTccKv75h9zXZlL0xRcerc+hoquryX7qadYfcSRbRl9I2epfKf76awAKP/o45MdvisZc1yIyede1vbiYnBkzKP/9d/LeeDNMpQqe4oULse3dS/nvv1P2yy/hLk5YyXUdPUq9erVFmpbezXiRj2WVQIKP5T4ppToCdwBztdbnuS2fCEzyczddgDu11k+a274M/Aw8qpR6S2tdXe/WddBab1ZKLQNuBb7WWi92K98+jKD5MuBzt80uxrgJ0dhg9kngEq2165ajUup9YA1wj3m8hgTc/VsIgKuvvjrgbbyn26lYX3enBO9sxmAEWNa0NL+P5z5m1tZCWmY9ytSIDM2hYtu9y+N3u1vCrauvvprS+x8AIK5rV48ue4mHHgoWCzgclK1cRcrw4a7nqrOy2DzqfHRZGb0+eJ+E/fcP8VnUprVmx/XjXOOBVVwcXZ95mtQTTgjN8aqr2Tb2SspXrQKMGzbbr7nG9bxqRBewgo8/oeyXX+hw913EtG3MPWD/FH/7HRe3b492OII+jZWurkbF1uqcVEve7NkUL1hIp8mTiO/du951q/fsoejzz6natg0Vn0CH8bdjSfb3vnbdylatIv+d2WRedhlJhw5p8v7CSVdVUb5uHUopEg46CG2zUfzV18R171brM7zy779dc3uX/fxzOIobVBV//eX6f9mKX0g59tgwlia8GvP3WkSmdu3ahbsITdLSW2ZvAv7l9Tg9wH2chBG0v+C1/LkA9mEDXnb+YgaCLwMdgKEBlscv5vjdd4CzlVKpbk9dCvygtd7SyP3+4B7Imss2AOsAv781KqVSlVLWxpRBRK/x48cHvI13y2rVli04KnwPT/dumYXAWzIdJTXHcxS0wJbZehJgNTfvFkv3QHv8+PGuMbOx3bp5rGdNSSF+4AAAylZ63hfb9+xzOAoL0dXVFISpRbJ6+3aPxFa6qopd99xL9a5ddW6jHQ52PzSRLaPO9+heXbUzi+3XXkfem3W3WhUvXuwKZDGDN11W5no+0GA0//0P2H3//RTOnUvBhx8FtG0gqrZvZ+ctt1D8v8fqPb9Aaa3Zfu11/HPkURT6Mdfl3oenULZiBdvHjG1w3Z0330L29Cco+PAj8t9+m7w338SWn8/WSy5l52231xrW4FS9N5u9jz7K7ocm4igv93iuZMkStl95FUVffMHOm25qUb0nApXz4ousP/wItl18CVsvupitF17ElvNGseuuu9h6yaU8et11OCorKVmyBHtxMRV/1fSUqdywAVteXhhLX5ujrKxWfTlpu52iBQvZetHFbDjxRCr++ccrmDVaJqt27nR1/Y8mjfl7LSLTjiYOEaiuruaAAw5AKcX06dODVCr/tfRgdoXWepHX47sA99HT/OmRAVlrnQfk+7mPXVpr7zZ458C9XgGWJxBvYmRIPg9AKTUAI3huKGNyQJTRZNIR8Hcek++AIqBMKfWZUqq/n8fpoJQa5P4AJMNAFHnjjTcC3qZWgOpwULlxk891vRNAAdj2BTY9j2c245YRzHq0zLagL8rVu/d4/O5etlmzZlFlBnXewSxA0mGHAVC+dq3r5kTF+n8o/Owz1zpFXy1E2xuVzy9g2m6n9KefsRcVUbFunWt5mzFXAEaX86w776qzPHmvv07BBx9Q8eef5L1Z8xFd8P57lC5bxt7/PYYtv+ZPji0/n7KVK9EOB5Vu48B7f/RhrZZC794J9Sn+7jv2PPyw6/fqrNB11y794UcwX4+c52c0aiosX8pW/ELpsmU4ysrY9Z8J5Lz0EkVffknV1q211nVU1uRUtGVn1xt02HJyqFjrOW18ydJlFHz4EeWrV1O8cCHFixYZ74UffjDG3Nts5Lzyf2w67TTy3niTgg8+IG/WLAC0zUbeG2+w4+ZbXMe15+ez+6GJEZmpu3rvXvY9P8M1NRlAxZo1VG0yP2/tdm60Wtl+xRh2XD+OXffcS8V6z2EfZd7dkEtKyXvzTXZPnMSu++5v1jH/1Xuz2XjKqWw69bRan5va4WDnrbeRdfvtlP/2G7Zdu8l/6y0qN9Z8VSxfs4bsJ55k08n/YncUTknUmL/XIjL1bqBHS0Oee+45tm/fHqTSBK6lB7NRTWv9J8Y4XWfX38uAKuCDIB/qUqAr8H4D65UBszBazM8DHsdo+f5BKdXdj+PcCKz1enwKsHz5cpYsWcK0adPIy8tjzJgxAIwcORIw7hBu3LiRmTNnMmfOHFasWMGUKVMoKytj9OjRHuved999rFmzhtmzZzN79mzWrFnDfffd57HO6NGjKSsrY8qUKaxYsYI5c+Ywc+ZMNm7c6Lob6Vx3zJgx5OXlMW3aNJYsWcKCBQuYMWMGWVlZrknFneuOGzeOrKwsZsyYwYIFC+ScvM5p5MiRgZ9Tbm6tN9KOpUt9nlNFrtEq4EhKcq2bu3FjQOf0gzlOEYwg4s7bbgt7Pa1YXHMPb9/69S3mvffJK64OKwCUZmW5zun4gw92tS7Gdu1S65y+NsfTUl3Nuw8/TFZWFt9cdZWryyKAfV8O27/6qt5zmnH0MWy//nruuemmxp/TH3+w4NRT2T52LPNGnEC5M5i1Wnm1ooKqE43uxeW//sqGjz6qVU8Tzj+f7KeedpV7j9v1tPLjT8w3k4PSH35g3LhxbPvqK/484QS2XXY5K/73GGs+N0aSFMTHkzBgAG+mpqASakbTVJeUNHxO997L2ocfZseNN7kCTDBalUP1GbHA7Q68o6SEZVdfw4IvvuD7119n4dlns/urrzzee7qqyq96+uymm2reVFqz7+lnyBp/BxvPOZcp4+/wKOc1F13k8R786umn6zynx8deWfOa9ugBQOlvv5E75xPX8iX33c/uBx9i+1VXs+HEk1h13PHse/JJtFvr3oaXXqZ6zx6+PXQoex/9nzH9VEwMxV2MuRpLvvuON6++mrKyMi76979xVFY26TPi81df5fVXXvE4pytOO43Sn35izBVXBO2zvOCjj1zvneUH7I/lwtE4YmJwxMRgG2DkiKz4/Q/Kf/8dgMJvvqF85SqP1/+3t9/2OKdXTz6ZvVMfpeD99yn85BO2XHoZq598sln+Pr1y2WXYc3KwZWdT+Pl8j8+9xffcQ8k333iUvfDTzzxyAGCzkft//wdAwefzmXj33fXWU0v8m+u+bqDvveOOO67J57R8+XIAtm3bRlVVFdnZ2RQWFlJcXMyePXuw2Wxs2WJ0NNywYQNgtBJWVFSQk5NDfn4+paWl7Nq1C7vdzibzxopz3Z07d1JWVkZubi65ubmUlZWx0+wR5Fxn06ZN2O12du3aRWlpKfn5+eTk5FBRUeFqkXSuu2XLFmw2G3v27KG4uJjCwkKys7Opqqpi27ZtHuu2tHNybteYc/rtt98afU5//fUXkydPdr0/HA5Hg+dks9lYs2ZNne8953P+Ui3x7qGZ5fd14PCGxmYqpTQwWWs9yWvb3lrrrUqpSzC6656itf7abbu2GC2Rb2itx5rLRmC0Op7gHL+qlFoMHAtkuLfOmtmMXwSO1lr/ZGZP3gJcqbWeZa4zCZiotVZu220FFrsd83zgI/djep3frRjjXLsDy4Hftdaj6ntNAqGUGogx/ncdcLw5tVEg2x+HkcjqFa31uAbW7QC091rcF/h07dq1DBo0KJBDiyhROG8eu+7+j8eyjH//m85THq617o4bbqTku++IHziQqs2b0VVVtLnySjpO+E+tdeuy/drrKF22zPV7/+XLiAnzeJJd99xLoTnnnyUlhQErW0Zikh0330zJIs8vhANWr8KSlET5H3+wdfSFAHR7/jlSTz7ZYz1bbi4bjj0OgHa33kLbq69m/SFDQGtSTjyRkiVLwG4n89JL6fTgAz6PX713LxuHjwCg8yNTyLjggkadR97s2ex9uCZjcHz//lRu2ED8gAH0+XQu9uJi/jn6GLDZyLzkEtd0QhX//EP2/x6j9McfPYJwgH7fLCK2a1c2nvwvV3fr9HPOIfX008i67XZX61fKiSdStWULVVu2kHLCCXR/0RgRo7Um96WX2PeMkSNw4B+/o+Li6jyH7CefIveVVwBjjK1r/277DCatNRuGDcPu1fMhrmdPY35hrYnp1Il+332LUgp7SSlbL7qQqo2biOnYkZQTRtDpwQdRVs/RKracHDaccCJUV5M4dChVW7Zgd+u62mnSRDLdAtjKjRvZfNZI1+8ZF19E54kTfZZ5z8NTyJ892xgD/dST7LzpZr/PN65vX5IOPZSCD40JCGK7d6fa/NIY27MHnR+eQsKA/dh01kjsOTkkHXYY3WY8z5bzRuEoL6fPZ58S0977z1/Dcl5+hX1PPUXy8GH0eNm4eeSorGTjiSdhz82l69NPk3baqQ3spWHabmfjyf/Ctns38QfsT++PPzbqrbgYHA5UTAybzhrp0f3el7g+fej7xXzX75vPPofKf/5BJSSgbTZXsBisctdn68WXUG62BCcOGUKvd2cDULllC1vOG4WuqCC2SxfSzh5J7ksv17erZitza7N582YA+vTpE+aSBN+kSZOYPHkyGzZs4JFHHmHu3LlorRk1ahQzZswgye2mOsDbb7/NU089xZ9//kliYiKnnHIK06ZNo3v3mragXr16MWLECGaZvT+cRowYAcDixYtdP0844QTeffdd1q5dy+uvv87u3bvJy8sjIyODDz/8kP/973/8+eefJCcnc9ppp/HYY4/RtWtX1z7Hjh3LRx99xPr167nppptYtGgRiYmJjBkzhsceewyr1b+RhFdddRXr1q3jvffeo0+fPkybNo277rqr3m0ael+sW7eOwYMHAwzWWq/zuZKbaGiZ/QZjzOsNXsv9/ytmjLm93vmLUirO/H0fRstpUzgD5Iw6nn8X0MAzQB8an/ipFjMz8nygELgg0EAWQGu9HCMYPtmPdbO11uvcH4Dv/qKiVWrUmFm3bsbxZjKg4sXfGXMB1rGuNSWFmM7GbFGV6+vOfuzzeEVFHr+3hOl53KevcZSUBNTtNJRsXt2Moaar8atTp7qW+epmHNO2LXFm16byVauNgMUMCFOGDyf5yCMAKP7qqzq7jtr21By/sfVUvmYt2Y/+z2NZpXk3OcG8wWZNTSXpcKNbdMnixa4upNnTp1P6ww+ucqefc45rHyXLluMoK/MYP1uybBm777nXoxtn2apVVJl3x+P3q5khTSmFxe3LUF3j/gCqtm4l9/XXASPI6vX+eyQdfjgA9uKiOrcLRMEnc/hr8IHkvPSS65jOQPaPXj2J6dDBWL5tm+v1sO3Z4wrkc557jipzeIBt714K3nufkqVLASOQKvhkDjvG3WC0LJvjVjvceQf9vvuW3p/OdQWCxd95jjTyHgpQ8s23Pj8bAFd22sSDDiL52GPrvTmgkpJIGT4cS3IybcaOpffHH9Hhrjtd2zgD2bQzzqDPZ5+RfOQRWDMySD/zDONYq1eTPf0Jqnftwp6fT5Fbjw9/Vaxfz77njPQepUuWurKDV27ciN3sseLeLb8xtNaUr1lL3qxZrkA1c/SFroRt1tRUrOnpWJKT6fzIFKpiYkj91788eg6AcRMDoGrzZvY9+yxlK1diLyl1XUttrriCHjNfw5JqpADJf/fdJpW7IbZ9+yg3W5vA6FVRvXcvZb/+yvYrxqDNoQ2dH32UtDPO8NhWJSYSP3BgrX2WLFkS0jK3NDJm1j+jR4+muLiYRx99lNGjRzNr1iwmT57ssc5///tfrrjiCvr378+TTz7J7bffzjfffMOwYcMoaMJ3jClTpjB//nzuuusupk6dSlxcHLNmzWL06NFYrVYeffRRrr32Wj755BOOO+64Wsey2+2ceuqpJCQkMH36dIYPH84TTzzBK+aN0YasWLGCN954g6effjqs8zK39GzGp5sth95+0Fpv9mcHWuu9SqlngDuVUp8BC4CDMRJJ5WAEig3ZBUwwW1//AS4EDgGua2wmYze/AXZz/+kY2Zq/1Vpnm+Xfp5RaAPwbY/qb+XXsJyDmsb7ECKKP11rXndmkYTuAAcEol2jdbnLvPugn96l50s85m+y//sK+L4eKNWtIPPhgj3WdQZ4lOZmU/Y4lf9t2Slf8gr2gAGtGhn/H80o41RLGzXoH2LZ9+4gLQgbWpnImgIrp3Nn1RdiWk0Ncz56ccsghOH4zuiP6CmYB4gcMoGrLFqqzsjwSx1jbZJJ66mmU/vAjtn372HHLLXR7+mksXvMeuo+D857Cya/yZ2Wx48YbjKQ/ViuW+HgcbomXEgYd4Pp/6ogRlP34E9W7dlG1caPRemuOdU046CA6PfQQCQfsT8ny5dhzcylZtoyEwYM9u027nWPSkUdS9vPPHtM/xff3TD+g3IPZ0lKs6emAEfxhsbi+POydNt0IAJWi61NPkTBwIBYzg7ejyPP93Bhaa/Y9/xyY40fbjB1L2Yqa3gGH3nknfY4+mrw33iB/9rvEdOhApZlIp2zlKhzFxeS9ZYwjjh8wgMpNm8Bmo+ynn0kYOJAd111H5QaPtBbE9+9H4pAhRkbdAQNIGTGCgg8/pOzHn3CUlbkCfXuh17WRnU3FmjXEdOrEjuuuJ2HQILpM/S+2/HxXYJV0xOFYEhJIOuww42YEYG3blvg+fVwBb/tbbqHtlWPRWtd8SUtIIPWUUygyu4XHdOxIp0kTsbhlm0458SRjihqHw9WKC+AoDuz9qW02dt//gEe315JvFtFmzBiPMdalP/yAo7y81rXhr33PPOPRKmlJSiLtrLN8rpty7LEkzfmEbv37s2PcDZSYrUQAmVdczt4pjwCQ88KL5Lzyf3R64AHX+z/xkINJPuII0s87l/w336Lsl1+w5efjKDWut7huXWsdrymKv/uuVm+J3fc/QOnPP7tulrS9/nqSjzwCrTUxHTtiM+fMTthvPxKHDnVNAxffvx+VGzZSsmxZSLJ2t1SN+Xvtrz1Tp1L5V2A3mkMpfv+BdDK7XAdqyJAhvPbaa67fc3Nzee2113jssccAo+vuxIkTeeSRR1zdugFGjRrFkCFDeOGFFzyWB6KiooKVK1e65gSurq5mwoQJDB48mKVLl5Jg3nQ67rjjOOuss3jqqac8Au2KigouvPBC7r77bhISEhg3bhyHHnoor732Gjfc4N0G6ElrzS233MKFF17I0UcfzVYfOQ2aS0u/Ih/GSHbk/RgW4H4mAFOAw4HpQD/gFEABvtOiesoHzgAOA6ZhdPm9WWv9fwGWoxat9R5gHEZm5NcwWmIP8FrNmSbyA611JU2klEoA5gH7AWeZY3Obog9GK7UQ9VpqtsQEwvUl0Gol7fSaO+jFXt1bAezm1DyWlBRSTznFWGizUfzd4gCO1/KCWe8AuyUkgXJUVLiCs8SDDnItd5Zt16+/AWBNT8eakuJzH84svbbcXOx5NcmRYtq0If2cs0k42Nhv6ZKl7PrPhFrbu78OjpLAWqvtxcXsGDfO1brY8Z57at4zpkS3oQ8pZjcvMLIP20tKXV9+U08YQeLgQSiLhZTjjK7TZT/+SOXff+FLwsEH0eE/d9daHr+fZzBrdbth4QyybTk5bD7jTDaecCLV2dmUrljhGvuXfs45JA6uaU0GsJcEHswWfPwJeW+9jcNsEa/4/Xdsu4ybFbqsjJKlS12Jfqzp6Szbvh1rSgrtb7qJ/b5fTu8PP3AF4mWrVrJnyiPgcEBMDF2nTyPxwAMBKP35Z7KfeNIVyFrbtiW2a1es7dvR4a67PO70p5jTIumqKlcACr6vz/K1ayle+BWV69dT+MknVO/e7ZE129lqnew27UrKCSNod8vNqNhYko85mjaXG6kqvFsbMi+u6eLc+eHJtab9Sjp0CBbzpoM7297avRjqU/TlglrJqoq/NmYrrHSbnkxXVHi8HoEoW7mS3Jc9W2Ayr7gca0rdN8qWmUMwUoa7fQ2LjSXj3/8m/Zxzam4a2mzse/ZZ1yrOG4+u4QYOB/uefZbNZ53F5pEjqdzSqAka6lRsXhPWdu2IMccyly5fbgSysbF0mvgQ7W+/DTDqOPn441zbJgw6gLbXXkPamWfS6eHJZF5qvBfsOTlUrGvq16XI0Zi/1/6q/Otvyn75pcU8mhJYO8cHOx1//PHk5uZSZN6E/uSTT3A4HIwePZqcnBzXo1OnTvTv35/vvHqbBGLMmDGuQBZg5cqVZGdnc+ONN7oCWYAzzzyTgQMHMn9+7fawcePGUeJ2M/j44493dQOuz6xZs1izZo0raA+nFtkya445neXnusrr91rbmt1nHzIfACilMoC2GHO5OtdbjBHgum87wu3XY+opx1Yf207Cay5brXUvH9u+Crxa174xkj5BELoYm9PpvA8cDZyjtf6xjvU6A+nAJmfrs1KqvdZ6n9d6Z2BkWH629l6E8JSZmRnwNu5dh2M7diDh4IOo+P0Pir/9lg533uG1rtkym5JC0mGHYc3IwF5QQPHXX5Nx3rl+Ha9Wy2x+QcBlDjbvltnqFjA9j3sX38SDDqR44UJjuTk9T4oz+VMdrbIAMe2MYNZRXIwte69ruTWzDZaEBHrOnMmO68dRtnIlxV9/XasFyjOY9b/lS1dXk3Xbba4gKvOKy2lz+WUUffWVa2wyVqtHV8O4nj2J692bqi1bKFm8hOSjjq55rnfNuJ/k44+n8NNPcZSVkf/e+659xXbrSvU2I9tjx7vvJmHAAFRSUs0UPDExxPfq5VFOj5ZZc719zzzj6pZc8OGHrqlEVEIC7cff7lrfkmYEs4G2zJZ8/z27778fgPz336PL1KkUfbnAY53CTz9zJQFKPPwwMtu08Sx3TAxJhxxM6Q8/UvzFl66ytxlzBfH9+5N01JGU//orlX//7cpQnDzseLo9+ywWr+6rTslHH+UaC5z/4Ydom43ko47CUVQ7mLUXFBjjM03Ve/a4WlyJjSXxkEMAI0DOfuopsNlIO/10ko84ggGrVxmt3nWMF0saOpQer88Ei9XVFd7j3GNjSRk2jCKvKYWqd9U/1tRb2WpjBJNKTCT9nLMpeO99ylavxpabS8U/nnNtF3/zLaknnRTQ/u0lJeyacA9ojYqPp9vzzxHXuzdx9VyvUPMZnnx8TTAb368flrg4ujxmdNffPGoUlX/+5brZFdu9u+vGVdLQoVjbtMGel0fBu++59lH48cdkXnIJ2dOfIOWkE0k/88yAzsfj3IqKKPvB+GqTeuKJWJKSXBmoY9q3p+szz9SaCzjluOMpNKcCi99/f2IyM+n6hJHgzH1KrpKlS0g8cHCjyxZJGvP32l/x+/vqdBk+TSlPDzOZnJPzdcvPzyctLY0NGzagtaa/V88bp1g/5tKui3cWYmdCpwEDaneWHDhwoCshl1NCQgLt27cn3y3TfmZmpsfvvhQVFXHvvfdy9913e4z5DZcWGcwGm1IqUWvtPeDodvPn4uYtTaNcC2zGSADVVE8AZ2O0zLZRSl3m/qTW2hkwPwqMAXoDW81lPyilfgVWYoyzPRS4CqOb8VSEaIB78gF/OdxaWwFSTzyJit//oGrTJiq3bCHe7cPcGdBYUpJRMTGknHQihR9/Quny5dhLSuttcQBwVFW5xlI5Scusb+5zzCbsvz9YrWC3u8qWZAbgsfXUubVNzfyp7tMtxbQxvgxYkpNJO3ukq1XNXlBQdzBb2nAwW/TVVxQvWkT1rl2uLKwpJ51ExwlGq2/KsceiYmPR1dXE9+1bK7BKGTGCvC1bKP/1V4/xeHF9at6DKccf59qHs2UtrkcP2lxxOXsmP0z6+aNc0xIlHnQQZT/9BEB87961xnBavILZij//9Jh7t+DDj1zT4aSddSaxHTu6nrOmmMFsSQnabq8zOPOW9/os1/+rNm5i26WXoby6sLpngU0ZNszndZ04dCilP/xY0207Npa2Y8cCkHzkUeS+aIy9dV5vmRddXGcgC2BJTCT5mGMo+e47SpcspXTJUpKPP97Vygu4bg7YCwrRtpoRQLY9e6j402hRS9h/f9d7KL5Pb3q88jL20lJSzFZa5ccXy+Sjj673+dSTTqwdzDaQOMmbs6UoYcAA0s86i4L33geHg+Jvv6Xyb89gtmTx4oDqGKDw009d47k73HUXKccf79d2zrqO69aVhEGDqFi3jqRDD/VYJ/2MM8j+s6ZXgvtwEGW1knrSibXmPy78bB7l69ZR9uNPFH/9NcnHHENMI4OpwjlzXPMFp556CnE9e1GydClx3bvT+ZEpPhNxpQwfRsIBB2AvKKh1YyC2SxdXV+PS73+gfQi737Ykjfl77a/GdultiepKlOTMreBwOFBK8eWXX/pcN8Wt51Jd407tdrvPbRMbObzAybnPuHryB/gyffp0qqqquPDCC13di50Zl/Pz89m6dStdunQJeL+N1dK7GQfLhUqpxUqp/yilblRKzQYmAl9prb8Pd+HqopS6SCk1FTgTeEYHJ/X0IebPkfjuwl2f94H+wH3Ac8BpwP9hZJ3eW9+GwVS9Zw/VewLrsiVahoVm610g7MVewezJNV80ij6v6TKjq6tdiXWc83Sm/utfxnNVVZQsWdzgsby7GEP4E0Bph6NWq6Oz9TOcqvfUXPKxXbrUdBnOycFeUoIyW4/jvFob3TlbZqEm6RJWq2u8J+Ax1tm7Ltxfh4bGzNr27SPrjjsp+myeK5BNGDyYrtMedwUBluRk0s44HYAUczoed8nHmJ1zHA4KPjGnc7FYXMlvwOh2m/ovz3x48f36knHRRez38090fuQR13L31iHv8bLO8jg5SkvZ+7/HPMYB2vbscY2pzBjlmeTe2TIL/rdaV/zzj9EVE4g/YH+IiUFXV7t6Brh3ywUjQ2zGqFE+r+ukoUM9fk8/43RXEJE45BCPwN2ank7KcZ779iXjgvM9fi//4w/XzSZLWhoxZguxPT/f471SvWcv1VlG61pcr54e+0g+5hjSzM+JYEk+7ria97D55TSQv1nabqfiH2NcbPz+A0kcMgSreW7578zGbraaxPfvBxhjsd1vrvjDOZ+qJSWFzEsv8Xs797ru+szTdJo0kfa33eqxTuppp3v87p3bwCOzeYzRpmLLzqbsR+PGjq6upqiRia20w0HebCNrcVyvXiQffTRx3brS94v5dH/5pTozSlsSE+n18Uf0XfS1633kLumIIwFj3l1HhT+j0yJfY/5ei9r69u2L1prevXtz8skn13ocddRRrnUzMzN9JoRytrg2pKf5t2j9+vW1nlu/fr3reW+FAd603759O/n5+QwaNIjevXvTu3dvjjdviE2dOpXevXvz55/N1yU/WoLZPzAyGv8HeBo4HiM78Pn1bNMSvAvcgjGWNihzK2itR2itVV0Pt/XGmsu2ui17QGs9RGudobWO01r31Frf2KyB7N69bDrlVDadcWbQx9iI0LvzzjsD3sbV2ppqBLPxffsaiXUwulk6uxO6Z/h1jtFMPuYY15dK75YAn8fyFcyGuWXWUVJSK5FJS2iZdR8DGNOxo+tLom3fPspXrUKZZU46bKjP7QHXF3So+XJtzcz0SLBiTc9w/b9WMBvAmNnC+fNdgV9M584kHXkk3V98waP1E6DzlCn0/uxT2t96a619JA45BMyyORMcxXbr5pEACCB9lOeflri+fVFKYU1P97jznjjELZh1y2Ts5F626t17XONU08443WgJd+6/Vy+PfQFYU2tuCNj9TD6U96aZnkEpuj39NN1fmIFynpvFQucpD7vKZElJocu0x1ExMT6v68SDDnIFKgCZl9V0ArLEx5Po1pqXevpp9WYWdq130kn0mf85GRcaUz45CguxmTdNrGlprhsf9oICj+EB1Tt2uMY319dTIFisKSn0fPMNuj71JO1vv91VVruf47qrtm93dT9PGLg/ymol7XQjQHQmJQJoe911rmC5+JtvAypj9XZzWqEe3QNKaORe13HdupF50UW1xg3Hdevq6soNePwfIOnoo4nfbz9UUhLdnn7KZ93n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cl+B60No+otXpnMU54klM3EjxVcEM0QkG7gM+FBV13h5vUXkoBaWzUhRgnFml23cAEDrY45x+cXFlC9enCixWoRKr88ZnTtDRgYAO956O5EixRVVpcozZv3tO5B/5pmA8+Rc9tHHiRTNiBNBBx5G6mO6Th9M18lFeXk51U0cHAg6amoKmzZt4s4772TMmDFNbqO5xMWYFZGeOMNzeROqPwLcCswACnHrbk/COXhqjrz1DQnUlx+N3+iG6gblfRbXh0ipRefeqeqHOIda94jIn0TkCuBtnPEf6nb1GdyHhhpEpK2IjBORcbgp4gDXeHnXxF96I1kJhuY55Eg3ASDv2D2z+EvnzUuESC1GlTfNOKtPH9r87HgASl57rWYqbqpRvbMMragAIKNDe9qccnKNEV8y+7VEimbEiVdffTXRIhgthOk6fTBd753x48cjIixfvpzhw4fTrl072rZty2VexIJwnn32WQ477DByc3Np3749F154YZ3pvX379mX48OF16h5//PEcf/zxNfvz5s1DRHj++ecZN24cPXr0oFWrVpSUuKibL774Ys25OnbsyMUXX8y6sLCAw4cPJy8vj3Xr1nHjjTeSl5dHp06dGD16NIFGzKK6+eabOfDAA7n44oujrhNr4jUye4m3fdPbrvK2B0YoexCwRVV3evvnAU+r6g2qOlNV/wUswI1wRmJA6I6I5OHWf65smugxZTNudNqvqnPrSZsaaiQOXIqLB3wJ8DCQCZypqvMbqFcATPDSqV7eDd7+6LhIaqQEwTWzny9z37cyu3Yl+5CDASh+7nkCpTvrrZvsBKcZZ3TtSsEl7taou3ez7YUXEilW3AgU7XH+5O/QkYyCAvKOPhqAkjf/SfXu3YkSzYgTtrYufTBdpw+m6+goLCxkx44d3HPPPRQWFjJt2jTuuOOOWmXuvvtuLr30UgYMGMD//u//MmrUKN566y2OPfZYtnkz15rChAkTmD17NqNHj2bixIlkZWUxbdo0CgsL8fv93HPPPfzud7/j5Zdf5uijj65zrkAgwCmnnEJOTg73338/xx13HA888ABPPvlkVOdfuHAhTz/9NA899FBC4wnH3JgVkaHAH4HvgL8BqOp63FrMYSLSLqTsobiR19dDmghQd1T0WtzU2EhcISKZIfsjgQzgjSZ3IkaoagB4Cfil19daiEinlpcKVLVcVW9U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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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1gnkx1jjeb1vrwFs2rSJDRs2sGTJEoqKipg7dy5gZdMDa+xGZmYmy5cvZ/Xq1aSnp7N48WIqKyuZM2eOz7oLFy4kIyODVatWsWrVKjIyMjyZ4tzrzJkzh8rKShYvXkx6ejqrV69m+fLlZGZmek5297pz586lqKiIJUuWsGHDBtatW8fSpUvJycnxZLFzrzt//nxycnJYunQp69at02PyO6YhQ4b0umPqqnqqq3Ewf97P2LvlKI898C9WL/uQ55a+w9JFz7L+pQzum/9ntq47ws++uZj0Nw7zm/l/491ndrD0/hf472Pv8vxfP+TPv/ovHz67i19/9898+moWd33r93z6ahaLf/oP3vzPFv7x4Cus/MObvPLER/zp7pV89OI+7pn7J591f3/nMl7/56cse+h1lj30Oq//81N+f+cyn3XumfsnPnpxH3+6eyU71lvTcjuljpy8o72+nvSY4Omnn+51x9Qb66kzjqlv374+x3TxzWMwOAB4/f+2s/L/Xgq5Y+qN9dQZx1RSUtLhY3InHDp69Ci1tbXk5+dTWlpKWVkZubm51NfXc/jwYQAOHjwIWOM3q6urKSgooLi4mIqKCk6cOIHD4SArK8tn3ePHj1NZWUlhYSGFhYVUVlZy/Phxn3WysrJwOBycOHGCiooKiouLKSgooLq62tPi6V738OHD1NfXk5ubS1lZGaWlpeTn51NbW+tJruRe190d+NSpUz7H5HBY54P3ut/61rd49tlncTgcPPjgg9x999288sorXHXVVZx77rmeda+55hruv/9+9u/fz5133slHH33ESy+95Om2695eTk4OAEVFRY2O6corr+T555+nrKyMe+65hyeffJIbb7yRV155Bbvd7jkmp9PpaSnOy8vz1JO7/M3VU0pKCpdffjnvvPMO9957L7/85S85fPgwv/rVr1i9enWjOvWvp/r6ejIyMpp877kfay3xb/JWSkQGYiWligQuNMaccC2fBmwGvmOMedrvOX8EfgHEtKNl9rVdu3YxceLEzj0Q1eMsXrzYM5+Z8uVwODm8o4Bjewo5cbCE0lNVIT2TdF3Uae78603BLobqBnpeh49AdX1gcy7v/WcvxmkQmzB2an/OnjWUgWOSm0xoo3q+zjivDx2yLm62ZrynCp4TJ04wePDgbttfS++L3bt3M2nSJIBJxpjdLW1PuxkrHyKSDLyF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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" + }, + { + "data": { + "image/png": "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dZoxpqKx11WLt7EmJbrOTtS/wuoKfJn9WJaffX6J1YI8Q0Rutfc5gNUieQLWskRnYC2/0tmuYzbW87gd67m8BKu765PGmKIA61qTO7Faiv8oIoOxurFm2HVvAfzRGLOlkecIxCysuPlL3sFKIE8ExmFN9PUx1tjs9lhjaX8O/A17sjB7gqV/YSXJq0VkHtZnkHOxWoF3NqCOkXyu5mCtI/sLYJ19PbuxJr26BGvW6zsbO8O1Ukqp2mkyq5RSMcIY86yIlGElGaOxZoxdBozFWj7mqKTPGLNARE7FmrToHOA8rC6f67FmXfUu+5GInABMwOo6OwyrpXEnVsL3Zj3rWywib2C1zIL/LsYNuq4ajlMqIudgdZM9FxgMrMFKWPPxk8waY3aIyClYS81cyZEZl3djJWLTAPcyQluxWipHYHVjzbCPuwErsaq2vE9DGGPyReQMYCLWsi9/xno+VgBTjTEfNPYcAdbDJSJ/BRbV8HiFiFyONVZ4DFYClwbsBbZgJa3/89ntXqyuwb/Hmi15N9ZzNpk6ZsiuoQ4Re67s5+ci4BasSc6uwJpdOR94D+uLjbDESimlnExqnmdEKaWUUkoppZSKTjpmVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFkVimllFJKKaVUzNFk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0YItW7Ywb948brzxRiZMmADA7373O+bMmcMFF1xAVlYWmzZt4uWXX6Znz54BnSspKYlHHnmEsWPHMnz4cK677jrP0jyZmZk1rh3s73Nhbdq1a8cNN9zA888/zznnnMOoUaMoKiriqaeeoqSkhIkTJ9breI3liJZZY8w3xphfGGMyjDHJxpiuxpjbjDFRPb2hMUaMMS2MMb8zxoS3zV5FBd9ktlmzZp5Whvp8iKgrmU1ISPB0Fdu8eTNFRUUNrXKt3n///ZAcV0UfjXV13q+pnJycCNYk+KIt1t7zA4gI/fr18zymrbMN490ym5KS4unyuG/fPgoLCyNVLRVC0fa6jmV33nknb775JgkJCdx3331MmDCBd955h/POO49LL73UU+7888/nscce48cff+S2227jiy++4N1336VLly4Bn2vMmDG89tprlJeXc8cdd/Dss89yxRVXsHz58hrXs23Ia/jpp59m2rRpFBQUMHHiRB566CF69+7Nhx9+yJlnnlnv4zWGaM9VFUkiMgBYs2bNGgYMGBDp6kSdL7/8kkWLFgFw++23k5qaykcffcSyZcsAuOGGG46aSc+fXbt28eyzzwJwzTXXVPtw57Z9+3bPWmlnnXVWSCaCKi4ujrvJb5R/GusjSktL+fvf/+75vUWLFvz5z3+Om5l1oy3W77zzDt988w1paWlMmDABYwz//ve/2b9/P+3ateOmm27ydJNVgVmxYgXvvfceABMmTODAgQM8/7w1b+Vll10W9m6FKvSC8bp2f+keyHhPFTk1TTAVKnX9Xaxdu9bde2mgMWZtXcfTd3OlophvyyzAkCFDPG86vtOs16SullmALl26eGb0W7lypd+B/Y01ZsyYoB9TRSeN9RG+PR2KiorIy8uroXTsibZY+87cLiKeZGvv3r1s2LAhYnWLVb4ts506dfJMGPPdd98dNRZQxb5oe12r0Nm6dWukq9AomsxGARHJEpF8EUmru3S1/b4UkX+Eql4q8tzJbJMmTTwJbIsWLTjppJMAa7Im96xytQkkmRURz1jZoqKikHzge/3114N+TBWdNNZH+Ou2v3HjxgjUJDSiLdb+liE79dRTPcnXsmXLNPmqJ3cym5ycTGJiIgkJCZx44omA9UE4nv6elSXaXtcqdAIdkxutYjqZFZGfichke83YmCQiicB9wLQGjOF9BLhFRKJrwS4V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DMDdgY+8yswGzgFygb8C/8Iak/ot8N8ALmMmcLqIVFuJPJBz262lVwIv1jDLsT8pWImxr1Kvx2vajwbu63Yz1vha79vbYH3oSE9PJyEhgU6dOlFSUkL37t0pKiqie/fuVFZW0r59e5o2bUrz5s09Czx36dKFw4cPVyvrcrnIyMggJSWFlJQUMjIycLlc1cocPnyYLl26ANYyDc2bN6dp06a0b9+eysrKamVLSkro1KkTCQkJpKen06JFC5KSkujQoQPl5eXVypaXl9OhQweSkpJo0aJFUK7ptNNO4/nnnyc7O5vZs2cze/ZssrOzmTTJ6tU9cuRIALKysiguLmbKlCmsWLGCefPmMXPmTHJychg/fny1sqNHjyY/P5+pU6eyZMkSFi1axPTp08nNzWXcuHHVyo4bN47c3FymT5/OokWLWLJkCVOnTiU/P5/Ro0eTmprKhAkTOOecc/jyyy85//zz6dSpE/3792fo0KEkJCRw8cUXs2vXLs466yxyc3MZOnSo58PLpk2b6nVNzz//PAsXLuSuu+7iH//4By+++CKLFy9m7dq17N+/v84PPYmJibhcLpo2beppRWnWrBkiQuvWrT0xPHz4MJ06daKyspK2bduSnJxMamoq6enWPHEdO3akuLiYLl26cOjQIbp06YLL5aJt27Y0a9aMZs2a0bZtW1wuF926daOoqIhu3brF1N9eY15PSUlJcXdNDY1TZmYmGzduJCEhoc7Xk/ff//jx49mzZw9fffUVhw8fpmfPnhw4cIDx48fz448/cuONN7Jx40auuOIKKisrOf7442nbti2tW7emZ8+eVFVVcdJJJ7F//36OP/54CgsLPTOcu7vLNmvWjI4dO1JRUcGxxx7LwYMHOfbYYykpKaFr164kJCTQunVrWrZsSVJSEp06daKsrIwePXpw8OBBevToQWlpKZ06dSIpKYmWLVvSqlUrEhIS6NKlCyUlJWRmZnLw4EEyMzOprKzkmGOOOSpOXbt2DWqc+vfvz6OPPtqo971du3bx5ptvsmfPHtLS0igoKOD3v/89W7du5f/+7//YsGED11xzDcXFxQwePJj09HTat29PZmYmIsKJJ55IQUEBJ554Ivv372fAgAG4XC46duxIamoqqampHHPMMbhcLnr16kVhYSE9e/bk0KFDZGZmApCRkUFaWhrNmjWjQ4cOVFZWVnvu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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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HRpr79BYe0d7jHUGMABYGEllTWaV2yqd27WRDPJWiSvoEtONGuvkprH2Do21d2isvUNj7R3tONbLIq2o68wqpZRSSimllEo4mswqpZRSSimllEo4mswqpZRSSimllEo4mswqt+0D7iXsIiYqyWisvUNj7R0aa+/QWHuHxto7Ej7WujSPUkoppZRSSqmEoz2zSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSjiazSimllFJKKaUSTprbDVDeJiKdgTOBbYDP5eYopZRSSiml3JMBDAAWGmPKWqusyaxy25nA6243QimllFJKKdVuXAS80VolTWaV27YBvPbaawwbNszttqgY8vsr2br1FXr1GkPHjl9zuzkqxsrKyujcubPbzVBxoLH2Do21d2isvaO9xbqwsJAf/ehH4OQIrdFkVrnNBzBs2DCOO+44t9uiYmjzVzPILfkXdXWf8LWvfYKIuN0kFUPTpk3j1ltvdbsZKg401t6hsfYOjbV3tONYRzT8UCeAUkrFRXW1/YKt1rcHn6/I5daoWBszZozbTVBxorH2Do21d2isvSPRY63JrFIqLur8+xt/rqra5F5DVFxUV1e73QQVJxpr79BYe4fG2jsSPdaazCql4sJfd3BCugNVG11siYqHjRs1xl6hsfYOjbV3aKy9I9FjrcmsUiou6vwHk9mqqs0utkTFw9nn5LJ8+QSqq7e63RQVY85EHcoDNNbeobH2jkSPtU4ApZSKi+CeWb3MOPlt3vx/ZGX5ycjsxYhj7nO7OSqGpk6dyhNPPOF2M1QcaKy9I1qxrquro7S0lMrKSowxUWiZirYlS5YwevTomD6HiJCZmUmnTp3Izc2N6iSgmswqpeLCHzxm9oAms8msoaGWrCw/ABUVq1xujYo1TW68Q2PtHdGItTGG7du3U11dTWpqKmlpmna0R7FOZAHq6+spKyujrKyMbt260atXr6gltPpX5UEikgncB1wBdAWWA3caY95rZb9jgAnAKcCJQCYwxBjzVUwbrBJefX0NDQ01jfera7bT0FBLSkqmi61SseLzlTT+XFm5FmPqEUl1sUUqli688ELmzp3rdjNUHGisvSMasa6oqKC6uprOnTvTt29fXZKvndqwYQPDhw+P+fP4fD527dpFSUkJubm5dOjQISrH1TGz3vQ0cDPwT+AmoB54S0ROb2W/U4EbgY7Amlg2UCWXuqBLjK0Gqqq2uNIWNxQVfcCyZeMoK/+P202JC5+/uPHnhoYaT8XaizS58Q6NtXdEI9bl5eUAUe2FU9EXj0QWICMjg759+wIH/zaiQZPZCIjIFBFJigv9RWQMcBlwhzHmVmPMk8A5wBbg963s/gbQxRjzdWwirFRE/P7QZNZbk0Bt3PQwJaWL2LRputtNiQu/r7jJ/crK1S61RMXDhAkT3G6CihONtXdEI9Z+v5+0tDS9vLid27Ilfl84Z2RkkJ6eTm1tbdSOeVjJrIiMFxETtNWIyE4ReUdEbhSRjlFroYq2S7A9sU8GCowxNcBM4FQRGdDSjsaYEmNMReybqJKNv1nPLFR5aHme6urtAJSVLaWhoc7l1sSeLySZrajUCzmS2V133eV2E1ScaKy9IxqxNsaQkqL9Zu1doLc0XkQkqpOBHelf2N3YcZfXAo85ZX8CVojI8Ud47Pbkd0C2242IklHAemNMaP9+gXN7QqyeWER6ichxwRswNFbPp9qPuqDJnwIOeGRG47q6A9TXVwJQX3+AAwfWudyi2PP5S5rcr6zQntlk9tprr7ndBBUnGmvviFas9fLi9m///v1xfb5o/00caTL7tjHmOWPMU8aYB40x5wHnAr2AN0QkKRJAY0yd03uZDPoCu8KUB8r6xfC5rwNWhmyvAyxatIiFCxcybdo0SkpKGDduHGAnIACYOHEihYWFzJo1izlz5lBQUMDUqVOpqqpi7NixTepOnjyZFStWMHv2bGbPns2KFSuYPHlykzpjx46lqqqKqVOnUlBQwJw5c5g1axaFhYVMnDixSd1x48ZRUlLCtGnTWLhwIfPnz2fGjBns2LGj8TKcQN0JEyawY8cOZsyYwfz58/WcnHM6cGBv4x9BeXk6AOvXf5jQ5xRpnB78v9ubvAj++MdfJ/w5tRanVas+bXLOFZVrE/6ckjFO0Tqnt956K+nOKRnjFI1zysvLS7pzSsY4ReOc6urqjvicFi1aBNjLWH0+H3v37qWsrIyKigp2795NXV0dmzfbIUcbNmwAYNu2bdTU1FBUVERpaSkHDhxg586d1NfXs3HjxiZ1t2/fTlVVFcXFxRQXF1NVVcX27dub1Nm4cSP19fXs3LmTAwcOUFpaSlFRETU1NWzbtq1J3c2bN1NXV8fu3bupqKigrKyMvXv34vP5Gi/FDdRNpnMqLi6O6znV1dWxYsWKFv/2Ao9FSg6nm1dExgNPAScbYxaHefwO4AHgGmPM34LKzwHuxc6E6wcWArcbY9YE1RkETAK+AwwEqoAPgFuDZ80NasOZwOXYy2fTgdeAm4wxpUF1v8ImTn9wtuOAQuAGY8wCEbnYaddwYBVwtTFmWdD+U4B7jDESVGaAGUA+tud2uHPM3xhj5of8PvKAqcD5QBen3sPGmFlhfr0xJSIbgXXGmB+ElB8FbAQmGmP+FMFxbgGm0YbZjEWkF9AzpHgo8PrKlSs57rjjIjmMSkBbtv6dwsIHAcjLu5wdO/4JCN8+vYCMjG7uNi7GSks/Y+myyxvv9+51ASNHPuJii2Jv9erb2LX71SZlp5/+OZkZPVxqkYqlhQsXcuaZZ7rdDBUHGmvviEasN22yV2AdddRR0WiSipGKigo6dozfCNHW/i5WrVrFyJEjAUYaY1pd3y9WF7L/w7n9XqBARM4F3sH22k4B/gicBnwiIoOD9j3ZKX8BO3PuE9jEdoGI5IR5rseBY51jPotNbF+T5n3Yw4DZwFzgDuySNHNF5HJgOvAccA82uXpJRCL53ZwO/Nlp621AFvCqiHQPOu/ewGfYHuvHsbMHFwIzReR/I3iOaKvGLqkTKivo8Zgwxuw1xqwK3rAJtEpydc4EUMYIvXr9l1NqKClZ5F6j4qS2dk+T+/vLlrjUkvgJns04oLJCx80mq4KCgtYrqaSgsfYOjbV3HDhwwO0mHJGYTC9mjNkuImU0HQ85DSgBTjXGlACIyGvAMmyv6Din3jxjzCvBxxORucCnwE84mCgH+IDvGGP8Tt3ArLwXYmffDTgGOM0Y86lTbzU2uf4bMMIYs9UpLwX+CpwBLGjlVI8FvmaM2ejs+yHwH+Bn2MQV4H4gFfi6MSbwCe8JEXkemCIifzXGxCyBDGMXkBemPDD6e2cc26I8IjABVHpaZ7p0Hk1qai719QcoKfmYPn1+6HLrYqu2dnfI/V3U1OwkKyuWV/S7KzABVMeOI6moWAlAaemndO/+bTebpWLkqquucrsJKk401t6hsfaOHj0O76qpxx9/nBkzZrBp0yZ69OjBpZdeytSpU8nNzY1yCw8tllOMVWLXI0VE+mInFno6kMgCGGOWA+8BPwgqa0zsRCTd6eUsBPZjL08O9WQgkXX8BagLPqZjdSCRdXzu3H4QSGRDyiO5JiI/kMgGnU95YF+nd/gn2N5gEZEegQ2bSHdu4Zxi6UvgaBHpFFJ+StDjSkWV35kAqriklpSUDLp2/aZzf1FUZ7Rrj2pr9zYrS/beWb8zAVRu7jA6dxoFwJ6985I+1l4VGEunkp/G2js01t4RGGfbFpMmTeKGG25g5MiRPPLII/zkJz/hscce4+KLL45BCw8tlslsByCwjMsg5zbcNJ5rgB4ikgsgItkicp+IbANqgSJgH3asaecw+28IvmOMqcT2Pg4Oqbc1pF5grZDQCAbKu4Z5rlBbw5SVBu3bE9vua7DnELw95dTpFcHzRNMr2J7iawIFIpIJXAl8bozZ5pQNFJERcW6bSlKBy4wHDDgGgG7dbA+dz7eXyiSf3TdwmXFWVh4pKfYK/3373nWzSTFljGnsmc1I706v3ucDUFOznfKK5W42TcXIM88843YTVJxorL1DY51YampqaGhoOKx9hwwZ0qb6u3bt4o9//CNXXHEFL7/8MhMmTODRRx9l+vTpvPvuu8ydO/ew2nG4YpLMikh/bOJZeBi7Pwb8FngJGIsdd/tdoJgja299G8sjmTe6tX0D7X0Oew7htk8ieJ6oMcZ8DrwMPCgivxeRa7ATbA3GjvsNeBb7RUMjEeksIneKyJ3YccwA1ztl18e+9SpR+ev2A/Cf/9i3hO7dDl5uWlK80I0mxU2tL5DM9qdXTzteeN++d8P22CaD+voqGhrs5O/pGd3p3esHBN4S9+6Z52LLVKwEZqNUyU9j7R0a60ObMmUKIkJhYSHjx4+nS5cudO7cmSuvvJKqqqpm9Z977jlGjx5NdnY23bp147LLLmvWIzp48GDGjx/fbN+zzjqLs846q/H+ggULEBFeeOEF7rzzTvLy8sjJyaG83K66+fLLLzc+V48ePfjFL37Bjh07mhxz/PjxdOjQgR07dnDuuefSoUMHevbsyS233EJ9fUvpjfXpp59SV1fHZZdd1qQ8cP+FF1445P7RFpMxs9i1Z8FeSguwxbk9JkzdEUCRMSYw+vgS4BljzG8CFUQkC9vDGc5w4MOguh2w4z/fOqyWR9c+bO90qjEm3+3GBPkldnblK7C9yMuBC4wxH7WyX1dnv2CBOG3h4DhhpZqo89s32FO/ab8DyckZTHb2IKqrt7B9x/MMGHAlKSkZbjYxZhp7ZjP70L//L9i95zWMqWPHzhc5asgNLrcu+vxBkz9lpHcnM7M3XbqczP79BezZ+xbDht1OZPPrqUQR72/hlXs01t6hsY7M2LFjGTJkCA8++CBLly7l73//O7169eKhhx5qrHP//fdz1113MXbsWK6++mr27dvHY489xhlnnMGyZcvo0qXLYT331KlTycjI4JZbbqG2tpaMjAyefvpprrzySk4++WQefPBB9uzZwyOPPMInn3zS7Lnq6+s577zzOOWUU7jkkkvIz8/n4YcfZujQoVx77bUtPm9tbS0A2dlNV2DNybHz9C5ZEt+hVFFPZp3ld+4CNgP/BDDG7BKRL4FxIvKgMWa/U3cktuf1uaBD1NO8V/QG7KWx4VwjIk8FjZu9Fntebx/52RwZY0y9iLwK/FxERhpjVgY/LiI9jTH7XGhXDXCrs7VU56wwZV8RWY+1Uk0EemY//XQ5gRWYBg64inXr76amZhs7d75M//6Xt3yABGVMQ2MPbEZmLzp1OoGOHY6jonIVO3c8z+BBE0hJSXe5ldHl8zVOi0BGhp3YvVevH7B/fwG1tbsoKnqfnj2/61bzVAxMnDiR6dOnu90MFQcaa++IZazXr59KRWX7meG+Y4djOfrouw5r31GjRjFz5szG+8XFxcycObMxmd2yZQv33HMPv/vd7xrX9QW4+OKLGTVqFH/+85+blLdFTU0Nixcvbkwq/X4/kyZNYuTIkXz00UdkZdmFSk4//XQuuOACpk+fzr333ttk/0svvZTx48czYMAAJkyYwIknnsjMmTMPmcwec4ztm/zkk084++yzG8s//vhjgGa9wLF2pMnsfznjKtOA3sA52EtntwA/dJKmgFuxCeanIjITyMYmqWXYZXUC3gSucGZDXg2cil3WpvlaD1YG8L6IvITt+b0OWETTmYzddDtwNvC5iPwNe07dsBM/nev8rFTSMqaeujrbM3vCCd9qLO/X76ds2fokNTXb2fzV4/TtezGpqdktHSYh+f2lBL5ny8zsjYjQv/8vWLP2Dmp9e9i+4zkGDrjS5VZGV/CyPIFktk/vC9i06WHq6ipYt34KXbt+k7S0+K1pp2Lr17/+tdtNUHGisfaOWMa6onIN+/d/3nrFBDBhwoQm97/97W8zZ84cysvL6dSpE//6179oaGhg7NixFBUVNdbr06cPw4cP58MPPzzsZHbcuHFNekcXL17M3r17mTJlSmMiC3D++eczYsQI5s2b1ySZDbQ/eI3Zb3/72/zjH6ELxzR14okncsopp/DQQw+Rl5fH2WefzZo1a7j22mtJT0+nujqei7QceTJ7n3Prwy67swL4X+ApY0xFcEVjTL6IfB+7DM99gB9YCEwyxmwOqnoTtnf2cuzap59gk753CO96p+59QDrwPHCjaSfTZhpj9ojIGOBu4GJssl0MrAImudEmZ8Kn+2h6mfGdxpj3Itg3D7su7/ewY4I/BCYaYzbFrsUqkQUSWYDNm/dy0kn255SUDI4achOr19yKz7eX9evvY8SIB2i+RHTiCl5jNjOzDwC9e1/Ips2PUlu7i8LCh+jc6QQ6dx7lVhOjzu87mMymp3dzbrsybNgdrF07mdra3RRu/AMjjrm3pUOoBPPRRx8xbNgwt5uh4kBj7R2xjHXHDsfG5LiH60jaM3DgwCb3u3a1c8CWlpbSqVMnNmzYgDGG4cOHh90/Pf3wr84KnbhpyxY7qjPQcxpsxIgRLFq0qElZVlYWPXv2pKioqDH57dq1K6Wlpa0+96uvvsqll17Kr371KwBSU1O5+eabWbhwIevWxXdiz8NKZo0xTwNPH8Z+7wPvt1JnP/CrMA8NbmGXKmPM/wD/c4hjht3XGNPsU3O4S2mNMVNo2nscdt+WnssYsxebdLeXSZKexo5N/hN2NujxwFsicrYxZlFLOznjkT/ETu71APYLiYnAQhE5IWgdXaUaBZblAcjO7t7ksT59LmLb9meoqFjJzl0vkZbWManGVDZNZu3E5amp2Xx95GMsWfozjPGzYuX1HP/1v9Cp0/FuNTOqfL7gntmDF5706zuW3btfZ//+z9mx4zlSU7MZNvS2pIm1lwU+vKnkp7H2jljG+nAv6W2PUlPDj4IM9Kk1NDQgIrz99tth63bo0KHx55a+zK+vrw+7b+iY1bYKHLOlcziUvLw8Fi1axIYNG9i9ezfDhw+nT58+9OvXj6OPPvqI2tVWsZoASrVTTi/xZcCtxpg/OGXPAiuB3wOnHWL367ATbo0xxnzh7Pu2s+9vgMO7TkIlNX9Qz2y3bv2bPCaSyjeO/ztLlo6lunorW7fNZP/+Lxg69Ba6dv0mIm1/g21PmiSzGX0af+7ceRTDh93B+g33UVu7m8VLfsrAAVeRl3c52dl5bjQ1ag5eZpxJampOY7mIcOyIB1i8ZCx+fzFbt/6NivIVDB5yPV27fDOpeuS9Ji8vsf9mVeQ01t6hsY6OoUOHYoxhyJAhrSZ5Xbt2Zf/+/c3Kt2zZwlFHHdXqcw0aZFdCXbduHeecc06Tx9atW9f4eKiMjMOfgHP48OGNvc6rV69m165dYWdkjiVNZr3nEuxl3E8GCowxNc445gdEZEBgrdkW9v0ikMg6+64VkfexyygddjLr95c1mThGJY+a6u2NP39esIrTQr4uyczsyagT/sHSZZc3rkW67Mtfkp7ejS5dxtAh92gyM3uRlt6F9PQupKV1RCQNkVSEVHsbtNHGnr62p1CR71FdvaXx58zMnk0e69//lzQYHxs3/gFj6tiy9a9s2fokHTt8jU6djicrK4+MjB5kZPQgPb0LkpJOiqQjkk5KShoi6WF6NUPbFnQ/JFlsfhZyyEcjVVuzG4CamuaXTuXkDObkk17ly//8iqqqTZTu/4zSZZ+RkdGDLl3GkJszlKysPNLSOpGW1oG0tI6kpGQ5sU1xvtwI+llSXJiRzo2ku30n+u+//zonnKCXnia79PSuvPPOO4wZMyYqxzPGYEw9xtQD9UE/R2eUWLRGm6WkpEd1jL8x9TQ0+Dk4b2mgPLS9bbsfzdF1KSmZUY/1wfaaoLLEZYxd07WhoY6GhrrG8oaG+iblP/rRD7njjjuYMuUe/vGPZ5t8cWuMoaSkhO7d7VVrRx11FIsWLaKmpqoxwXzzzXls27aNo44a0vg8B5+jvslzn3jiCfTq1YsnnvgL48f/ksxMu7b922/PZ82aNdx1152N9YPbX16+n5yc7CO6UqqhoYHbbruNnJycZuOIY02TWe8ZBaw3xpSHlBc4tycAzZJZsX/hxwOzwhyzAPieiHQMHSsdcoxeQM+Q4qEAS5ZeSnFJci7Nog765RXh3+Cys/tzypi32LLlCbZu+zsNDT78/hL27ZvPvn3z49zK6EtP79Zs6SERYdDA/6Zrl2+ybv09lJf/BzBUVK6ionKVOw2Noh7dwy/Cnp09gJNGv8KmzdPZufNlGhpq8PmK2Lu3Paympg7HmFPg40XxXVdQxV+Xzidz881/j6iu37+f4uKPqKxcw4GqTfh9xfjryvD791NXV4kxdUBDbBscRYMH/5qhR918yDrG1FNWtoyy8i85ULmOWt8+/L4SfP5i6urKaWiocxLY9p/EiaRy+S8i65/w+Uoo3f855WXLqK7eSm3tHurqK6irqyA9bRxdu55KRcXK1g+UYHw+uxjJgQPryco6uDBJbe0up7yQyspqeveGO++8nnvvfYRNm9Zy/vln06FDLlu27ODNNz9g/PifcOON4wH4+c/P5dVXX+V73zuLH//4PDZv3sZLL81jyJAB1NdXUenMAB34orymZntjWcCUKTdw3XV3ccYZp3LJJf/F3r3FPPHEPxk4sB9XX/39xvp1dWVAA5WVa8jNhbq6XNLTu0R8/jfddBM1NTWccMIJ+P1+Zs+eTUFBAc8880yzccSxlrCDlYwxTxtjxBiz2O22JJi+wK4w5YGyfi3s1w3IPMx9A67DXpIcvL3eyj4qSdTWpnLDDfc0LsQ+efJkVqxYwezZs5k9ezZr1mxi5sxivnXaIt57ty89e3yX8vLk+IKjU8eRjec9duxYqqqqmDp1KgUFBbz/fiErll9A3z5/ZmPhULp0Ppna2oR9a26U//56CgsLmThxIkDj+Y8bN46KinreeD0X4SHq635Keflw0tJ6kuBf1CuV1PaXfcGvf30pY8eOBQj7Xv7SSw/z8aKfsmDhSaxaPZEtW5+kqCifsvJlVFVtwu8vwRgfiZTIAmzd+kLjjLOh7+X33383H398G/nvn8ySpZdSWPggu3b/i5KSj6moXEVt7W7q66uc806MNzlj6vnoo98zZ84cZs2aFfa9/De/+TGLl1zFRx+fzMqV17N120z2Fb1HecVyqqo24/MVNfb+ed3NN1/FP/7xR1JShIceeoK77nqYt99ewDnnnMoPfnBWY71zz/0W999/Cxs3buGOO37PF18s58UXHycvr3fEz3X55Rfx1FPT8Pn83HPPn3jqqVe44ILv8M47z9ClS6dD7rtlyxbq622vb1lZGRUVFezevZu6ujo2b7Zz9W7YsAGwlzR/9tln3HLLLfz2t78lOzubF198kZ///Ods3LixSd3t27dTVVVFcXExxcXF1NXVsWLFCqD562nq1KmNj0VKEr2bX7WNiGwE1hljfhBSfhSwETsz8Z/C7DcA2Iqdffr3IY/9CpgJjDLGfHmI526pZ/b19/Lv55hj+ofZSyUHoWvXb9IhN/xsfodSX1+D31/qfKtfSn1dBcY0YExd81saaFtG1Pb3P9PGfVJSMujZ49zGZWoiVV9fhc9XhM9XhN9fhjF1NBg/xvl2v6Gh6Tf8h2xXK5evNd33yP8npKXm0rPn99p8aV59fS0+317q6ioat4aGWnv5IQ1g6p1YB+7H94NSW2MfrWdVyk0HDhSyY8c/ATj5pDlhJ6traKhjQ+Hv2L79OYL/ZkVSyc4eQlZmb9LSO9uhIqkdnKEiac6QgYO3duhAlL7Mi8I4/OKiDyku+QiRVM4+a02zeRzKypayavVvqK7e2qQ8Pb07WVn9yMjoTkZGD9LSOtlhIilpjcNFJCWt+bm20mY51FCSCPaPxK5dr1JRsZKcnCGc+s38Zo8bU09h4UNs3TazSblIOtnZA8nK6ucMFemIz3caOdlDGDiwe1BbpbGt7XsAhbekpnYkNTUzLs+1aZNdAKWlccCrVq1i5MiRACONMa1eqqaXGXtPNbaHNVRW0OMt7cdh7gs0zuq8N7gsMHagb5+LGND/uEPtrpLAhRdeyNy5c9u0T2pqFqmpfcmib4xa1T6lpuaQnT2Q7Oz4Xq4TLYcX60yyswfEqEUqVg4n1ipx7C9b0pjMTp58E48//mGTx41pYM3a29m9ew4AImn07XsJvXudT5cuo0lJic8H5FgpLvkIY+rx+YrIzDzYQ1Za+jnLvvylc8k0dOx4HHn9fkb3HmeTldmnpcO1e1UHNlFRsZKSki3NHmtoqGXFyhspKrJJrkgGffv8iN59fkjnTic2S4YCSUvw7021Pxs2bGD48B5uN+OwaTIbJSIyFngCGGiMqWzjvhOwkycNN8bUxqJ9QXYB4aaoC2QKO1vYrwSoDarXln2VAtAPvB6isfYOjXVyS0/r3PjznXc1Hze6ofCBxkS2Q4djGXncI+TmDo1b+2IpOAmrrd3TeL+2di8rV92IMXWIpDN06C0MHPCrpFhqLN25iigrq4GGBl+T+R42bX60MZHNzR3ON47/m34BmQRaWgM3Ubj+qhOR00Rkioh0cbsth0vsdSf3Ao+1NZF1PA1kcIi1cqPoS+BoEQm9cP6UoMebMXbgwwrgpDAPnwJsOtTkT0oBjWOOVPLTWHuHxjq5pQVNCvPqq882eay8fDnbtj0FQE7OMEad8EzSJLIAmUE9rLW1dqZ2YxpYueomfL4iAEYccx+DBl6dFIksQEb6wfXB/f7Sxp8rK9exdaudAKxjx+M4afTLmsgmie3bt7deqR1rD6+804B7gC4ut+NIXAgcQ9ByN21hjKkBngFultgvtvgKkApcEygQkUzgSuDzwLI8IjJQREaE2fdkETkpaN9jgHOAl2PcbpUEfvazn7ndBBUnGmvv0Fgnt/S0g999jz6x6ceCjZv+CNjxkt84/sk2zw3Q3gX3zNY464YXl3zE/v12AYi+fX9Kv35jXWlbrATH0Oez64bbS8l/6/REp3LsiP+L6nJFyl3dunVrvVI71h6S2YiJSIqIZLVeM+6uBD4xxuw4gmO8BAwCzo5Ok8IzxnyOTTwfFJHfi8g1wAfAYOC2oKrPAmtCdv8zdpKoeSJyq4j8L/AesAd4OJbtVsmhrTPUqcSlsfYOjXVyS0nJIDU1F4C9+75qLC8t/ZySko8ByOt3GTk5g9xoXkxlpPcg8FG51klmt217GoDU1FyOHv5bl1oWO+lhktmSkkWUly8DYMCAK+nY8WsRH08nmm3/qqsPOeVN1EX7b8LVZFZEpgDTnLubRcQ422DncSMij4vI5SKyCjtm8/vOY7eIyL9FpFhEqkVkiYhc0sLz/EJECkSkSkRKReQjEfleSJ3/EpGPReSAiFSIyDwRaXVGIie5/j7QbMq3oPb/SERWikitiKwSke+H1jXGLMGOS72oteeMgl8CfwKuAB4F0oELjDEfHWon5zLis4CPgDuBqcB/gDONMfsOsatSSimlElRg3GxKysEPvZu/eswpy2Lw4OtcaVespaSkkZlhF2Gord3NgQMbGxP4vn0vTsreyYz0g8ms318CwJ49dlx8SkoGQwZfH/GxRISGBl2eRzVljGmcADYa3J4A6l/A0cDPgIlAkVMenBidA4wFHnce/8opvwl4A/gndrzpZcDLInKBMWZeYGcRuQeYAvwbuBvwYcd4ngO869S5AnuZ7zvAJCAHuBZYJCKjjDGB5wxntPP8S1t4/HTgYmyvZgVwI/CqiAw0xhSH1F0KfOsQzxUVzmXNtzpbS3XOaqF8O/DT2LRMJbuvf/3rbjdBxYnG2js01skvLb0z1O6kc2f7sdHv309p6ecA9Os3lszMXm42L6Yys/pQ69tDbe0etm0/OGZ4QP9xLrYqdkIvM66vr2XvvncB6N797DYl8Onp6dTU1FBXV0damtsph2pJdnZ23J7L5/Ph9/vJycmJ2jFd/csyxiwXkaXYZPa1FpLGY4CvG2NWh5QfbYxp/IpQRB7HJoM3A/OcsmHYBHYOcIkJWr05MDZVRDpgeyf/bowJHkf6DLAOO8twY3kYgQEkm1t4/Fjga8aYjc5xP8T2Zv4Mm6AH24TtLVUqKT3//PP6wdcjNNbeobFOfoGe2b177EedkpJPAPuRqmePc91qVlwExs3W1OykvHw5AN27n0lOzhA3mxUzaWmdEEnDmDp8/mKKixdQX2/nNu3d+8I2HatTp05UVFSwd+9e+vbtG9XeOBU9JSUlUU0uW+Lz+di1axdg/zaiJRG+JlkYJpElJJHtip3U6GNskhjwI+yl1PcFJ7LO/oELtr+LnXzqeREJXmSpHvic1sewBr7CKm3h8fxAIus873IRKQfCrRRcCmSLSI4xpqqV51Uq4TzwwANuN0HFicbaOzTWyS8wo3Fe/64AFBcvBCAlJZsuXcItcpA8AslsdfVXjWW9e53vUmtiT0RIT++Gz7cXv6+EPXvfBOwY4R7d2zatS8eOHcnJyaGsrIzKykpSU1M1oW2nAmsCx4IxBmMMfr8fsBNO5ebmRu34iTABVNgeTxG5QEQ+E5Ea7FjTfdhLgzsHVRuK/eqwWTIcJLC40gfOMYK37wGRXjvT0qtza5iyUqDrIY4R09HyItJFRJ4UkX3OGOEPReTECPcdIyJ/dsYo+0VER/ariF14Ydu+1VWJS2PtHRrr5Jee7vTM7t2MMYbiEjvFRreup5KSkulm02IuM6NPs7LOnUe70JL4CVxqXFOzg6KiDwDo2eO7pKa2bQ5WESEvL48ePXqQnp6uiWw7tWjRopgeX0RITU2lc+fODBgwgF69eiXVmNlINJtiS0S+jR0v+xFwHbAL8GNnFf55G48fSOivAHaHebyulf0D4167AuEWaqpvYb9wUewKVAX3Okeb2IXQ5gHfwE6+VYT9HS4QkdHGmA2tHOIHwNXAcuxl0UfHqq0q+cydO9ftJqg40Vh7h8Y6+aWndQGgQ4cUKivX4PPZqU26dz/TxVbFR/DyPAAZGT3Izk6+mZuDBSaB2l+2mIaGWgB69Di8xTbS0tLo2bMnPXv2jFr7VHQddVS4i0UTR3vomT2cnr2fADXAecaYWcaYt40xzWYTxi4jkwIcag7xwCXAe40x+WG2Ba20Za1zG43BE0NovhxOtF2CXdt3vDHmXmPMDOwMxfXAvRHs/xegszHmJOyyPEpFbOzY5FqPT7VMY+0dGuvkl+b0zBrjY++++Y3l3buf4VaT4iY0me3ceXTS9zAGemYDiSxAx46tLvChElSiv4e3h2T2gHPbpQ371GOT4NRAgbOcz49C6r2Gvcz4bqdHkqD6gXeid4ByYLKIpIc+kYi09lXSEuwMydEYNHIidtblWLoEuy7svwIFzrI6LwEXicghrxcyxuyJZc+xSm5PP/20201QcaKx9g6NdfILTAAFsG+f/R47O3sQ2dkD3WpS3GRmNr3MuEuSX2IMkJ7Rrcn9lJRsT8TaqxL9Pbw9JLNLnNv7ReQKEblMRFobFTwPu3zOfBGZICJ3YydrKgyuZIwpBO4Hfgx8LCK/EZHrnZmKH3DqlGPH2n4bWCoivxWRa0TkdyKyDLjnUA1xlrl5Fzii6fxEZDTQDXj9SI4TgVHA0tAJsYAC7O80ZpcNi0gvETkueMOOa1Ye8fDDD7vdBBUnGmvv0Fgnv3RnAiiAAwfsaCSv9NSF65lNdsFrzQJ06DACkdQWaqtEl+jv4a4ns8aYL4C7sGM4nwaeBw7ZG2qM+QC4CugD/Ak7g/Ek7BI8oXXvBn4FZGMT2/uAQcD7QXVmA98BdmDXXn0Eu27tl8BTEZzGLOCbIjIggrot+Sl2sqgPjuAYkeiLHWMcKlDWL4bPfR2wMmR7Hezg84ULFzJt2jRKSkoYN86u3xaYWGTixIkUFhYya9Ys5syZQ0FBAVOnTqWqqqrx8ohA3cmTJ7NixQpmz57N7NmzWbFiBZMnT25SZ+zYsVRVVTF16lQKCgqYM2cOs2bNorCwkIkTJzapO27cOEpKSpg2bRoLFy5k/vz5zJgxgx07djBhwoQmdSdMmMCOHTuYMWMG8+fP13MKOafzzjsv6c4pGeMUjXOqra1NunNKxjhF45yWLVuWdOeUjHE6knMqLAz+2GBHh819oyChzynSOL300uuI2GVLUlKy+OUv70z4c2otTu+80/QiwYaGvgl/TskYp2id07vvvtuuzmnFihW0hRxcoUYdLrFfV60GXjLG3HUY+2cCXwH/Z4x5pA37pQAZEVavNcYYEakH/mqMuS7kWOdgE/wfG2Nei/D5Hwd+bYyJaPCIiPSi+RcVQ4HXV65cyXHHeeNbXi+bM2cOP/7xj91uhooDjbV3aKyTX0XFagq+aDpr9deO/QN9+3oj7p99/l8cOLCeLl1OYfSJs91uTsztK3qf5cuvabx/zDFT6Z/X1vlVVaJob+/hq1atYuTIkQAjjTGrWqvves9sMjDG1AN3A78WkQ6HcYgrsbMxP9HG/c7AzvYcyXaMs081EG5cbFbQ4zFhjNlrjFkVvHFwAi7lAaWlLS3HrJKNxto7NNbJL/gy44Cc3MSeAbUthgy+nk6dvsGQITe43ZS4yEhvOma2Y4cRLrVExUOiv4cnwtI8CcEY8yLw4mHu+wRtT2TBzqR8ZYR1dwXd9g3zeKBs52G0Q6mInHFG8s98qSyNtXdorJNfWtAEUAG5Od5JZnv3Pp/evc93uxlxE5jN2BJyc49psa5KfIn+Hq49swnMGLPbGPN0hFuZs9uXwImhszsDpwBVwPp4noPylhkzZrjdBBUnGmvv0Fgnv9TUHIIXfMjI6EFaWkcXW6RiKT1oAqjs7EGkpbU2L6tKZIn+Hq7JrPe8AvQGLg4UiEgP7ARUc40xtUHlQ0VEZxtWUTN9+nS3m6DiRGPtHRrr5CcipKcf7J3NyR7iYmtUrKWm5pCSYkefdexwrMutUbGW6O/hmsx6zyvAZ8BTInK3iFwHLMCu2Ru6DNH7BM36DCAig0TkThG5E2dt3cB9Ebki5q1XCS0wa53XeHGiPa/G2os01t4QfKlxTo7HklmPvYeLCCtXZiKSRp8+F7ndHBVjif4ersmsxziTVf0AO773RmAaUAScY4xZF8EhhgBTne0Upyxw/6qoN1gljfxN+bx3ynvkb8p3uylxlb8pn+z7sz113l6NtVfNnTvX7SaoOEg/cPBnL03+RH4+ZGfbW6/Iz+f6W1ZzZv0f6dnzu263RsVYor+HazLrQcaYUmPM1caYHsaYXGPMWcaYxWHqDTbGDA4pW2CMkRa2s+J1DiqxGGO4Pf92al+p5Y78OzzTU9l43vXeOW+vxtrLAusPqiRmDOlrtjbezcke7F5b4skYuP12qK2FO+7wRg+tc87ja2tJvWOKN87Z4xL9PVyTWaVUzM3bMI8lu5bAebB412Le2vCW202Ki8bzxjvn7dVYe1mij7dSEZg3j7TtJY13c77Y5mJj4mjePFhi38NZvBje8sD7mXPO08E75+xxif4ersmsUiqmjDFMWTAFQWAZCMKUBVOSvseuyXnjjfP2aqy9bubMmW43QcWSMTBlChllDQBInSH73j8nf4+dc96IfQ9HxN5P5vMOOueZ4I1zVgn/Hq7JrFIqpgI9dQYDeWAwnuixa3LeeOO8vRprrxszZozbTVCx5PTU9Xm3AjbWMuQfpaQULEn+HrtAr2wgkTMm+Xsqg855DHjjnFXCv4enud0A5XkZAIWFhW63Q8WAMYZJr0yCfU7BPiDH/jhp9iQGXTIICXzrnUSanXeQZD1vr8Zawdq1a+nRo4fbzVCxYAxMmmR/3uSj8Jod9AFWgS0fNOhgz2UyCT7vUMl63iHnvBZofFUn6zkroP29hwflBBmR1Be9/Eu5yVnO51m326GUUkoppZRqNy4yxrzRWiXtmVVuW+/cXoL9IlAlr6HA68BFwEaX26JiS2PtHRpr79BYe4fG2jvaY6wzgAHAwkgqazKr3Fbp3K41xqxytSUqpoIuMd2osU5uGmvv0Fh7h8baOzTW3tGOY70s0oo6AZRSSimllFJKqYSjyaxSSimllFJKqYSjyaxSSimllFJKqYSjyaxy2z7gXsIuYqKSjMbaOzTW3qGx9g6NtXdorL0j4WOtS/MopZRSSimllEo42jOrlFJKKaWUUirhaDKrlFJKKaWUUirhaDKrlFJKKaWUUirhaDKrlFJKKaWUUirhaDKrlFJKKaWUUirhaDKrlFJKKaWUUirhaDKrXCEimSLykIjsFJFqEflcRL7rdrtUUyJysog8LiKrROSAiGwVkZdE5OgwdY8VkfkiUikiJSLyDxHpGaZeiojcJiKbRaRGRJaLyM9aeP6IjqliQ0R+KyJGRFaGeew0EVkkIlUisltEHhWRDmHqRfxaj/SYKjpE5EQRecN5bVWJyEoRuTGkjsY5wYnIcBF5QUS2O7/ztSJyt4jkhNTTWCcQEekgIvc6/yNLnPfq8S3Ude3/c1uOqcKLJNbO73m8856+TexntpUicqeIZLVw3KtEZI0Tlw0ickML9fLEfvbbLyLlIvK6iBx1JMeMKmOMbrrFfQOeB/zANOAa4N/O/dPdbptuTeL0CrALeBS4GrgT2A1UAiOD6vXHLrhdCNwITAZKgC+BjJBjPggY4Engv4E3nfuXhdSL+Ji6xST2/YEDTqxXhjx2AlANLAUmAL8DaoC3wxwnotd6W46pW1Ti+z2gFvgMmOi8Fv8P+L3GOXk2YABQCnwF3O7E5innPfd1jXXibsBgJ45bgA+dn8eHqefq/+dIj6nbkcUa6OCUfwr81vldzwLqnX0kpP7/OPVfceo+69yfFOa464E9wG3Y/xdbgW1A98M5ZtR/P24HSDfvbcAY54/7lqCyLOdN8d9ut0+3JrE6Lcw/puHOB5Lngsr+DFQBA4PKznXifE1QWR7gAx4PKhPgI+eNMbWtx9QtZrF/AXgfWEDzZPYtYCfQKajsaic23wsqi/i1HukxdYtKbDthv5T6F5ByiHoa5wTfsEmGAY4LKX/GKe+qsU7MDcgE+jg/n0TLyaxr/5/bckzdjizWQAZwWph973bqnxtUlg0UAW+G1H0O+wV216Cy25z9Tw4qGwHUAQ8czjGjvellxsoNl2C/KXoyUGCMqQFmAqeKyAC3GqaaMsb82xjjCynbAKwCjg0q/gn2DWxrUL187Ld5Y4PqXQSkY/8RBuoZ4C/Yb3pPPYxjqigTkTOwr9P/DfNYJ+C72C8zyoMeehb7Dys4NhG91tt4THXkfg70Bn5rjGkQkVwRafJ5QOOcNDo5t3tCyncBDYBPY52YjDG1xpjdEVR18/9zW46pWhBJrI0xPmPMv8M8NMe5Df7MdjbQnaC4OGYAucD5QWWXAF8YY74Ieq612C+7g2PdlmNGlSazyg2jgPUh/+AACpzbE+LbHNUWIiLYD8JFzv08oBewOEz1Amy8A0ZhL11dE6Ze4PG2HlNFkYikAo8BfzfGrAhT5etAGiGxcb70+JLm8Y7ktd6WY6ojdy5QDuSJyDpsclEuIn8JGlulcU4OC5zbmSJygogMEJFLgWuBR40xB9BYJ6128P85omOqmOrj3BYFlQV+76ExXIL9kisQ6xTg+DD1wMZwqIh0bMsxY0GTWeWGvthvhUMFyvrFsS2q7S7HXjr0onO/r3PbUky7iUhmUN09zjezofXgYOzbckwVXROAQcBdLTzeWmz6hdSN5LXelmOqIzccm2i8DryD7WWZhY39U04djXMSMMbMx76Wvwssw451ewF4zBgz0ammsU5ebv9/jvSYKnZuw355+XZQWV+g3hizN7ii82VTMQfj0g17iXOkr/lIjhl1abE6sFKHkI2deCRUTdDjqh0SkRHYS0Y+xY65goPxai2mtUQe+7YcU0WJiHQH7gOmGmP2tVCttdhkh9SNRrz1PSG6OgA5wBPGmMDsxf8SkQzgf0TkbjTOyeQr7BjFV7EfKs8HJovIbmPM42isk5nb/5/1856LRGQy9kqc64wx+4MeysaOZQ4n+PUZaazbcsyo02RWuaEa+01PqKygx1U7IyJ9gHlAGXCJMabeeSgQr0hiGmns23JMFT2/w85I+dgh6rQWm+qQutGIt8Y6ugK/z+dDymdjZ6M8FTu5C2icE5qIXIYd33q0MWa7U/wv5/LBh0TkefQ1nczc/v+sn/dc4gwn+B0w0xjzl5CHq7ETRoUT/Ppsa6wjOWbU6WXGyg27OHiZSrBA2c44tkVFQEQ6Yy9R6QJ83xgTHKPApSYtxbTEGFMbVLePM+42tB4cjH1bjqmiQESGY5fZeBToJyKDRWQw9p9QunO/G63HJvRvI5LXeluOqY5c4PcZOilQ4PKwrmick8V1wLKgRDbgDWzv/Cg01snM7f/PkR5TRZGz7vOz2A6ICWGq7AJSRaRXyH4Z2EmcAnEpwfbKRvqaj+SYUafJrHLDl8DRzmyHwU4Jely1E86EMHOBo4ELjDGrgx83xuzArjd3Upjdx9A0nl9iP0AdG1KvSezbeEwVHXnY/wmPApuDtlOwsd+MneJ/JXZK/iaxcf5hnUDzeEfyWm/LMdWRW+Lc5oWUB8Y07UPjnCx6A6lhytOd2zQ01kmrHfx/juiYKnpE5BTsDMaLgbHGmLow1b50bkNjeBL2c8CXAMaYBmBFmHpgY7jJGFPRlmPGgiazyg2vYP+5XhMocCYLuBL43Bizza2GqaacmW1fxF52+FNjzKctVH0VuCB4WSUR+Q42CXo5qN7rgB/bWxCoJ9hvDncAwdPKR3pMFR0rgR+H2VZhJ435MfZypTIgH/hF0CyGAFdgx2IGxyai13obj6mO3EvO7VUh5VdjE5AFGueksR4YJSJHh5T/DDvD6HKNddJz8/9zW46pjpCIHIvtjf0K2/nQ0qW9H2B7Xa8NKb8WO8RkXlDZK8DJItKYpIrIMcA5NI11W44ZXbFawFY33Q61YT9M+YHfY/8pfuLcP8PttunWJE5/wi6W/Qbwi9AtqN4A7LTvhcANwB3Om9pyIDPkmL93jvlX7IfnN537Pw+pF/ExdYvp38ACYGVI2YnYCR2WYj+U/A47HuadMPtH9FpvyzF1i0pcZzqvuxexHzRfcu4/oHFOng04A/sFxR7srMbXAW85sf6bxjqxN+B64E7s2p4Gm2Te6WydnTqu/n+O9Ji6HVmsgY7YL57rgUk0/8x2asjxrnOO87ITl2ec+5ND6nV04rwHuBW7/vxW7JcRPQ/nmFH/3bgdHN28uWHH4U3DXmNfg12v6jy326VbszgtcN6Iwm4hdY/DLvNxACgFngN6hzlmivOP7yvsWIyVwOUtPH9Ex9Qt5n8DK8OUn479EFuNHWv5ONAxTL2IX+uRHlO3qMQ1HbjHeR36gA3A/2qck2/DXvr5lhMbH7AOmAykaawTe3Nevy39jx4cVM+1/89tOaZuhx9rZ2vx8xrwdJhj/jew1olLITZRlTD1+mMT1DKgAjv0bFgL7YzomNHcxHlipZRSSimllFIqYeiYWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCUeTWaWUUkoppZRSCef/ASdWvSPfwkUqAAAAAElFTkSuQmCC\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": [ + "# Plot trace values for all neurons\n", + "plot_traces_for_neuron(log, [\"c\", \"w\", \"n\"], pos_dopa_spike_times=pos_dopa_spike_times, neg_dopa_spike_times=neg_dopa_spike_times)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see, the eligibility trace values for neurons 1, 2, 4, 5, and 9 are large when the dopamine spikes are applied, which increases the weights of these neurons, resulting in stronger firing. If the dopamine spikes arrive while the eligibility trace is close to zero, the weight does not increase or increases only very little.\n", + " \n", + "In our simulation above, we set a low value of 50 ms for the time constant of the dopamine trace $\\tau_n$. This means that the dopamine signal does not sustain for a long time, allowing only some neurons that fire around the time when the dopamine spikes (reward signal) are applied have their synapses strengthened (see the weight trace plots) and consequenty increase their firing rate. Similarly, the firing rate is decreased when the dopamine spikes (punishment signals) are applied. For neuron 9, the punishment signal doesn't seem to affect the firing rate. This behavior can be explained by the time constant of the signals and the very large weights after the initial potentiation, resulting in sustained firing.\n", + "\n", + "Play around with the initial weight value `w` and dopamine time constant $\\tau_n$ to simulate and see the effects of these values on firing rates and trace values." + ] + }, + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Noisy Cue-Association: Temporal Credit-Assignment Task\n", + "\n", + "In this experiment, the synapse is embedded in a network consisting of 800 excitatory, and 200 inhibitory neurons, that are randomly and sparsely connected. The network is in the _balanced state_, meaning that excitatory currents are roughly matched in mean amplitude over time, and the neurons have a membrane potential close to the firing threshold, firing only sparsely and with statistics approaching that of a Poisson process [4].\n", + "\n", + "Using this network, we illustrate a classical (Pavlovian) conditioning experiment: rewarding a conditioned stimulus $S_1$ embedded in a continuous stream of irrelevant but equally salient stimuli [3]. The conditioned stimulus is repeatedly presented to the network, causing a transient of activity against the background of low-rate random background firing. The CS is always followed by a reward, which reinforces the recurrent excitatory pathways in the network.\n", + "\n", + "To simulate the experiment, `n_subgroups` random sets of neurons (each representing stimulus $S_1$ through $S_\\text{n_subgroups}$) are chosen from the pool of excitatory and inhibitory neurons in the network. To present a stimulus to the network, we create `n_subgroups` spike generators (named `stim_sg`), and connect each to its individual target group of `subgroup_size` neurons in the network (here, 50) with a very large weight, so that the stimulus spike generator firing will cause all of the neurons in the subgroup to fire.\n", + "\n", + "A continuous input stream is generated, consisting of stimuli $S_i (1 \\leq i \\leq \\text{n_subgroups})$ in a random order with random intervals of rate `stimulus_rate` and at least `min_stimulus_presentation_delay`. After every presentation of the CS ($S_1$), a reward in the form of an increase of extra-cellular dopamine is delivered to all plastic synapses in the network, after a random delay between `min_dopa_reinforcement_delay` and `max_dopa_reinforcement_delay`. These delays were chosen lower than in the original publications ([1], [3]) to keep the simulation times low for this interactive tutorial. The delay is large enough to allow irrelevant input stimuli to be presented during the waiting period; these can be considered as distractors.\n", + "\n", + "At the beginning of the experiment the neurons representing each stimulus $S_i$ respond equally. However, after many trials, the network starts to show reinforced response to the CS ($S_1$). Because synapses coming out of neurons representing $S_1$ are always tagged with the eligibility trace when the reward is delivered, whereas the synapses connected to neurons representing irrelevant stimuli will only be occasionally tagged, the average strength of synaptic connections from neurons representing stimulus $S_1$ becomes stronger than the mean synaptic connection strength in the rest of the network. Therefore, the other neurons in the network learn to listen more closely to the stimulus $S_1$, because the activation of this pathway causes a reward.\n", + "\n", + "\n", + "
\n", + "\n", + "![image.png](attachment:image.png)\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This network uses neurons with a decaying-exponential shaped postsynaptic current. Let's first generate the code for those." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[11,neuromodulated_stdp88712fce9134422ea34eade734bde898_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[21,neuromodulated_stdp88712fce9134422ea34eade734bde898_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[43,neuromodulated_stdp88712fce9134422ea34eade734bde898_nestml__with_iaf_psc_exp88712fce9134422ea34eade734bde898_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[56,neuromodulated_stdp88712fce9134422ea34eade734bde898_nestml__with_iaf_psc_exp88712fce9134422ea34eade734bde898_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n", + "[60,neuromodulated_stdp88712fce9134422ea34eade734bde898_nestml__with_iaf_psc_exp88712fce9134422ea34eade734bde898_nestml, WARNING, [18:4;18:13]]: Variable 'b' has the same name as a physical unit!\n" + ] + } + ], + "source": [ + "# generate and build code\n", + "module_name, neuron_model_name, synapse_model_name = \\\n", + " generate_code_for(\"models/neurons/iaf_psc_exp.nestml\",\n", + " nestml_stdp_dopa_model,\n", + " post_ports=[\"post_spikes\"],\n", + " mod_ports=[\"mod_spikes\"])\n", + "\n", + "# load dynamic library (NEST extension module) into NEST kernel\n", + "nest.ResetKernel()\n", + "nest.Install(module_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we define the network and the simulation parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# simulation parameters\n", + "\n", + "dt = .1 # the resolution in ms\n", + "delay = 1. # synaptic delay in ms\n", + "total_t_sim = 10000. # [ms]\n", + "\n", + "# parameters for balanced network\n", + "\n", + "g = 4. # ratio inhibitory weight/excitatory weight\n", + "epsilon = .1 # connection probability\n", + "NE = 800 # number of excitatory neurons\n", + "NI = 200 # number of inhibitory neurons\n", + "N_neurons = NE + NI # number of neurons in total\n", + "N_rec = 50 # record from 50 neurons\n", + "\n", + "CE = int(epsilon * NE) # number of excitatory synapses per neuron\n", + "CI = int(epsilon * NI) # number of inhibitory synapses per neuron\n", + "C_tot = int(CI + CE) # total number of synapses per neuron\n", + "\n", + "# neuron parameters\n", + "\n", + "tauSyn = 1. # synaptic time constant [ms]\n", + "tauMem = 10. # time constant of membrane potential [ms]\n", + "CMem = 300. # capacitance of membrane [pF]\n", + "\n", + "neuron_params_exc = {\"C_m\": CMem,\n", + " \"tau_m\": tauMem,\n", + " \"tau_syn_exc\": tauSyn,\n", + " \"tau_syn_inh\": tauSyn,\n", + " \"t_ref\": 4.0,\n", + " \"E_L\": -65.,\n", + " \"V_reset\": -5., # relative to E_L\n", + " \"V_abs\": 0.,\n", + " \"Theta\": 9.6, # relative to E_L\n", + " \"I_e\": 0. # [pA]\n", + "}\n", + "neuron_params_inh = {\"C_m\": CMem,\n", + " \"tau_m\": tauMem,\n", + " \"tau_syn_exc\": tauSyn,\n", + " \"tau_syn_inh\": tauSyn,\n", + " \"t_ref\": 2.0,\n", + " \"E_L\": -65.,\n", + " \"V_reset\": -5, # relative to E_L\n", + " \"V_abs\": 0.,\n", + " \"Theta\": 8.6} # relative to E_L\n", + "\n", + "# J_ex should be large enough so that when stimulus excites the subgroup cells,\n", + "# the subgroup cells cause an excitatory transient in the network to establish\n", + "# a causal STDP timing and positive eligibility trace in the synapses\n", + "J_ex = 300. # amplitude of excitatory postsynaptic current\n", + "J_in = -g * J_ex # amplitude of inhibitory postsynaptic current\n", + "J_poisson = 2500.\n", + "J_stim = 5000.\n", + "\n", + "p_rate = 5. # external Poisson generator rate [s^-1]\n", + "\n", + "# synapse parameters\n", + "\n", + "learning_rate = .1 # multiplier for weight updates\n", + "tau_c = 200. # [ms]\n", + "tau_n = 200. # [ms]\n", + "\n", + "# stimulus parameters\n", + "\n", + "n_subgroups = 2 # = n_stimuli\n", + "subgroup_size = 50 # per subgroup, this many neurons are stimulated when stimulus is presented\n", + "reinforced_subgroup_idx = 0\n", + "stimulus_rate = 5. # [s^-1]\n", + "\n", + "min_stimulus_presentation_delay = 10. # minimum time between presenting stimuli [ms]\n", + "\n", + "min_dopa_reinforcement_delay = 10. # [ms]\n", + "max_dopa_reinforcement_delay = 30. # [ms]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the parameters defined, we are ready to instantiate and connect the network." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> Stimuli will be presented at times: [502.0, 1217.0, 1247.0, 1513.0, 1615.0, 1951.0, 2007.0, 2040.0, 2371.0, 3419.0, 3509.0, 3604.0, 3801.0, 3918.0, 4088.0, 4259.0, 4427.0, 4881.0, 4891.0, 5568.0, 5578.0, 5811.0, 5920.0, 6527.0, 7013.0, 7302.0, 7378.0, 7406.0, 7608.0, 7789.0, 7799.0, 7887.0, 8050.0, 8213.0, 8356.0, 8396.0, 8508.0, 8841.0, 8945.0, 8966.0, 8976.0, 9005.0, 9287.0, 9678.0, 9807.0, 9945.0, 10046.0]\n", + "--> t_dopa_spikes = [513.0, 1274.0, 1629.0, 2051.0, 2385.0, 3443.0, 3529.0, 3621.0, 3830.0, 4107.0, 4449.0, 4908.0, 4915.0, 7030.0, 7404.0, 7425.0, 7629.0, 7812.0, 7813.0, 8241.0, 8417.0, 8531.0, 8988.0, 9027.0, 9688.0, 9970.0]\n" + ] + } + ], + "source": [ + "nest.ResetKernel()\n", + "nest.set_verbosity(\"M_ALL\")\n", + "nest.local_num_threads = 4\n", + "\n", + "nest.resolution = dt\n", + "nest.print_time = True\n", + "nest.overwrite_files = True\n", + "\n", + "nodes_ex = nest.Create(neuron_model_name, NE, params=neuron_params_exc)\n", + "nodes_in = nest.Create(neuron_model_name, NI, params=neuron_params_inh)\n", + "noise = nest.Create(\"poisson_generator\", params={\"rate\": p_rate})\n", + "vt_spike_times = []\n", + "vt_sg = nest.Create(\"spike_generator\",\n", + " params={\"spike_times\": vt_spike_times,\n", + " \"allow_offgrid_times\": True})\n", + "\n", + "espikes = nest.Create(\"spike_recorder\")\n", + "ispikes = nest.Create(\"spike_recorder\")\n", + "spikedet_vt = nest.Create(\"spike_recorder\")\n", + "\n", + "# create volume transmitter\n", + "vt = nest.Create(\"volume_transmitter\")\n", + "vt_parrot = nest.Create(\"parrot_neuron\")\n", + "nest.Connect(vt_sg, vt_parrot)\n", + "nest.Connect(vt_parrot, vt, syn_spec={\"synapse_model\": \"static_synapse\",\n", + " \"weight\": 1.,\n", + " \"delay\": 1.}) # delay is ignored\n", + "vt_gid = vt.get(\"global_id\")\n", + "\n", + "# set up custom synapse models\n", + "wr = nest.Create(\"weight_recorder\")\n", + "nest.CopyModel(synapse_model_name, \"excitatory\",\n", + " {\"weight_recorder\": wr, \"w\": J_ex, \"the_delay\": delay, \"receptor_type\": 0,\n", + " \"vt\": vt_gid, \"A_plus\": learning_rate * 1., \"A_minus\": learning_rate * 1.5,\n", + " \"tau_n\": tau_n,\n", + " \"tau_c\": tau_c})\n", + "\n", + "nest.CopyModel(\"static_synapse\", \"inhibitory\",\n", + " {\"weight\": J_in, \"delay\": delay})\n", + "nest.CopyModel(\"static_synapse\", \"poisson\",\n", + " {\"weight\": J_poisson, \"delay\": delay})\n", + "\n", + "# make subgroups: pick from excitatory population. subgroups can overlap, but\n", + "# each group consists of `subgroup_size` unique neurons\n", + "\n", + "subgroup_indices = n_subgroups * [[]]\n", + "for i in range(n_subgroups):\n", + " ids_nonoverlapping = False\n", + " # TODO: replace while loop with:\n", + " # subgroup_indices[i] = np.sort(np.random.choice(NE, size=subgroup_size, replace=False))\n", + " while not ids_nonoverlapping:\n", + " ids = np.random.randint(0, NE, subgroup_size)\n", + " ids_nonoverlapping = len(np.unique(ids)) == subgroup_size\n", + " ids.sort()\n", + " subgroup_indices[i] = ids\n", + " \n", + "# make one spike generator and one parrot neuron for each subgroup\n", + "stim_sg = nest.Create(\"spike_generator\", n_subgroups)\n", + "stim_parrots = nest.Create(\"parrot_neuron\", n_subgroups)\n", + "\n", + "# make recording devices\n", + "stim_spikes_rec = nest.Create(\"spike_recorder\")\n", + "mm = nest.Create(\"multimeter\", params={'record_from': ['V_m'], 'interval': dt})\n", + "mms = [nest.Create(\"multimeter\", params={'record_from': ['V_m'], 'interval': dt}) for _ in range(10)]\n", + "\n", + "# connect everything up\n", + "nest.Connect(stim_parrots, stim_spikes_rec, syn_spec=\"static_synapse\")\n", + "nest.Connect(noise, nodes_ex + nodes_in, syn_spec=\"poisson\")\n", + "nest.Connect(mm, nodes_ex[0])\n", + "[nest.Connect(mms[i], nodes_ex[i]) for i in range(10)]\n", + "\n", + "nest.Connect(stim_sg, stim_parrots, \"one_to_one\")\n", + "\n", + "for i in range(n_subgroups):\n", + " nest.Connect(stim_parrots[i], nodes_ex[subgroup_indices[i]], \"all_to_all\", syn_spec={\"weight\": J_stim})\n", + "\n", + "conn_params_ex = {'rule': 'fixed_indegree', 'indegree': CE}\n", + "nest.Connect(nodes_ex, nodes_ex + nodes_in, conn_params_ex, \"excitatory\")\n", + "\n", + "conn_params_in = {'rule': 'fixed_indegree', 'indegree': CI}\n", + "nest.Connect(nodes_in, nodes_ex + nodes_in, conn_params_in, \"inhibitory\")\n", + "\n", + "nest.Connect(vt_parrot, spikedet_vt)\n", + "\n", + "nest.Connect(nodes_ex, espikes, syn_spec=\"static_synapse\")\n", + "nest.Connect(nodes_in, ispikes, syn_spec=\"static_synapse\")\n", + "\n", + "# generate stimulus timings (input stimulus and reinforcement signal)\n", + "\n", + "t_dopa_spikes = []\n", + "t_pre_sg_spikes = [[] for _ in range(n_subgroups)] # mapping from subgroup_idx to a list of spike (or presentation) times of that subgroup\n", + "\n", + "t = 0. # [ms]\n", + "ev_timestamps = []\n", + "while t < total_t_sim:\n", + " # jump to time of next stimulus presentation\n", + " dt_next_stimulus = max(min_stimulus_presentation_delay, np.round(random.expovariate(stimulus_rate) * 1000)) # [ms]\n", + " t += dt_next_stimulus\n", + "\n", + " ev_timestamps.append(t)\n", + " \n", + " # apply stimulus\n", + " subgroup_idx = np.random.randint(0, n_subgroups)\n", + " t_pre_sg_spikes[subgroup_idx].append(t)\n", + "\n", + " # reinforce?\n", + " if subgroup_idx == reinforced_subgroup_idx:\n", + " # fire a dopa spike some time after the current time\n", + " t_dopa_spike = t + min_dopa_reinforcement_delay + np.random.randint(max_dopa_reinforcement_delay - min_dopa_reinforcement_delay)\n", + " t_dopa_spikes.append(t_dopa_spike)\n", + "\n", + "print(\"--> Stimuli will be presented at times: \" + str(ev_timestamps))\n", + " \n", + "# set the spike times in the spike generators\n", + "for i in range(n_subgroups):\n", + " t_pre_sg_spikes[i].sort()\n", + " stim_sg[i].spike_times = t_pre_sg_spikes[i]\n", + "\n", + "t_dopa_spikes.sort()\n", + "vt_sg.spike_times = t_dopa_spikes\n", + "\n", + "print(\"--> t_dopa_spikes = \" + str(t_dopa_spikes))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Run the simulation. Instead of just running from start to finish in one go:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# nest.Simulate(total_t_sim)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "we split the simulation into equally-sized chunks, so that we can measure and record the state of some internal variables inbetween:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "def run_chunked_simulation(n_chunks, all_nodes, reinforced_group_nodes, not_reinforced_group_nodes):\n", + " # init log\n", + " log = {}\n", + " log[\"t\"] = []\n", + " log[\"w_net\"] = []\n", + " recordables = [\"c_sum\", \"w_avg\", \"n_avg\"]\n", + " for group in [\"reinforced_group\", \"not_reinforced_group\"]:\n", + " log[group] = {}\n", + " for recordable in recordables:\n", + " log[group][recordable] = []\n", + " \n", + " nest.Prepare()\n", + " for i in range(n_chunks):\n", + " print(str(np.round(100 * i / n_chunks)) + \"%\")\n", + "\n", + " # simulate one chunk\n", + " nest.Run(total_t_sim // n_chunks)\n", + "\n", + " # log current values\n", + " log[\"t\"].append(nest.GetKernelStatus(\"biological_time\"))\n", + "\n", + " syn_reinforced_subgroup = nest.GetConnections(source=reinforced_group_nodes, synapse_model=\"excitatory\")\n", + " syn_nonreinforced_subgroup = nest.GetConnections(source=not_reinforced_group_nodes, synapse_model=\"excitatory\")\n", + " syn_all = nest.GetConnections(source=all_nodes, synapse_model=\"excitatory\")\n", + "\n", + " log[\"w_net\"].append(np.mean(syn_all.w))\n", + "\n", + " log[\"reinforced_group\"][\"w_avg\"].append(np.mean(syn_reinforced_subgroup.get(\"w\")))\n", + " log[\"not_reinforced_group\"][\"w_avg\"].append(np.mean(syn_nonreinforced_subgroup.get(\"w\")))\n", + "\n", + " log[\"reinforced_group\"][\"c_sum\"].append(np.sum(syn_reinforced_subgroup.get(\"c\")))\n", + " log[\"not_reinforced_group\"][\"c_sum\"].append(np.sum(syn_nonreinforced_subgroup.get(\"c\")))\n", + "\n", + " log[\"reinforced_group\"][\"n_avg\"].append(np.mean(syn_reinforced_subgroup.get(\"n\")))\n", + " log[\"not_reinforced_group\"][\"n_avg\"].append(np.mean(syn_nonreinforced_subgroup.get(\"n\")))\n", + " nest.Cleanup()\n", + "\n", + " return log" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0%\n", + "1.0%\n", + "2.0%\n", + "3.0%\n", + "4.0%\n", + "5.0%\n", + "6.0%\n", + "7.0%\n", + "8.0%\n", + "9.0%\n", + "10.0%\n", + "11.0%\n", + "12.0%\n", + "13.0%\n", + "14.0%\n", + "15.0%\n", + "16.0%\n", + "17.0%\n", + "18.0%\n", + "19.0%\n", + "20.0%\n", + "21.0%\n", + "22.0%\n", + "23.0%\n", + "24.0%\n", + "25.0%\n", + "26.0%\n", + "27.0%\n", + "28.0%\n", + "29.0%\n", + "30.0%\n", + "31.0%\n", + "32.0%\n", + "33.0%\n", + "34.0%\n", + "35.0%\n", + "36.0%\n", + "37.0%\n", + "38.0%\n", + "39.0%\n", + "40.0%\n", + "41.0%\n", + "42.0%\n", + "43.0%\n", + "44.0%\n", + "45.0%\n", + "46.0%\n", + "47.0%\n", + "48.0%\n", + "49.0%\n", + "50.0%\n", + "51.0%\n", + "52.0%\n", + "53.0%\n", + "54.0%\n", + "55.0%\n", + "56.0%\n", + "57.0%\n", + "58.0%\n", + "59.0%\n", + "60.0%\n", + "61.0%\n", + "62.0%\n", + "63.0%\n", + "64.0%\n", + "65.0%\n", + "66.0%\n", + "67.0%\n", + "68.0%\n", + "69.0%\n", + "70.0%\n", + "71.0%\n", + "72.0%\n", + "73.0%\n", + "74.0%\n", + "75.0%\n", + "76.0%\n", + "77.0%\n", + "78.0%\n", + "79.0%\n", + "80.0%\n", + "81.0%\n", + "82.0%\n", + "83.0%\n", + "84.0%\n", + "85.0%\n", + "86.0%\n", + "87.0%\n", + "88.0%\n", + "89.0%\n", + "90.0%\n", + "91.0%\n", + "92.0%\n", + "93.0%\n", + "94.0%\n", + "95.0%\n", + "96.0%\n", + "97.0%\n", + "98.0%\n", + "99.0%\n" + ] + } + ], + "source": [ + "all_nodes = nodes_ex\n", + "reinforced_group_nodes = nodes_ex[subgroup_indices[reinforced_subgroup_idx]]\n", + "not_reinforced_group_nodes = nodes_ex[subgroup_indices[1 - reinforced_subgroup_idx]]\n", + "\n", + "n_chunks = 100\n", + "\n", + "log = run_chunked_simulation(n_chunks,\n", + " all_nodes,\n", + " reinforced_group_nodes,\n", + " not_reinforced_group_nodes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Print some network statistics:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Balanced network simulation statistics:\n", + "Number of neurons : 1000\n", + "Number of synapses: 100000\n", + " Exitatory : 81000\n", + " Inhibitory : 20000\n", + "Excitatory rate : 11.84 Hz\n", + "Inhibitory rate : 2.92 Hz\n", + "Actual times of stimulus presentation: [1218. 1514. 1952. 2008. 3919. 4260. 5569. 5579. 5812. 5921. 6528. 7303.\n", + " 7888. 8051. 8357. 8842. 8946. 8977. 9288. 9808. 503. 1248. 1616. 2041.\n", + " 2372. 3420. 3510. 3605. 3802. 4089. 4428. 4882. 4892. 7014. 7379. 7407.\n", + " 7609. 7790. 7800. 8214. 8397. 8509. 8967. 9006. 9679. 9946.]\n", + "Actual t_dopa_spikes = [ 514. 1275. 1630. 2052. 2386. 3444. 3530. 3622. 3831. 4108. 4450. 4909.\n", + " 4916. 7031. 7405. 7426. 7630. 7813. 7814. 8242. 8418. 8532. 8989. 9028.\n", + " 9689. 9971.]\n" + ] + } + ], + "source": [ + "events_ex = espikes.n_events\n", + "events_in = ispikes.n_events\n", + "\n", + "rate_ex = events_ex / total_t_sim * 1000.0 / N_rec\n", + "rate_in = events_in / total_t_sim * 1000.0 / N_rec\n", + "\n", + "num_synapses = (nest.GetDefaults(\"excitatory\")[\"num_connections\"] +\n", + " nest.GetDefaults(\"inhibitory\")[\"num_connections\"])\n", + "\n", + "print(\"Balanced network simulation statistics:\")\n", + "print(f\"Number of neurons : {N_neurons}\")\n", + "print(f\"Number of synapses: {num_synapses}\")\n", + "print(f\" Exitatory : {int(CE * N_neurons) + N_neurons}\")\n", + "print(f\" Inhibitory : {int(CI * N_neurons)}\")\n", + "print(f\"Excitatory rate : {rate_ex:.2f} Hz\")\n", + "print(f\"Inhibitory rate : {rate_in:.2f} Hz\")\n", + "print(\"Actual times of stimulus presentation: \" + str(stim_spikes_rec.events[\"times\"]))\n", + "print(\"Actual t_dopa_spikes = \" + str(spikedet_vt.get(\"events\")[\"times\"]))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Rasterplot of network activity\n", + "\n", + "N.B. orange diamonds indicate dopamine spikes." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA14AAAFeCAYAAACVR87bAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAABJ0AAASdAHeZh94AAEAAElEQVR4nOy9e3xU1bk+/qy5ZXIbEkIIjAgIgjFIEbHWK7FXsEL1tJbK6TnS0/prRYtHra0czrE3WovVekGRtt9qq+dULF5bUIOt1YCgUjFGIIb7RTIQQkKYkAvJzOzfH5M17Nmz3rXW3rMDaOf5fPgAe2b2Xntd3vW+73rf52WGYSCHHHLIIYcccsghhxxyyCGHgYPnZDcghxxyyCGHHHLIIYcccsjh446c4ZVDDjnkkEMOOeSQQw455DDAyBleOeSQQw455JBDDjnkkEMOA4yc4ZVDDjnkkEMOOeSQQw455DDAyBleOeSQQw455JBDDjnkkEMOA4yc4ZVDDjnkkEMOOeSQQw455DDAyBleOeSQQw455JBDDjnkkEMOA4yc4ZVDDjnkkEMOOeSQQw455DDAyBleOeSQQw455JBDDjnkkEMOA4yc4ZVDDjnkkEMOOeSQQw455DDA8J3sBnyUwRgbBKAawIcAek9yc3LIIYcccsghhxxyyOGfHQEApwOoNQzjyMlujBk5wys7VAP488luRA455JBDDjnkkEMOOeSQhqsA/OVkN8KMnOGVHT4EgBdeeAFnnnnmyW5LDh8TLFiwAHfdddfJbkYOHyPk5lQObiI3n3JwG7k5lYOb2L59O66++mqgX08/lcAMwzjZbfjIgjE2AcCmTZs2YcKECSe7OTl8TNDW1obBgwef7Gbk8DFCbk7l4CZy8ykHt5GbUzm4ic2bN+Occ84BgHMMw9h8sttjRo5cI4ccTjE8+uijJ7sJOXzMkJtTObiJ3HzKwW3k5lQO/yzIhRp+zNAQiWJp7Q5sa+7AuIpizK0ei6pw6GQ3KwcbuOCCC052E3L4mME6p/7Z5MQ/2/sOND6KMio3B05tfBTn1EDjRM3ZU3FtnIptcgs5w+sjAN0J2BCJ4upH3kBvLBk+2nigA6s278cLN176sZiwbi9E1f1O1sLv7u529Du77V1ZH8FdLzei9egxlBXlYcEVlZgxKey02QPWzlMNVL8N1HxyY5zMc6ohEsWXl65FT18CQFJO/LXhAJ6be8lHahx00RCJ4ktL1iAWT/6/8UAHXt4UwV9uuuxj+b4nAk5l1MnCQM552br+9evb8eCr29HTF0fQ78V/fvZM3HD5wOSDuyFXGyJRLKppRN3ewwCA80aW4o7plVr34c/fuK8dvXEDAS/DxBEl2u2wyqiB2CPs3PdE7FMr6yP4ycoGtB49Bg9jmHR6CRZedQ6qwqF+fW4temPH5+yK+gjOHlaM8lAQB6M9rrRrZX0ENz9Vh0R/1tGpsB+o1qt1bKZVVWBVQ3PaWJ3KyOV4ZYETkeNlnYAAEPR7hIviusfWY/XWlox7TB1fjie++dH2JtnpB9FvrQIUgPR+2TwvGzREorjtdy+jJ3+orc3LbntX1kfw3WV1GdfnTz8Lm/d3DNhmc7L61S3I+u2BV7eR72Xd3Kyf233ew7Mn2zK+fnT/b9E27JPY1tyBaE8MkfZMxXnmpDAemj1Z637UmjqVDGrexr9uPoCeWCLj8/NGleK5uRe7+qxT5d3dgOydlixZgptuuumUapPs83nL6rCiPpJxPztznmoPJc9Wbz2IRTVbMn4zf/pZrhtfViWdo7w4D4UBr/Ye8qUlbyAWT9cJAz4PXrgxU06Z+3poKIi3drZmPD/5e4aLxgxBs8JQ4HPKqaxUwc7ecyL2KUq2+7wMf7npUtxd04hagT5nRTbtaohEMeOhNWl9zTF1fDkG5fsHRKap1rFsvc6tHpsxNlYE/R788jODcdVnLgROwRyvnOGVBU6E4WVnw5jwwxp09sYzvlsY8GLzT6cPSPuygZ2TvOufeMeRsigSoB4GTB5Zig17DpP3G6iN2to2q9fmtqffS51YmqESrnbbe/Givwv70+5z7eJE9OtA4pM//xtaOo5lXM/zeXBMoHTwjYLa3Kj35nPjpY37ERf8sLw4D//4789peZkbIlH8yyNv4JhgXplROawYNbdMJT83P2tvW1fa+wR8HgBG2twN+j245bPj8MRbe0/Kqapqc/YyYMcvrszqGVR/DJQzIZsTCdG9KPlrjZ4Akgo0j55oamrCaaed5s5L2WivyllGtfm25e+h8UBHxj1Vc14FmTz7W0Mzuvsy9+N8vxcfLHS+H4vGTUdJV83JOY+tJ+9hlVM664uCeR6Z73ffyxuxva0Xu1u7tNpgF9RYFQd9uPysoWnzP9t9Ske3ke3BMyeF8fqWg+joiem8muO+od5TBLdkmkq2AMD0B1YL1+vosgJMHFGi1eaLy7qx7AdfBU5BwysXaniKY1tz5uSjrosUP9n1kwnd0A/Kk8dh7gezsKsIBWEAqNt7OGNzSBgQGl0AsGFPW8Z9qedlA9H7r6yPgFKNe/oSuP6JdxAK+oSC3G57W49mGg/Uc7/22zczNibru+h6+we6X0Vw8zTiENFv1Brb1tyBu2sahUYX/1zUXpVS03r0GPm93a1daWtpae0OpdEFAENDQfIz1ToUXe/pS6R5/CPt3SkP70AbX0trdyiVwngWPkfVGPX0JbC0dkfWpykqx0zt1hbUbm2xfYqikr+LahozHEC9MQOLahrxxDcvwMKFC/HrX//a8bs5gWhMzf1MtXnO79fj7OEhoSI3rqI4qzbJ5FmPwOgCIDTGdEGNm4cx5W9Vc/Kd3W3kbzfua0/7v876omCeR4C+EUft9boyfQPxfh09Mayoj6TNf+v7pu6xh+4jc9t0dJuWjh7yHtuaO4QONwqbmpzVB6beUwQ3ZBoApWwBkutStF73tomNchH2HurMqp0DiZzhNQDINtbZDGoCijaMPJ8HMcGJV57v1COvXFTTKN1EOe6uaSSVPQBoau/GvGV1mFZVgdufqU8Tdk7QerQXgL1+dwLRxqUSs5H2bkQgFuR22xvK9wtPbkQQbUwcdnMnBrpfeZuoEJis49dtKutDQ0G8u1ds5APi99ZRahJGcm3oKP66Ru1bO1vREIkK+0W1Du3grpcbB9zw0n1n6n1V0BmjbJwJonX14vsR0oBfVLMFI0oLtPuVMmK4k4VSUvlJ24kyusxruYk4HeD9XEess5aOYzjS3YqAj2WcyJpzQZwo8zJ5tutQJ+mQcXPe9fQl4FXbXQDkc1IUjsvRa/FSZOsoM4+VrhHHZaXOniMay8NdfdL7m2Wm9X05Iu09yrFTOQg4fB4P+uJiI7ypvduW4XX0mN7JmBWiCCkZ3HCQUrLFfH1u9VihvEsYmXORwsghhVjruJUDi1NPI/+IgwuFFfUR7G7tQqS9G7tbu7CiPoIvL12LhkjU1v3mVo9F0J8+TNYNg2PKaHENDOr6yUJDJIo1REiDdWG/tbNVei9uFNz8VJ1jD5wZx2IJNESimFZVAeteFvAx15I239pxKKvfc0HOIZsnDZEo5i2rw/QHVmPesjo0RKI4fXBB1s8E5JuMCHbmMwXR+5g/4+uv8UAHVm9tyTAYZO1TgXJiBLwMAV+m9vPWzlbpBip6b93NTWbQ8WcD+kZtbyyBRTWN0nu5Ad3T1myg+85O54HOGMlOEFUQrSuVHnbXy+KxE4GSP1yeUgoZX0szZ87UfpZTWNcyFXbFx7o3RiuRvbEEJoYHIVySjzyfB+GSfNx7zaQ0Rd38LN39WibPxpQXkr+7m1hnFLjMe2njfuHnujvfuIpiWn5K0k6YxeOUraPMLJN1T13MeaSyPYcay2MaJ418XQckliwlM3i/vrL5gPTeHD7JMzp6YrYilTptGF7m8aciOCi44SDVicyqCocwKN8v/F53byxjzVkR9Htw7fmnO2/kAOOUPfFijP0BwBzJV0YYhtHEGHsdQLXg81WGYaQFUjPG8gD8FMC/AygF8D6A/zEM46+uNBpy742To9qqcAjPzb1EyxM3a8oIIbnGrCkjtJ9nJ+/KafjW0tod5MGBVVnRFT42nENKLKppxFs7D2W00c10yLZOufdNB2ZBTs0TAELv4DBCKWSQH+pYNw+7oYN25rMIKm+nrvfUqeduwmmDhGGqY4cWYWhxMCNHojeWACOMtaDPg6W1OzLevyIUdHxia0Zb/+nt3Oqx+GvDgbR+ocZ5zdYWoUdXtQ5FOV4UPIw59vjrQvTOIjidB9RJhxlcrXIiK520y45B61T+9MWT/blixQpHv7cDnbXsYcDfP2jGxB+vUobTvru3PTXnI+3duP2ZeowpLyLlhnW/psaRkmey/YI6nRNBJxRPZ28K+DyYVlVBys+g30sb3P2nDOZoHg9zvu/29s+jhkhUO3yMrxnVnkONpQ64YTFxRAmZa8afY01teHPnIan8sxotXcech5xa4fPoHXlmk5tn10FKQTcyK9otNiaj3TGsmHepktXQOPxh1m0dKJyyhheA3wD4m+UaA/BrALsNw2gyXd8H4L8s3xVl3/0BwDUAHgCwDcA3ALzEGPu0YRhvOG3od554B5PP7cXc6rHKDdPJhloVDmkZa6samsnrOiEourSidvKzRBuSrA/M4U4rNZM+3Ubd3sNCAdoXN1yJcQaAuAtWnFWQi+bJvGWZJ4E9fQnyuP6yfiYjKrHX+kwnoYO681kElYKku76o9qmU5K5e8WbQuL8DR4hQFspo6YklhCGcumEjk0eWYv2uVnIT5XOsKhzCea2voeyy2an32tTUjl2HMhULA7A9xzmBCPp/W7NpP/ok4SDdfXF8eenaAWWyNCvEFEEJ4NyDq2PYNUd7HNOY6xh2VoQID7EITuUP78Ybbrgh63BD1Vqj1nIo6MPgwkCK0EQ3XMr6xjpyw6xky8ZRtF5kY2in97PJpzLjwjFlWNXQTMrPymHF2LC3XfjbrmOxrJR2K/j0W1q7w7bxRvXr9oNHMeex9djT6iy3xxzRQoW68eeL5oMMIqPFDR2AY/LIUq3vOZlLZwwpxDmnDXJcnsC6xqeMHiw8ILBGZlH9EzeMjDWXPLUV67+nIk5Zw8swjDcBvGm+xhi7FEABgD9avn7EMIz/k92PMXYBgGsBfN8wjHv7rz0BYBOAXwJwzCu881An9vUrUJ86o0y6CN3MZbGCjJ3VTAi1UrgC4lM6Xe8gtVHJNqTeWPI+06oqhFSrMmTjgTNDFhpmx3CWKRb5fm9WSda63ie6veJ3nDVlRKomlYhBzPpMkQLqhmfMrtHOr+ucFlHt01GSt0oUqcgROllaBvPaaYhE8S5B/GLF/OmVAIArF68RjqbXlHB/z3//Z4qFriESxRcXryHvK+pjam0xIE02PDR7Mi5edFjJmOlWorYMVeEQ5laPlTJgOZ2n3LCb8/v1ZK7kuIpi7XwPEZGGjGxHBDvhw17GHCl++X4vAODOO++0/VszdNYatU9UnzUUAMgTCRGoE14+11UOJN1xNGNaVQU593QVZXMbs8XBaA8ORsUy6vUtB9EnOdX2eJhrBiBw/DTYybtRTo9YwkDt1hZo8IwoWpWEx8OQEFDrz60eq90XeT4PvjBhmNBoUUWX2MFXp4zQOlm329+jywrw2u2XO2oTtcZnf/J0rN6a+f2Lx6QbXlT/WIeXes4vP3NqpdiY8VHL8fpXJMfiSesHjDEfY6xI8ttrAMQB/JZfMAyjB8CjAC5ijGUdENrTl4ABkPGnbh3VUqCSRw9rhJXIPE9OwstkG5UoLt56Hzv5CkCybxdfOxkzJ4VROawY1ePLMXV8OUJB+76Fwjz6NxWaeRuqnIFrP6kf/skRLslH5bBizJwU1j4toA198e7ET025Ysn7k3qm+XujywoQLsnHsFAQd9c04rrH1gvzsFSQ9R31PhWhIOYtqyOZucqL85R9p5Ovlg0TngzmMBk7j6gKh1CSL56voXxv6t8vvPBC6t+q/JJoTyxjvAoDXuF3DSDju7L8CDMGksmSQ5XDlc2JW1U4hMf/4wL4BF3DFTQdWSma77c/U4/Jo/SVcyB5KqGLgoB866eGkMst83xyAp21JsufsjN3GJIn+SJweaLKPXXCxkpFoDAcd5rowC1n7biKYvJeHT0xKbnG+Ipi8l2d2DmjywpSbbILvueES/KFnxtG0lFkF9zpCyTnp7WeGZA8NVRF7ZjxhQnD8NDsyQNe0+/3a3dp5Sja7e+JI0oct4la40/9Y5/w+0+8tTft/9QQWq+Tz3nn1A01/MgYXowxP4BZANYZhrHb8vF4AJ0AOhhjBxhjC/u/b8ZkAFsNw7BqgOv7/z7XjXYejPakFNEzhhQiXJKP0WUFtpRlp+Dx97rXzZAJElF4mep7so1KJTjHVRRr5yswINW3M/prWdTcMhWPf/MCzJ9eiXNHlmYsVFVipl8itXWVYpVisVMQ5qUCg4GaW6baEuSUQkElBZhpaflxvuiZ5gRdfkJ5INqTIpOp3dqC1VtbbCWqc9g12gM+D97ceUhKClBWGFD23cmguufga8fOs/hc8ok0fwA+rzc1Tk+2jca8ZXVYWR8RhnmYEWnvzhgvGZPU1377ZppxrbtZD+TpP4cqcd8u2ZEVVeEQ/nLTZZg6vhzFQR9CQR+qx5enCs7qyEpqvhfn+ZSyirqnCtR4cnk6nrjX+/uS8mHs2OwciLpr7YIzytL6le+hdt61KOjD/OmVUsNK5WiSjSNFVkHNvXBJ0JYeoHJU2rmP03sV5vkcrVfq9GlwYSDVJp32+C2egKpwSOpUzfN5UezA6cr3P2rsPuzPR9PpC5WjXXYyVxjwZryzDPX7jmiRXNkZ/2wPCqg1TkX6WE9j/URutPU6NVbbT8C+7RSnbKihANMAlCEzzHAHgNcAbARQiOTJ1v8gaYx9zfS94QBElED8mjQJijE2FIDVbZYxK8dVFGeVw5INvB6GmODYyqvh/qFCLTwsMxxHJ7xMFbpRFQ7hd9edT4azbdijDlcCkoYQVYDWem+GZDX2O6ZXSkOt+iShhlSohhUqxULFSCd8tib9uxlU8vec368Xfl8nv8gu1TVgL7RMx2g3v8+R7j6lMaGzUerkq7kVzmqGee3Yye3h/USddBztiaWNU1N9BC++rxe+Zh2vXonzxlpuQCf/aaBP/zlU+T9uhDtWhUOp+jNW6MhKar439zvxeMFkVTFVO/0pKw3w0OzJOHPBS8LP6vsNr/x8sdNMF6q1JpLfb+86zqw5t3osVm0+oFXioKs3rkXqI9u3qXGUkVUc6RZHmnRp5qSZQ8c+dUYZDABvbGtxLH94kekLzihD3d7DYEiG1evkyB2M9mD+9EphH8TihlDvAEB6KrcdPJpqEx+X93YeQORoQhhV4PNkKuEyWXksFkdpYb52AWIOvv9RfcI/F82HgM+DC8eU4WC0R4tERxbpW16cZyuUNkHcTEQEcsEZZfhgf1RaTsbDkPVBgd08Ves7ULXprNepsdJdZycDH5kTLyTDDPsALDdfNAzjW4Zh/MQwjOcMw/hfwzCuAvD/AMxijF1o+mo+ANFM6zF9LsONSOaDmf/82fwFLxL4+uQhmDMnScbIKXdvvfVWbN++HY899hief/55rF+/HgsXLkRXVxdmzZqV9t0FCxZg48aNePLJJ/Hkk09i48aNWLBgQdp3Zs2aha6uLixcuBDr16/H888/j8ceewzxBJFkn0jgnnvuQW1tLWpqarBkyRI0NTXhhhtuSN13bvVYeAw+UZMLgAH4XOGHGBaMpb1TVTiEizvX4dNjilER6MPksjh+etkgPPvog6l3mls9FiwRS7ufjxkY3bUl9U5V4RBGfPAnzJwURv6xNnxxwlBM927G0X2N+FxZFLrnS6J3mr3wMWGdrJ6Ow3jxj7+R3q/9KG3w7d/yLgD1OFGKvrezBdu3b0dnt/18oL5+qvsbbrgBTU1NWLJkCWpqalBbW4t77rkHbW1twrkX6DqIyd11+M6oVvz72D48++iD6OwRKwUd3ceUc+/hV7eIqa4VOSPvbo8I5x6AtHcqShwV/p73/f+750f4z08WY1ZoOz4T3I3dB9ogmysBL8Pori3K9eTd8iqOR9Ql7+cx4phbPTb13UTCnjDP8wJMQvbsiR/Dc3Mvwf+750fYvn07hrdvhN/D30Xen4HuVjz55JOIEbVgjsXijsaJP/uDfW2pcTI0Ts25sXbHd76O5+ZeAhj0b07b93dUhUOuyL3t27fj1ltvTfvunDlz0NbWhsMdEuXFMLCtucP2erIjy+Ote/D/jT6CTwzqxegSP0ahBc/NvQQ333wz5i2rw1m3PYndRKHPo03bAABrGvcnFUjZuPV/JlpPonei7mTAwPr16xEj9pJYIoGNGzfiN7/5TVbj9MGzD2Z43v0eYJL/AJYsWYL7Xt4o9ODf9/JGLFmyBHvfX4c7P5WHkf4OFOV54U30kl0TTySw/JV1ePbRB3H3VWchtO5hPDR7Mu74ztcB0HOvIRLFpLkPYPoDq/Fvdz2Bn3/pbIzxtmHUIC8ml8VxXbgFz769XdjOB19pQHuXWLGNdvcpx+mtxg8x48HXkqFj+6Oo3dqCN7YcSMvbtIuL5v8vrly8Bqu3tqCjJ4ZoT0w7z7h112YMC8ZwVcE2fGq4D6cVApUFR/Hrr4wj5U9yNonR0ZncY83705itT0nqkRkZ4/T50xKgZGTCMPodt/as1PaOLjQ1NaHtiHgPau/oQk1NDVq21eGqgm2YVlmGwr52zJwUxsjGP+GJb16As/c8j//8ZDHeqnlGKiNkLdOtVcXh6RXLkKLEUfzo/t/iXx55I63EyqGOY3J5Eo+lyWcnOuzori0ZZQhkSBhGmozo6RHrSLF4PE2PoKj0j/bQMuFkgxlucmQPEPpzt5oB/N0wDGUBEcbYWQAaAdxpGMbP+q9tAtBsGMZnLd+tArAZwA2GYZAaueTE68+X/OAPmHzuJ7RYX7KhYVdh9PwXyc9mTgoPKEW8CNne79evb8eimi3K7+1edGXGtekPrBZ6WyqHFaPmlqkY+18vCj1rXgbk+b2kt+Slmy/TegeKnCIVKvPfL0mZ3yjM7A+nzBZVP6wRvmNBwIuGn04X/OI4qL5VQbftqr6zYt6yOmESe3HQh8vPGmqbrl42Z8f/90u2NsWgzwOPh5HzSdQn5jbI+pnPRadzSQVz285c8CJ0Kjvw9QXI+0o2nm6Cmucc1ePL8ThxWjVQ0GGH4/2ztHaHlBzEjKnjy8mTN+vzZSf+uxddiTPmv0gmtu9adCXa2toweHB2yeuytaaS3yJQbQbszzddGSRr55YDHWR7VPvInMfWZ5SmANwlZODQOcWXtVemd1Dt9XsZtv38i2nX2tra8KlfvSWUZaLvA/blsQp8/3OyP9rVd2T9Fh4UtEXWNH/6WXjg1W3C+WpHhnD4PMD2uzL1Kl3wvlAx3FphnmfUvmadC9RYedv3YedvbgCAcwzD2Gz7JQYQH5VQw6shZjOkwLPqzDvDfgCnCb47vP9v6cw0DOMggIPma6zf+/Sb687HhAkTlI2SMTkBGDCDDEBq4TUe6MCqzftx0ZghaLYciXMWMN4OUY0hO8gm5LIhEsUDr25z9FtAHcpCqTwGkvHsooXs9zLctvw9rfFRhbaQoRkKuJVvRL2jjFiEwwnVtYxJ0E5tHBGoMKA/ffuitAKpOvdTzVm7o9YTS6C0wE8q/6I+MbdBtjlzOJ1LMljHS3fvNJ/0ykJ2TwSrIUDPcw6d13LbIaViRAuX5ON3151vK4kf0K8N5bRotBm33norHn/88azuIVtrTspUyMbS7nzTZTGUtXNHy1FS6ZSVU2iIRMnQ6YFwk48cXICJI0pss2hmAxFz8K233opYeJbw+5SMG1QQkIbM2QXf//J8HqHcsNaa4nBaNoKEzZPNzfs7yD3Tic5go3ZzBrIpO2BeX9SYW+cOJeNl4fEnGx8Vw+vrAI4C+Ivm98f0/22WXu8B+DRjLGQh2PiU6fMBBSXMF9U0ptXjsbNozUqBLnpjRsqbZjX+XBUeWUCXrpXKX1PlVngIOmXGGAoDXoi2vb64gcYDHdr9IlMsvIwh5uC02S1CAuodizQML1UOT15/rHvHsVhqXp4noE92UhtHBJWhZndTlCnaIqYrFXqIcJ7y4rysFfiHZk8m55LXw+D3sow1UJznQ8tRcRiGz8NwxcThGcaFzny1Gmuq6X0iSEuoec7xoaJ4q+sKFdTvHQr6lJTqIuiqam70e7ZGlxmi9SaSMR6WTKSft6zOkfH7yuYD2r/VJf+Q7TN/a2hGHxGGJzMEZcymA3HiNXFECR6aPTmZ/0nc3KmThGqrKH/n8ccfx5kLXhLLMsIQkRFhOQHf/6jcQeq6k3IDMlAGHgWe/2ynnlxhgC6YnQ2yKTtgXl/UnmOdO5SMl5UFOtk45XO8GGPlAD4H4HnDMLosn4UYY3mWawxJcg0AWGX66BkAXgDfNn03D8B/AHjbMIwB556khHnd3sNajDRWWGmInYI/S4fi1y1QTFAcusoBZ0eygmKpApKhaQliURYEvFqsbNn2y5kVssoHYoiITpxiVFmh8PpIjVpAKlbKL0wYhjumV6IhcgQdPTF09MRQu7UlgynPzfkmY2C08xxVGQAnoEJhWo8eU95XxmzF1wg1l8ZVFKXWQLDnUGoNXDh2CHnP278wXsj8SD2jOOgjafpVKtGJYDVUrWWquDXHQMhE1XubP59bPVbboOK1oVSyVfZ8nyf5e2re8es8nyNbUOsNQFqZCh4Ot7u1y/GaPNZfsFzntzpslICcDdGnYKWzy6LKAIwaol+rTQdmZ4nMUeK2k0QkT5K50bQsE0F2qu4E55w2yNHvnDDiymyrc04bhAKihIcITe3dZNkWitn4/NF0qLATRkgO6p3zfB7MnBRGaQFd6N28vqg9x3y9IRIdEONxoHHKG15IMhP6IA4zPA/AbsbYfYyxGxlj3wOwpv83vzUM413+RcMw3gbwNIBfMMZ+yRj7NoC/AxgN4AcD/A4A7CsaKmHnZkHDbc0dJ4xOW0e51e2rIYThBWQq4wBSz6XEdSyeSBKNaGg72fRLoV9fqHJMHlnq2skjnVyvB85KSVE06yisJ2q+2XkO1e7rn3gHDZGos+KchiGcTwlDHfZ15lDaQOdrhJpLhX5vag00PjAnZVDJ5vfm/eK+op4xfmgRSdNfJNm8TxSroeoZqppjduaOyuAxt0m31mNVOISpRA0qK5LODrVslRlzsURSRgaJ8eZ121asWKHVJlWfUOvtK0vX4cY/bgCQdBJZ9WuR8au7Nvl6lo2Tqq6XGZTTR1UkWde447hsfDnKCsT7nQ3mcQBJI85Mzw/IZb9sP7ZjIHCI5MmKFStQQMw76noHwRyZ52Mpo10X5vEtICI/qOt2xpKvCZnPZ271WNjhX+DMsiKnAuUcuGN6JSkHRhBOVR1QfcFrmsmYSM3rS7avAcf1SDdDTU8UPgqG19eRzK36m+CzPUgaWv8C4FcAfgogCOCG/j9WXAfgAQD/DmAxAD+AGYZhrHa91QJQwlwUhgWojQ83FdRxFcUYShQHdtsz7bR4pghNGpTzsudacawvgapwSOvkJ5t++cDBCeUH+6Mpoaqr5FGgaPF16fIBubdXR2G1q3g4hZ3nUO3mta0CXvsiM+j3kvNJtYapvZfh+CZFzSXzKThnigIgnd9Ue3SeYUUZ4RQpDHhPWPhyVTiE8iLaOaM6EdOdO3ZOSkVFx88YUkjWerxDUIPKijyfB1XhkNRxwGUF/z6Fnr4EWVaiL27gy0vX4pu33SltD6DXJ7JaP/x0i8p3sv7WTuR2pL1bOk66BeRlUBVJppwClJ4wf3oluQ51IqDDJfmpd3nx5svw+DcvSHuffIkzcFpVBfnZ0OI88jMKIrlx66232pYzdB5QsiyCbk1B6/hSBeOp67qGunlNyFAVDmmVSrDCzml8VThEnmzvIphWdaDqCw/h9bOmjajmgpsHDycap3yOl2EYF0k+24VkUWXde/UA+H7/nxMOKhcFSNYokdV6EUE3/n/KyBKESwuwrbkDQ0NBvLWzNW1R83oktz1dn/FbnzdJfzv9gdWukX7oKOW8r65cvEbqieNxvDoJ8DqGKu+VUWWF0joa2XrsqbwfGbp647j6kTdw31fPxe3P1GeVd+IkeV0Eu3Hl1jAqVY0jN2DnObI11dOXQHlxHnoEHjYvo5UfHtIhmk+q/q4IBYXtOW9kSWqsqXC5HtP1m266Ke0zSsmiyFWo+Sqjo544okT4zp85u+KE5ozKyEdkCiUgnztmmRPtidnK8XCSwyiThXwOyBwHERyXFarEc1VNPqPy88p26+S9DCXmtxlUU9xy0FDjlG09TtUc53W17JALqUJjKXgYUoQtFK795Aj8ft0e4WdPb9iHGZPEpU5Ve6UIPYL3uOmmm/CXx7Zqfx9IOhBiEhIMp87pkcQ7jSRC9HUJoewYC06DKK3vLMtTpchfnM4zQN0Xk0eWCp0p8YSRRjqj2tdORI7wQOGUN7w+bqCEuR0WNw6dQqUA0NUXT3umSNgvrd0h9LAkEhAScQxEYT1R/LxHotACyaKFugnwuoZqQySKN3ceyrjuYclN5pzTBmVlgDZEoo6LYPbGDNz1cmPWibzTqiqEXrem9u6sjGw+tzbua8+gKRaFUenMe5lRrWNw23nOke4+eQI74VaXlSD46pQRuO3p9zKuB3xqI7ODOHkwzHFVlKvfdH316tU488wzASTfk/Im7iXIJqj5KpvH1BybMHzgc7s4GiJRHO4ShyMBwKqGZlKhBOTOMh3mLreUAx1Z2BCJask4N7zEDfvalN/RcbDpRshZ16TbDhpzm9xisVRFIaysj0gdaEJZ7rD8zw+mnaV8h52HaONJxph5sMN+TUpRGN3q1asBg3CEEO9dOTyEDXsy21Y53B45jbkAfFU4RNa5pK4Deoa6jjxIrQmHOgLP9+LzVuYAyTblgIKsL2ZNGUGeYqfpMcSYxxMG5i2rI52SHGWFfuy33/QTgpzhdYrAiXfNqhRsO3hUyOTywf4ONESiKcErehYlEKjY+mw8gfZOOuQ8TsdiCW1GIV1DNWmEZj7z0nF6dXJUyJaspPWoOKbZjpK3qqFZeP3d/k3MiZEtopFVGavUvDcbcHvbulLzsPFAB158P4KRgwswsqww7fRW1mbRc8wKVkUoiDd3HhKOuxkUG2CPJMF3+YZ9wvsOyqeTjDlkyitvP6mMM5b6zjsflqOufzOWzb8okTPhBE9v2Ce8fnfNFry5sy2jnIUO7CrFqrW2qemI8pmiuTNvWZ2WAeNq2CxjUsWbl//QkXEyBP0e9MUSUiMvXKwOudVxsDVrhjZfNr4cDEkDwIA4f4raKRiAGf11LKM9sf7CuuI2ucliuaimUfr5T1Y22HegKeYAhXU723DD5fLvvCsxrmRP3ELkhcqQMJDh4CstLaXfj0jgo07o+R2mVVXgxfcjWo5Oc99TCn02JGaAniHIX9Wp8cPzvfi8PVG51Lr4/brd0s9T7ZLM9RX1EQR8DAGfhwzJNLTdOiceOcPrIw6zUnDmgpfI7y2qaZQaDXZoi7NdsHbqNCUUmwyTtMd63fxcWYw1dT87+U8yZNt/ZUV5UuWBQ6ak6rTBjdo3CSPJ0GTHUFfVAeHsZqJQEN02ixQsFWSFRmVq7ju7xacDLR3HpPV8ZEj0h2XIFGyfx3wq40ltxsOIXE4gObfcAqXIGaBP0c1zdmgoCAakDLRpVRW2Q2xV89xpSI3O+nH7VMbvYVKKZE4pbZatlKFBzWUPS0ZffPmRtYgTfeNhwOxJNDMmh46DTWffCfo9mDVlRNrYr97agvW7WtPGPuBjOCZwcAR8LCUPqMLIvE1u0oJT657DiQNNNQco6NZ4o2A2TM17yrSqCqnsk8FamuW0006Df0Or8P0o2nhqT67bczh1ominu3jfU6GN1HVd6DhGnOQR+zwsI6Saz1uZA4Qq8u2GyULpH/Uftkt/x+eaaq73xgxMHT+EPD1r7xI7SU8FfBTINT52yJYYgYJfsmDXbG2RPkeUEEkxn0V7Ylm3XUb/bYZKZnb1xVGhSQqiW/OMuh913S6y8YIHfAwLrshMtrcqNKrEdt13sWMkuuVZyzZpVud5us8ImejSZQaLjAVTls+nSoYeT7AaBnweZfsTRmZYWU9fQkq/u+AKMSGAjPqYkgVUyQYreB9Y5+zqrS2o3dqSmr83P5V5yqTqP9U8V7EaUqDWsJnAwG0CkXwFexyXy/zkq+aWqSTzKFkovZ9p0y8Z8FFlhdjy9qvK9uoQVIj2HYZkjTsz4ciqhmbl2BcECCY603VVm9w8HVAZ9aJaVoB8f1DNAQo6a3G85LnFeT7hnnLzU3WO2mMGH8dVq1aR8466Tq1vA+ITRRX4/ShGQdF1O/qcef5Rkoe/q6ocgRkjSsUshNuaO6RkF9Qz7DxbBJn+IaqfymEOv9eZ6wejPWQtV+aIgvjEIHfiNQBQ5aQMVJHioqCPTHY3kDz1GpTvF7arKhzCvddMwl0vN6L16DGUFeXhugtH4oFXt2UIL2uitshb7RYRhwqGkXy3oN8j9ayu7N8kdHTBgYp75phbPVbJaiRCaYEff7z+QlSFQxhTXiTta5XnVvdd7BiJbhF2ZHsiqPM83WdUnzUUD82ejIZIFDPep8fM62FIELFZqjkna0thUByOqMN4RRV77iLyxiqHF2PGpLBwHXs9HsQS4mdSRcUL8nzaNVa2NXcojWGqH1/fcjAtlNoMKkeOg0qWV4E6zVERGGQDFSEPJZdF0QVf6a+VZUUCUMqm0wcX4HvXfk+rzaoQet3oBx2DiOof63VZm9yQYakQYMXCnzRiEDbvj9oiF3JCygTQNOhmkMY4gD2tnbj+iXeEEQ1uYFtzB+7+3vfw+4WvCT/vJNaxbH1TJ4oyHH8dceAqs5hLTvQ5Pv+ogtX8Xe3UhqbIQMZVFEvXGPUMnWfL9D2Z/hHwekinxIVjylL3oHKmre/XHO0R5vEW5jlzUpwI5Awvl6FaiG5XODeDquDNsWZrS0qUiIwmcyhHpL0bD7y6DfdeMwlPb9iHur2H0dUbJ4+z51aPHRCDUp7hlcTBaI90826IRLWNLn4/O9ftwml/VISC0jw9M1SKyt5WNV2s3VApt1gK7YS9WmGmWc/2GdYQJJdrdaa1hYJbc84Mis63pzculF+rNu9HnyL3DciUY1R4kAjjKoodG9wdPTFhyGZDJIo6QeK9GU59onbCpd0CxUAmgnksRLLCzr2seGtnK2Z9+1as/L/fOL6HGTr5zToGEfVOdt41WxmmCpPm8DCgtbMXF5xRlhZOq5pDjsdNIy9MJmvMebYDgXEVxfjGN76BxJg5ws+pZ8tkhocxZaqCFbwPmKb7ldLnvvbbN3H5WUOl46kiLFIQj6aBIdP5zJDM2eVOKdEao5xz1HUOlZ4r0z/KCgOIHFHrWCrnIl+XG/e1Cw2vYg1nw8lCLtTQZahqVA1koqOqZoV1KZnbRbX76Q378PauVkR7YiQtM+WttlNTgoKs3gwH9+pQoYt2lWZKEXYjxDIb2D19oq43RKIke501VAqAozCKbMKtqLDXcElQ6Ym7bHy51vNEzwj4PJg6vjzV9nuvmYSltTsw/YHVeH3LQen9SojCpgDgVYQ8SGvkEKE0nb1xBBRrI+DzCENMqMKue1q7cHdNJmNmb8zQPiHduK/9+H80Qz34Bqozv6nxFxXFlbF2cezRcEBQ0A2Xdgs6stAM2Z7iII0khd5YAmdcKSqTmcRAhNLr1Emi+ieeMHD5Pa9ptSVbGaYbwszzVFdvbcHbu1px36xzteYQ9Y5UuBVHy9FerFScZMrW30AaXXwcly9fTr6H6v1EmHR6iVYtUDP4/kjJLmthcWqNyQoa64KqsSVCc7/zeWo/CQ1wPJdW2gaH4XgqfU+mf0zpL68iQtp+J2maeV1Seu+4YQMrj7NBzvByGSrDaiCLxs6tHmvreBo43i6q3XV7Dys3Epm3OluDcsJpg6Sf61By220DVbxZVXTTDs4eZm+8nZw+UYqKzBBdcEVlSpEEoF0UlsMNZVSk/KycdxnWzf8sVs67DMVBsSeLQV20VPaMF268BE988wLU3DIVc6vH4vZn6lPv3tEjD1kbQhQLBoBQvk+qAFAMk4CcvvjCMWUIl4hj+5PP9afeMdhzKLVZzZ9eKdzTDAD/UBACqLC3rSs1P3Typ8Il+akNVFU0Pej3YPG1k8nxt67PNCOQQG8WJz/AwOXriiBTWESQ7ynZ5T/89e33hdftFJK2Ax2DiOofA0gVY9ZpSzYyzMl+Z8dBSb3juRpGxl0vy1kWnRDBBP0eXD5eTbRihYchYxxnzpyJc08vEX6fun4e4URiABZedU7anFEh4GOYVlWBLy9dS4aJnm/pf5XeZh5bq6ygbB6uw1mNPBm483lQvl/qYLciSDkrDHk5BJW+J9M/5laPJd/dfHkIQfRUXpyXti4pR+22AyfeOa6LnOHlMlSGlW6FcyeoCofwg2lnZVz3sGQRZREqQkHMW1aHJgHzFaAO81N5q12lU7ZgyqhSvHCj2htppw0eluzHWz47Tvq9bE/zbvr0mdrf9XsZbvnsOOl7WoU6AFJRkSkHtz9TnxK4A3WKqQNK+akKh3D5WUOFv5mqedqlegZgn+Bjb1sXSvPFBkF+wIt7r5kEH+EVocajIRLFu3vbyWcejPYgRBghQDLUj79j4wNzUu9YFQ6RSppO7pgMCeM4hbvqBB5IkpeYx9Y8Z6eOL0e16QTyubmXYMakMDn+ZvT0JbSMKjqkSI2BMjIozJoyQvu7qj3FCTOeGf6SYUJDcyBlhsog0ukft+VXQySK6x5bj4k/XoWJP16F1k5nTGq6Bhv1jv9x8Wjc8tlxZGF0QJ3zVBUO2TpVDZfk495rJuGtXfadNV4PyzjlW7FiBf7j4tHC7/Pr1n3uq1NGZBBBMCBN1vE5QxkZHIaRLIFByX2/l+EOi2NP5SwCjpf+sMoKVRRkt2Z+rHmt23WAywxSUTkE3v+Uvsh1LZWjhHp3cyTOty4ZLfyO9TrnJwiX5KdOCRMG0NTufpi+Wzh1gyA/olDFiGebG2CtPWQgqYBxatd7X9mS8ZvF107GmPIiXP3I2jTFyu9l0tpFPCxJRNdZHPSlxTDrxMY7Id/YKtmQ6vs92qr72qltw/prH91dk9mPVmRzmic75bCiL25gUc0WjCgtEJIfyGi2RXHdQyWFB825Iada/Q8Oaq5ZN8VsYPcde/rioHSu7t44bln+HhmqSzkGFtU0Ss0C/jtqLA939aVq5cTefxFLf/E/AJLrpZtYCwaSnl9VPTMZeN9RBZTNEBVNp+qt3fjHDUljyjCk1P4ceT6P8l2yOfEayHxdEVQyozjow2kl+Vqy1e/1IJZwRtQAAB09fRlFZ4GBDaVXQVembmo6gnnL6hzn5plrDO5p7Upbo6qTcQq6zkHqHR9+fTsaFfW0rKUirPvIhOHFJOmBdb1xIhmnDLR9cSMjL3PBggXomPhV4fdXNTRjTHmRIP/0AAyLIKBWdHG+Hz0dtPHZFzekJQBE+WJmfe71LQeF4z80FLTVT/x1ejWTvMxOWbvkMBR5E5BZgkCVv2jV96i8Mll9uz2tnamctM3EfLZeb4hEk/trltELJxI5w8tl6BhWOsnEIshqD3Evigi/emULTi8rzPBmx+Li3I1Q0IfqfqMKANbvas1Qcv/07Ysy3klFcOGEfEPmmY3FDXxv+XvY1dopva+IsfFgtBuiPcbvYbjzz5u0/ODZnObphEFZceefNwk3H1GBSEoBbIhE8dbOVulzzGGxbrAUuo0TQWxgl+BDJvNFib8cslBZVe2daVUVGFNeRK777r54inEw4D0vtaHd+edN5D3jCQNejwdTxw/BwWgPhoaCaUWqdcDnx5LXtku/xzdqOyywZvDi3MdiCWGtqnNOG4Sgz4MPJOPYkUXBaJWRoXII2XVEqWTG5f0MnDooyvOSDLh6SHqWrXKGWjfRnhjJPOkWdGXqntZO7DqUzO3j5DEXjRmiRXChS54RLsnH/vZurX1EdjppnSMbCMNAZXQBwHUXjky7r3UfWVFP//YH087C5v0dGXM1G4PaPHcaIlHsO/3zeHPTfuF3N+5rFxovlFyat6wOY8qL0sZRh+xHtibiieQe/Ozci9Ouc32uIRLF1Y+8keHoeWtnK8KD7Jei0T2U/s3qnbjh8mQEDeXsovKIt0vGz9pblPFo1hd11vd6if7BIyYemj2ZXM/W63f+edNHyugCcobXgMCpYaWCU+/SrtYu7BJQjVJTNVySn9Z+XSVX9t5OvcOqpNpGQQFA631FjI0U8gNevKco8Afo5ZbJoEuzbcbhrj6ySLEIok1xae0OpRJtDoulTjFPRukAMwZqjXGI3j3bkyARzPS5drGqoRkPzQ6jtMAvNe6A5MkOXxOq+d0bS2BQvj9VcL0hEsUXF6/RapPfy3CkO3nSJjNcZ04Kp9aPXRZYDl6c28qoChyfpzMffkPa3p5YwrFBIHNMqBxNThxRRxRGoi155GKNG7OcoaILIu3dZLFwt2SJjkwVnZT2xgyyoLcVdur/yc56p44vT0WqUO/rpMi7DE+8tRdTxw9FVTiERQISHRk27+8QyttsGGiB9DA8WXs6e+O2jDwDyNAt+jQsmYSRyQ5oxnt7D5OnpVXhEC4aMyQ1lzh6Y3phz05hlv3UieiqhmbMmBTOuC4LjR03tCjtXSlDyKovqqAqQs3HmVrP1us6+tqphlyO10cIJyrEy8zet7I+4sqm6DQERVXLgRJn5vvaMVh7Ywmt/IdsFGaArqWkgp05IDqZ0vm9mYJWFKcN2Cfd+KhBlG+ULSGBCBSFc0Mkqkyu5huh3mmUkRp7nfltnid25nksbmB1f9FjGXgOhlMWWHM7ZfkEOu+qk/MjItFQEdjI3stJLlRUEcZmZ5ycyh8RzHKGj4WI9EX0fm7lyTVEomgjcpgYkCrGPHJwgfJesnHQlb+qqABO4iMj78i2kLwVkfZuXP3IG1hZH8EaQfqADNRJW7a56RWhoLA+mBVdx2JZ14PUnfN8jxMhbkA6V5sJeR7wMm2GRWb5Wwe8DXb1LFk448bIkbR3pZiQ3Y6A4fejxst6Pdt81ZOB3InXRwjZepdEEHkAzYU4zcfW2dTmchq2RlWQ13kehx1jxeNhWvkj2dZXomopSX/D6H4UxeCLNkWdOVTbT3HMx9nqzZq3rE6oNN5d04gQUaD7owjzu89bVpc18YQI5nlqzh3RqZtjz4vKUNFP1ev1MOVmZV2XOr8B7BcZ12GBlc1XczK3yOuq026VfJCdTlHRAKr3cuKIUtUksnNyR8mfwoAXnzm7Qhi+LIJIzlSFQ+SJDz/h4H0W7YlllSeXzMdtxGpTjUorvB6G126/HEByHYsKzYraKYKO/PQwvfxGp23IBr0xAz9Z2WB7nVIn6tnIdwZgzbYWrXnm8TBbudpApgzT2XO9/YREuvJON9R24ogSPNLvkOGygpof/Kl5Po/ydIiD1w2rIPK3KT3LyxhiArnCgIzojoShr2c4hfl+1HhZr+voa6cacideHyHI6v04Aadn5p5iGTU1h1NWKBWbI0XLbE0IFsG6Pq3CwI5HZvLIUgzKpxNOndyTeo5dnDuylOxH8zjKas/osDABzry+q7e2nLBTMF0ab7fovlVKkA51ugjm+c89/7tb9YqVcgayAs1CkfyWkwhqZg7RZkrROWcLJyywHDqbvupdgeP5RxRkp1MU057qveyywDZEokoWNF25LDtNnTJ6MB6aPRmXjisXfz6qFDMnhVGCTqmcod5jaCiYdsJFhX3rGB18zdRKjC4AaWyiuvKPar9OyZaEkWSHpb6nW5Oqgqjhly1U7IYi9ElORhyKPhjQV5jH99OlZ0Yh0LDKBp09l8sLHbnBYQ21pfQcq6xQ4YIxZdpt4HXD3tx5KKO+o0xOUu9JsVuOHFyQdZ3O0gKxfuX3srT7jSfWoPW6jr52qiF34vURgh0mPBkYkjHmd0yvRFU4lIr9nf7AamlcOocTT5yMEEHmUf7RjCp8t58encKoskKcc9ogV1gN50+vxI1/3CDNmbEajE5CMedPr8S6HYfSkkIZ6BMDrwf42VXnSPtRFMMtwgVnlGHNthalImfX66vKtXMLuvkxTgldRFB5useWF5EkDnk+j5AtbMqo0lQ7nIQVndNf464w4IVO4BA/pf3ZVedg5sNrYNalGIDRQwpTOVPW/ll41Tn40sNrhIQ0HLqeR7PeaYcF9t09bWjr7EMskUB5cRALrqhUjuPPrjpHmZ/G84/uvWYSVjU02z69EkH1XjossGboGFU6J3eLahqxhjBUfN7jdfDmT6/EWxbG24CPYWG/DIJiTVPvxwCtea5ybDVEolohakCSzY7DKj9F5DGycagKhzBycIHy1EzWrnjCwMr6iHCumfcTp9T0KlBr1O9l6CNO0f2Sitvfn3YWFmmwAGeDwn7nkjUKgcLDghBO0Z5rBt9jAbGMpCAKtc02PaMhEsX86ZVCRmkZemMGpo4fgkGakSciue7zJI0+0bMnjijJej//ztQxwvnyb58amdbOQsKhaL0+KF+d43yqIWd4fYSQTehBuCQfoaBPuhB1Qxmb2rsxb1mdbYFChQPJPMpzq8fC5wViklSvc04bJBUGXBhe/8Q7UmINjrKiPOHGmufz4AsThmkZjDJWLB5OZg1lSP3PMDKS372e4xufW6yYKsi8vlalijIaByJcRkXUwvv49S0HXaP7Vhnv21vo9xyU78PBjkwlylyzxm4/mcldRpYVaoVPmcfTyq3g9QJL/vU8+Xpm6aPs9QCXnlmeYoObVlWBm5+qUxpfZ0kUFV4i47bl76XJqiSBxvH+j7R34/Zn6jOYy5yipy+R1nbzWnYSJq1SwOwqaDrzQ9YenbXPTFklVeEQXrjxUrJ9M2fOxIoVK8h7Ue932/L3lO+hOsm0K8e6jsVSZRXMJw/m+9lRlCeOKNFabzKYnYl8rt17zaQ0EqgTDcroAoDBhfSpwohSdd5cttjb2plxjVoTDMCY8iLhZ7LDRutJpDXc0OcFPMyjNNLdIH7iuo8T1O09rF1WAugP3TO9p8fDMGvKCCGbtRthhW/uFOcLPv7mHnz1/OPGl2jMrdcbIlFHRGUnG1kbXoyxswGMBVAMoAPAdsMw5CXSc3AESgEIBX0oCvqlRkUo6EPNLVMBHA+/sm40uidD/Fjb6emBFZQArd1yENHuPqnRBeiFYMryDsxYWruDTCI9FkukCTK7TI3aCoOAcaw3lv3pkZ1TlaDfg2lVFcJ5IlKqjnT3CT1kdkIydRUg2QmETh9nc2I746E1QsNCxszt84rDusxMU3bzN83kLjqRPuZNc1FNY8aaisWT1zmToRV31zRmeIq5N5jLFQ6V8ZVv8Via6ZgpR4ZTVlQ7YdFUSQa7p1PW93L6uRk680MmB3XWfl8/8yUnB+Hr8L5Z52asQ5nRxSF6PyoHpbw4D2WFAS1l0e7pcGfv8bIKoj3LrqJsN9dIBz19Cdz1sj2mwROJ80YNJj+TladwCyLlWhZ5YXXC8XxCaU2/2HHm1yT7b/p3Y3Fg6vgy7dMkCrxNMmxqOiKtdyVDR09MOt/NEL1nb8zAqobmASvZ8i5RJiVhANc/8U7qgIAyqHrjhlZu56kMx4YXY+w7AP4bwGmCz/YC+LlhGL/Lom05WEApAE99+yLctvw9qVHBFWDVKQ1fbJuajiTDo/pPX4509WYshJ6+RCqpM5tFKav9onPUTlGl6j7HjG3NHYhKaJvNyqndEKRsWap0Qon4aVpv3EDAyzBxRImtmiv8VE9WlJkbX1avscxDplPTSPf0UHYCodPHTvPzqsIhR0Keyv9S0XB7WPKPKLzPTO5CMWmFgj6E+z2fu178NarCVwCg64PJ6oZRm6X1NzMmhTGmvAhLa3dgZX1E2F8fRI4AyJwT0e4+0rhyyoqa7YmrmTXxZJZPmFs9luxPDpkc1O2HTU1HMtbhyvpIWmg6AMyaNQvLly+39Q4AHUp99vAQafRb4VbtKKfQDVc81pewJS+c5F6dKMicDNmGeXlYMncoumczukvHCou7ixjuZGtC1wkn+h1A14Tb29qJ17//ae37WaHbpqPHYtJizrpQzXdqLW1qOjLgJVtEMBO70Q5FQ6sP3ecgdg+ODC/G2L0AbgPQBuAxAJsAHAVQBGAigKsB/IYxNs4wjDvcaeo/L8wKyqfOKIMBZNQAkRkVZgVY5Tk+HtaTPrGpSezG6ZfMg6izceluxDqeysI8H8qK8sjTQ7OiaTcEyUnRZJ37ArRA393apQyZMuMLE4bhodmTSeZCs0dKN3RKx6iyc6IhO4FQhTJlGy5BsUBR8DA6NGmoKXme6r+ltTuE7Ffm3w4lThHOHVmaUma7rrpf2VbZRnWMONLrEVznG/ZKgrWrpy8hnBPU87kjQQSVEa17kkjlp6lYE08UqsIhTB5Vinf30MaxTA7q9sPRY5ksgwYymU7/8Ic/6DY9DRQb7JqtLbh40d+x4IpKpRONehcvkxcy56D6yU7IoU644ld/vc5WGBS175QX5+FQx7GsPPvhknytMHsRSgv8rjsZRCecXV2fwicXrXbl/kNDQUeOTr7edWtI2YVum1o6jsHrUq29TU1HyNpj1N6x+1AnyZKabd29ySNLtRzq1Hzvixun7MmwLmyzGjLGLkDS6HoewCjDMP4/wzAeNAzj0f6/rwcwCsBfANzOGDvf3Sb/c8Fa56R2awvW72rFfbPOTWPRotiazh5enKbg6niORcJBJfRlLHgqZjmudBYHnR3A8oKlKvY6MysSxSy1t60LC66oJJ9l/pWKqdGMhkiUDGHUhdNQInPIlIzRy9x2ap5E2rtTrIUzHlqTplyLWJvmLavD1377prJmkZ0TDVndJkoRLw76HLMwmTGuQpw7QMEwkuMW8GXOt7d2tqbNUxFD3tzqsRDltZt/S23P5uu/+tWvUv8+j2D3krF+xYjYQeq6CnZkzN62LqHSqGNEq8KQw4OCmDkpjMXXTtZeyxxuMWbqoljBXiljt9Rl8+uU1Doyr1nzfLIDan0aSMqW7/bXjpSBkrshTXYzURuyrScmWruVw/RP1oN+DxZcUSl8r6rhzk7aOQI+Jry3LqI9fdJ+8GmyNJpRNTyUwQT6q1/9ipzDoutLa3eQ/fLWzlbbjk7zetetIWUXdk5rVeUjdLGntZOc19TI8XBNK9youzd/eiV84uh7LeiOwakcguhkJX4LwH4A/2oYhjD7rf/6bADN/d/PwSF0C21WhUOY/cnTM37/wf4OrN56MPV/HRpjWdKqDKLf6S7UqnAIl581VPEEMaZVVWgLA75BUptFtLsPMyaFcUaZOGHYrJzKDAArltbuyLrWxNMb9pGKnpNCs5XDi5HnSzKN5fu9uOWz41Jt16EyThjJfB5RP6/sN8xW1EfQQRR+NbfZLr02ReMtUsoCPg8mjyzFtuYOLK3dkZWCXKAoamyFgWQI2MTwoIzPemPJE0RZe3a2HBUya/GcP4AONTRfnzZtWurfd0yvhN8S/sgY8NUpI8h2UHNXphv4iBBLn5dpyxjqJCpckq9lRKuYYDl9+oz+tatLlexW4V87oMaZ40OJY8e69gsD4nmsUqL5uJnnkx3MrR6bQXdtxV0vy3NbRHL33msmaYW8Uca0k4LWKnRKEj85Lb95rlFzUDXuKiQSSbIJ8711SsdwxBPyXEknhpfonaZNm0bOS9F12Z7XG0vYqnMYLsnHvddMSq13qoaUbikACrbC3G0+KuBjGWtLJD/N81o2t17fcjBD13BjnVSFQ7j982dpf98KJzVQTzU4OWK4CMDThmFIA5INw+hhjD0NwHlA7D8RqONbWQyu+fh4WlUFfr9uj/C7i2q2YOr4oSSBhqjulej4+bLx5RiU70+SXgiUaZFQUTEWmt95WlWF7aRlL0sqV3YT70P5frR0ZE7hUL4fDZEomo5ketj9XoY7pqefhumGILnB7mdOJLWG69ktNLuyPpLGrNXdF8eimi0YUVqAMeVFeHPnIa02JQxk9HNDJKrFbmeeL04JDKwQseS9ufNQKrQhG0p5ANjsQLHe1HQEuw+JGZo4lTnVnp+sbJDeF9ALeW1qakr7zLD4Aw0DuO1pmiUw3+9Ft0CRDPq9tkNPmKTNXMbwe23c1y4M0wwFfVrjp/J6//2D5lRIjZ1wQqdkH9lAtcZlualAJhW3KIR18shSvG3J1bS2AcicT/YgFwxOcp2e3rCP/Ky0wI+KUNAxYY9TbJWMVYqW3wLRHLRLvGNFLGHg7ppGPP7NC1L3bohESaIgEaz9YF7zshpfjImdMyJdoampCRNHjBau94kjSoT3kPVLwMsQ9Hu09AkrS+r4oUXYsLc985lD7UU8WGGHmGVIUZ5QR7HC52G4YuLwtHQSlfzkOXAiPY5DRNLhxjppiETxy1XOyw9MHlmakU/+UYMTw+t0AB9ofrcBwHUOnvFPBVkODCVc9rR2Yle/Mtd4oAMvvi8PzzDncKkSxSkleH5/crUon4hSkqkFuXFfu/CdeS2d17ccJE9KzDAkz5AJg9MHFwiF2umDC4RMPwBw0dghrhOIiGFA5O6S1cmSCXTR2FBe5btebsSUUaVS9icrrP2sc7pnbROfl4tqGlN5dFRInApWBdP6LtkoyKJ6XCocPRaTqpqy9siUUN6WaVUVQiXaHGZ3+PDx3KCltTuETKEUc2ZDJIrRQwrwwf7M+XvtJ0eQsouql9MXN5QyhmPesjqh4qDrOVZ5vTt747j6kTfwwo2X2lrbbivqVuN1WlUFlm/Yl7YWvjplhHCcOXSKzXNQc+arU0bgjumVwnpf5hIG5vlkB5RsNUMVMmgnPxAAfF5PBvOmFU5KBqggk4E6c81MlqRbI4+ClaihKhzC4muTubw6tzX3gx3SCp+HgTGWRjxinkdmHD58GHOnfxarNh/Q+v7c6rF48f0I2S8TR5TgEZNzt7WzV2rImOVwYVA8B6nrujDrXxv3tWNvW5ew/UG/R6uGKZDM0zLLbPO/KflZmOezZXjzvqHWSUUoSOaRWSHTD3weJg1fD/g8qVqDuuN6KsKJ4RVCkjZeB0eRpJn/p4JdD7DqVEjEdmadm6oFZFYIdDy7F5xRhrq9h8GQ9DCYGa2qwiHce80k3PVyI1qPHkNZUR5ZzJRaqL2CBMmevgRWNTTjodmTMf2B1VqGimE42zTbCIV24752UnmiEsN1MK2qQrpJpEP/KJ231SrQe+MG8nwesiAupdC3dPTg9S0HhZ9RsPazTPksDvqkLJhmT5Y1od8JXPdky6pcE5DlzajaI5sJnC2R8vY/vWFfiqhg6tTjiqfs3UWebZmS9cJ7EVJ2ybpJlynQ6Ukol8EtHeo1a6aR1oWbirrIkLAaRbVbW7B2h/wU+roLR2orP7I58/g3LxAWmzXnnJjnkx3orLv2rl4ysR+wn4N8uLNXuSe7deLuFkTrzsOAYYOC2N/eYzt/pbM3ntGnY8qL4Pel16WiYO4HO6QVJQUBHO5M32sSCfFvp06dil5k5jZRuU5VYXkxa2vNNmuUhwh8flJ7PVVbSgXR/AOAmQ+tyfju1PHlKeNCC5J4b9G8Dvg8qNt72LYhv625A/fNOld4vzdNxdZVUSUyGXDxmUOkp1nx/rljHteJP15l70VOATgxvOyqHh/9gEwbcFJUV6YcihQU6vhYBqvHitqERAL/7V2tGe9ophqXFTOlNjQVxbbuCRFjzjbNI0RYTl/cQF9crCg7JRni/ZVtjpcI5nG1EypVEPAKT29k7y+CqJ+psfMw4E/fvsiWQpVt+JbbnuziPJ80PEOEmCQUR9WeoN9LMmnx8BuKdth8fcmSJbj//iSzYaGEhMHaDpWSReXVbGvugM8jpsLnZCE689UJlXs2NNK6cFNR11VkqRNEACgt8OGBV7dp7zuqOSOq2xaLHw9ZM88nO9CR67yemF0KbAqxhIGrH1mbMjBEfTMQJQMKAl50Cdaul0FqWALiOZEwkn3jdBux9mny9FE97woD3rSC5nb6vyjPC2tt+VgCuPOFjXj2xkvSri9ZsgRtE2dL550VZUV5Ql1ItFXLwlE5uGykZOSe1i7l2FlB6YTDQ0EhC2dLtAdV4RC+8sharftHjvSktcmq3/EoIlXNTRXGVRQL14nofrJ9W7b/zJoyAvOnV2Jp7Q78dfMB9FjmZzyRrBv37NyLU9f6HEShnGw4o7lJshX+RfUHSfbDfyo4ST5UEQtwBeW+WecCAFo7e223y1xPSZYUrtN+O+9IEVCIYrbN76zLwuX1sNQJXLgkH3k+T0airAh2lWcgSVTiJHk+2/pdFE6WRzZcki8lIBCNnYcBi6+dLB2TgcizsMM8qQMnydUq5j9Ze6wbjxn8N1T4Y1e/lxtAmpIsY9e0tsNp34+rKCYdDXYdEBSRCoVsaKTttMkOGYcMbuR/tndl0sDL9h1Rvp75uqpumxOjC9CX67I+GUoQ/8hWptXAoAiq7MwzFfIIEpG4ASURC/X+2YRUWe+pO+94AWquK1D9L8LeNjGFff2+IxnX7r//fu16gcfvL5ZlIlY+6t5m7Gw5avu+KlD60i7Cec4dE+992G7rGUA6qRUfs9ufqcfc6rGpee0kcse8R1nXCXU/an7J9p9VDc2p+1P7Zr2lX05l9kIKTgyvvQAGI1mvS/VncP/3/2ngRHnUUQ7NBpMo9yno90hppXXqJem2n0pYp1gNRV5E1TtzxUYFwzBSJ0qR9m4ciyVSJ3Cyjc1wSNXqhOXKDcUKSJJ7uKHoARB6YnUR8DKMqygWsgTy8R4WCiJcko/RZQWYOSmMlfMu06rPY+e6DtxUkAFo5R1aQRkaDFC2h5qnjCGVb0nNZAPHFbyZM2emrlMkDH4vy2iHk77n69gtw8su7K63gI+dtJAygDYk7IDqUqovKPGnEov8Y/N8sgPreqTY9WTzjtrn7LKdZSOXdUoJyGSFU2dsNrDe08kzevoSYIA2NX2cWOyi8MGZM2eS36eUcBmhjHV8ExqCh0fC2LmvCna/z1tpg5QRr285iJX1ESGplXWu6Y677p5pd9/W7VsqxFQ3FPVUhu1QQ8MwRg9AOz7S+M4T72Dyub2YWz3WUWiTTpgD5cUtDHjxmbMrMLd6LL7+u7eEoT8lBccTQlWGFdX+aE8stblQHgvrO6rCLlXvXBUOwethpDAGAK/H4yhEbVC+X4t+2IqN+9q18yg4smWl4uDdcN+sc7P2xlKsjjrY29aVCu8wjykAIenKI5ohOwOVZ2ENaeNKk5OQIidCPs/nEZ5KDSnOU4baUfO0pJ9988tL10rXB18HK1asSF2jxr6kIAAg3VlSEQoi4GNKQgRrQVQZsqVkVsHOevMy2CbWAJyFlFPQ7Q0H6YX0vkPcjIdTj68oxgZBsebx/fczz6dsMG5oEQ4d7UmbX6o1T1Fg+xV7RcazHRo3umMfV8gKmUJOkZ9kA2uf2mHYM6M52pO2dzvZ20REMCtWrMAnf/43oVOwMM8ndOLK9jHr+Bbk+ZQFkFn/ArBzXxVkofei6cpPSu2s946emJRJ2DzXdMbd72Xa4f12923dvi0jWB2tc6ekIEAwVPuwX+sNTjychhrmYMLOQ52pY/hpVRW2Qpu4Enjb8vcAIKMwMgclpLt64ynFcUy5mOrUfF3lnaBCQSLt3bhy8RrM+f164eL2sEzBrjpd0wntmHR6ibC9Zjg5ZawY5MzLvLetK+0Y/8rFa3DdY+ulp2u64TUqxBOGa/WCRg4W1ylTKYGyuiDZ1vhw+3RKhGzrL9k9rWEMGFNeKPyMGgMzZGtaN6RuW3MH5syZo3zuyMEFwoLtAMN5o+QMk2dbCqLKxny8zSLUdmFnvQX9Xkfzy826Tzp1mjwMuGO6vdo3sn1nCMGAyJUa2SkqgLT5ZIbqJIiaX1PHl2uveWoPk9UHs37GkPS8uxU63tOXwKKadKZYlY9GpsCr6s/ZRbGg/IJV3uqC5/rwvbs4SPvvqbzoH82oyrg2Z84c+CVOGZHcHlIYIJ9rnfuye3OE+t9Ftj/adQSK5BEDMIp4xq2fGwdA/1SRQ7Y3WXPB+bhTPRKLG+RJrnWNA7C1b5N9axkz0RwRXafud3qpen89WcgZXi6Cs/LpTkI7SiAlpM0xxxR7mvm6LMTPHCaWLygUa4COMR85uEDbWLRz9P6zq86Rfh5PGI5C1PYS8dWMQbqRWIWbgWR9LZnyzgWdk0KTImRb2BOgWQ29HpYWIvjw7Mlpc5kSctuaO6Q153RBGeM6oT06yFZhtjuGwwcF0U14WXXqFVHfaevs1V5H4yqK03JyKDnRuD+Ku2saM/qnN5bAaSX5eOnmy8i1YY3zl+boFGcfWicDz/nUGaoCSaK3DG7mI+p40BMGsHl/B0oL9Ois8/1eaZ6rSqlRvZ8ox0u0n814aA1Wmk5uROuvN5bAoHy/Vm5VQySKI919GQpj0O8hTzO8HoYXbrwEU8eXp35nIMkU6cSJRfXNmq0t2vdSneq5FZ7OESLWrVne6qwXUbuDsoLYBvDw7Mlp+dcP9xcst+L+++8nLbWjPeIcxn3t4hyyIUUBLK3dkb5faLBj8VN/Su4OHxS07ajh+3+1Zf7tau2Cz5M84WJIrtn508/CDZefmfzdcHccjiKnOB/3ImJeGIBQH6V0VgDa+ZHU/jPKokPO6Nc/VHOHuh+1754KsG14Mcbet/mnfiAafqpiU9MRbWYkO0rg3OqxpHeCh7/tOnRU+Ln5d9SpAnDco7S7tYtMvqZAFTgUwc5RfVU4hLDkdMrrcUagcIx4Pw+c1Y9SKe9V4RAuOXOI7ftSyHZjppSUWMJApL0bB6I9mFs9FjMmhdMEqowUhRrXPa2dWp4zSmnJ9pTKjGwVZqqAJqV8HDjSQzJoqsJeZN85eiymtY64Z//u3/xf6loFkVPU2Rsn2a54/xQTdWzs5I/IkqvdwqqGZq3TSb+HOTLo3cxHtEM4IXKIidDdF5fmuY4pL0qxS3J4PcdPWMncnP7rjz76aMZnFBPfzU8d79ds1h+XA+ZC8gxA9fhyPDf3EjIf0jAMVIVDGJTvJ2sh2oGOExSgHXg+D1J7LjX33M7x2t/PfCeDjG0u3+8hncgyoiqfl2FMeRGmjCrFGUMKMWVUKXmK/+ijj5JsxzGCgp7K22rp6E3bL65+ZC26e9X5udyxSMndPocJqlXhEEKC+RdLJE+ZzxpWjM9VVWDq+KEAknO93obDksNqPKtIrcYrCkJnQ6xGoTAglmFlptNLrhvc+0qy0PLwQUFy7lD7mZ26hicaTk682gC02vgj5q39mGJPa6e2gmhnE6oKh3DZ+HLh93n42zEiD2PnofTaE6JThWyY9wI+hmh3X8YG4gajXEMkiv1HZKE4zNUQNQNAw35npykq5eGO6ZVaXkUdZLsxdylqS1HCdFpVRcY78DGdWz1W+H4JI5OUxI4x5WZYF5nwa8phlKGcEPJUPkfCoBUT6xiIDFHKm9d1LKalsHPP/nMdY1PvJ1MdqM8qQkF8eelaRAQeZtGaljo9TgD9r64hfSDa48igd5MtU5dwoiIUREQqC9MhWyN31zTCWuUgnkheB2hGPh6yd8EFmdTeVJ+b1382BitVvyuU70dVOEQaDvy6W6eUMieo+V7UO33i9KRjzyr/rn7kDcx5bD2mP7AaR7r7MsIjAz6GKSNLHNXnEclgK2Sn+X6vhzzJ6JWUy/B7PUo5z+Xen3vPIQ0efhJlhe6JdW8soZXTzeUftT8edUCuxEHNs0h7d0bfJIvc2zPygn4PFl+bHqGiJLXSOAU0t9uNNbT3sPiUkl836wa7W7sQae/G7tYuUj6rwqJPRdg2vAzDuNwwjE/b+eOkYYyxyxljBvHnQst3L2aMvcEY62KMHWCMLWaMZZjGjLE8xtjdjLEIY6ybMfY2Y+zzTtongiz/RQTZJiRSwuZPrxTSdKucMDqKjt3Nh1OKTx1fDoChdmtLhvBwwyBaVNMoXUDWgnraVMCEwEkYzil7VcoDL/iYLU4UjbyomK61HpmHIRXSJHs/673sGFNuhnXJchh1lG6qgGafZJPUYWeiDFGqBlg8YaTWF6Wop7UvcVzxUhUBFYVxGYDQMRMuyReu6apwCOVFYmVJmfziAnQdE3bktRlu5yOa5dfvrjtfaNQ56TVqjVDU2mu3H0JDJIpuwgnH50B3d6byJOtzzoSbjcGqkgOU4cCvu3VKWRUO9e978nu1EeFqG/e1Y87v1wtCLo3UPpo8eTZQbcp9e+HGSxEuLRDOA2m4Xz9U8vKoxBknIy2Rqe49fXGpnDfLvX0dCXLvPX1wgXDe6ORt2YFKNnb3xR1FWgB684z3jZ29zcyOa41QUcmjrRrPMbOuurGG2rvE5ZD4ddkhgEg+U2O2v33gIyuc4qOQ47UYwL9b/mznHzLGzgXwKoACJOuG/Q7AtwE8LbjXH/q/80cA/wkgDuAlxtil2TRwzJBCZf6LCNQmNK2qgoyjtW72Ooq8jmyiFk55cZ5QEfvddeej5papGJTvl9ZIybY2ClW/g8Pv1Qu9sUJno7J1P03lYWSZmGhBBzr047rQ8RRaj/CpUCJzIriqPhuHjjHFnQ9NRBy/k1M/mbGio3T32vRCArRC2N2XUNbPo2iU+dWqcIjM37D+gvet6h0uG1+eYVBQtVpCgqR9Dr+PWJtOK5HbQDaENrpKj9t1n8z3FRl1TurvUGuEKjoaSxj48tK16CMMfn59xw5xODwFPueyMVhVSh9VIoNfd/OU8g6BE9R6LzJcLW5oOfd6YwZCltw3am7KTp04VPLS56HXi2y/kLGUMmKtc0NcN9Km61hMnCLhsizh81RG1GIlUdGFnZBiO3ubh8Gx/NGh2Df3sBtryEOMGb+ukr/Wz6l1RjmPTgU4yyw+sVhjGMYzks/vAnAYwOWGYUQBgDG2G8D/Y4x9wTCMV/qvXQDgWgDfNwzj3v5rTwDYBOCXAC4W3FsLv7nufEyYMAHzltUJq6hTi4iiVF8kSHA306ObaT6pZ5qhQ99MUYI+/h/JkBIqb20git7aAZUcqsKU0YMdVW8HkiEfE08rwdbmDjAAk0eW4o7plVqCL5ttorw4oE3xqoKOp9AskhsiUby+5aDweyqqWpFgVpVdsFI2W5HNqR83VkRkzcp56+C0JrmhiH/H17QsTEuEeMJIUeLrFQNnx+WQ4h3mC+aykzIZ1HPYCQgC4bL1ysVr3KNgH0BYqbKnVVUI2yWj7rZGP8jWiKyot0wR5iGIV199dcZnPB9XFA5pDl20lnfQhUq2lBXlCUNhea6HrIQJVW+Sgk45lGzC0jiscoGaAzqpRyp5WZTnJXO7iySGl0x5DwV9whA/buDo6glDQ0HxvHH59DwWT75/jyTHXeUMpmCdM62dvUIDfGgoiLnVY/Hi+xGtcY0bSEUYUaDmtw7Fvpl1lRMX3fVyI1qPHkNZUR4WXKGn+6jAI0BUcs4qn6l1lk2t0oHGR8HwAmOsGEC3YRgxy/UQgM8DuJ8bXf14AsD9AGYBeKX/2jVInnD9ln/JMIwextijAO5ijJ1uGMaH2bTTSR0iUY2hNYoEd9UzrdDxaqg2Et5G6wKuCAXtK2Q2cN7I0n7KYTGoUCwVZk0Z4cjwOm9UKTY1HUmrcfP2rlas3noQc36/Hq1Hj8HDGCadXoKFV52TIZB0qKNhGEJPns/h6Z4IOknC/AhfZQSJqGpVSoxqrVCe0FDQh+qzhioVI5Ui5ciQgLPkalmYjqp+npcxYf5YrL+0gC48Rvy4HJJ4iUsL/MJ+HVIoJtWgrgMglbgTtSFWhUO2ja4TFcZrhqgulHlseZ2oe6+ZRI65zwP85buXaRsPMsNLhvNHDwYALFy4EL/+9a8zPp8yejAigjaec9ogR88zQyVbFlxRie/201ubseCKygx5YK6F6LQmm8qApE4N7cDsiFpauyN1UmQXDHAcfg8cHz+RXJXZPlQdQm6I69bcI1tm48RLVRMUADp6krJJFhUw0Of1fKwWXztZOJ9FuLumEY9/MzPvEpDP78KAFyotyLwnWos0R9q7cfsz9RhTXqRtfFFj0Bc30BCJKnXaCcOLLb8jTu9dWH8DhY+C4fV7AEUA4oyxNUieWL3T/9lEJN/hHfMPDMPoZYy9B8AsFScD2Gox0ABgff/f5wLIyvDSVTplWFq7g1QWREqh+ZnUpqy7xao2EtECDvgYAj5PWrihm8rLHdMrsXbHITLRVM/bnwmndVI+iESFoZWLarak/p8wDGzYcxhfWvIG/nLTpVoKf7gkHwuuqMSqhmbUbNovzBmiGJ+cgCJtMGN3axfmPLaezO8BxGOt49FWrRXKExouyVfeuyESxdWPrE2NU+OBDqzafAAv3HhckXJarPloj/2i2z4PIxVdHs5Jtac4z4eWo+KYeCvCJfkIBX2pE5NVDc3CvpXNI+vc5njqH/vI6z/6krjkA7U2na5ZJ1ApWwGvB9POGeZYXrsBnXArXqok3+8RhtDEEsDOlqOunYiLEPB5cMf0SgAQGl2A3rqye7pkhky2cBIBqzd+THmRVB7I8k2z6c+Az4OYDScDdWKpcnzpwID6VERGuCRqB1fgZfrFyLJCYUQON+R0izhTDks7e6KOA5piTzRjsgPWY0DtwORojiYZKFc1NMPnSa5tFWSncLL5PXFEiTRiyrx2GyJRYZFmu2tFth/y+zw39xJ8Zek6ofPuibf2pij3AXqd+a20racQTmXDqxfAswBeAnAIQBWA2wGsYYxdbBhGHYDh/d8VFajeD+Ay0/+HS74HABLqF4AxNhSANaM2Q0urCocwt3psamNZWrvD1sZCKZyywn18M3rp/QhE9olb6rq4BouBqeOHYFC+f8CUF1n7KQphFZyGQtqh2Y/FjdT48/kwNBTMMFSBZGLp8g37cPGYwVj57h7Am3mS0NrZi3nL6jBheDGeeGtvmnIhZS7KArVbW8j+Lw768KdvX5Q1oYAITk+kgKT3z9q/vbFEmlfQqZPESY5Xcb4fPUROhzlXiwo7btE8me3o6Uvle40pL8JDs4/PiZkzZ2LFihUAIN1sqbBkKvRGFpJDKTo6CpBbOPf0krTTaSuGFOdpGfLZONNU0JVFr2w+IP38rpcbteWA38ukhDBm5Pk8+MKEYWnvbZ5PZqjWldPTJQ4nY6GSBwMVLv/J0YOl0RpmBP0e3PLZcRlyvSocwrxldVkZXRzZGpKUAi/bnzuPxRDwMfSaGJcDPpbSZczz5a9vv4/Bw04XhotScn9wUZ4y1YJDZ7b7PB40RKLI83nIk3nufJBBNE9189k4g6ydMZe9m2x+3zfrXKzavD9tfDwMGFVWiHNOG5S2vpbW7iBDH+2slfyAFz2ENcnvUxUOkaRU1hpr1Do757RB2KndqhOLU9YkNAxjnWEY1xiG8ZhhGH8xDGMRgAuRnGO/6P8az5AXaTU9ps/5d6nvwfJdEW5EMh/M/OfPAPDGG2/gf1f8HZ//4ZOYever+OKDtUlijP3RZBHJB1/Hqrc34bHHHsPzzz+P9evXY+HChejq6sKsWbMAJDcyAOg+IJ4qQ4rz8OVfvoB5y+ow49++g66uLixcuBDr16/H888/j8cee4xseMIApvz3s/jag6vwu2dexpIlS9DU1IQbbrgh7dk33HADmpqasGTJEtTU1KC2thb33HMP2traMGfOnOSiyFgMBrbva8a/j+3DJR21uPuqs/DjW65Pu++CBQuwceNGPPnkk3jyySexceNGLFiwIO07s2bNwrs7D+Iz//2/mHpXDf7lnr/grqVP4EfPbZAqCB4ANTU1ynf60f2/xTX3vYRLf/4yPv/DJxHw0PfM97gUCmUYeP/DNsxc3D8fDkSxemsLEokEBifa077a1V9DaVFNIwyB0QUAHd19WFEfwaKXGxFp78axWByR9m58d1kdvv2zX6fGyfz+t956K7Zv354x9woC+kuf6qmJQ7zY8vareOyxx7B9+3bceuutac+eM2cO2tracM8996C2tlZrnPjcu6DoMLxIpPoRAFgiSaFOvRNfTxRj29vbm9Pm3h3f+Toemj0ZoXUP4+6rzsKzjz6Ytp5E7xSP258bsW5xfT0AWP/+BwCS4xToOojJ3XX4zqhW/PvYPjz76INI2HheR08sJXOufPB1vLvzYEpGfPOb30y9U+c/niMjdEYVGcJxQkLsDfd5kCYjgON9ZRjizZUxZMg9XRkhknuyuXdm+zvWxx+HYWDBFZUZc4/L8s/96jVMvuV3uPqRN9Jpv5e8gbuWPqGU5brvNKZMzUoJJGsPJhlqBSvSMNB69Ji2LC8vyhPKchH64gnU/GMLdrYcTb3T7NmzyXf68S3X4+6rzsIlHbX497F9aTLi2/c/LVTe//PXK5Uy4l9v/AH+xTIWMxfX4q3GDzFnzhysrI/gu0++m5SNfVw2vot128W5qWs+SJ7iUnvuuIrirOZeXuRd4X0BwNvXjerx5SiOH8HnxpXg88X78atXtqTJ9Zuf/AcaIlH89e2NgjsY6X9rOCDX1G9La6f1nTwGfeI15+4/4oNIO4RzJEHLqE0fHkbcsn8nEsDNN98MIF3ufff8QSgPxDLeiSWSYdKi9dSwx0bkikYfdffF8S+PvIFAp3jOhP3d2Pv+uoz1BBzv12/edieuXvJGas/n8/T9Dw9L1tzx65u32i/tY7QkyW5Eey6iovMGoH1vIw4ePIiYxQjyMIbBHzyHh2ZPxh3f+TqA5Dht2nsIlIwwrxWV3KOiKgBgeAFS6yneLTbm8lgiTUbcMb3y+P7U378eJHBeUTv5nJMN5vTE4GSBMbYMwJeRZDH8FyTZC6cahrHG8r3lAC4zDGN4//83AWg2DOOzlu9VAdgM4AbDMH4jeS514vXnP//9Lfzg723SxTKzn+ZTBZ3j6KDfI/QQVv7Py6QnQfVbHcxbVicMZ9R9NxlE7x30e2AYcjr8gJdh68+/aPveNN0BEC4JItJun0FMfK98oQevtEAc+57Nc9bN/4z29y/+xau2agJZ+yubeaQLpycNE3+8Ch2CcLbioA8bfzwtqzbprDErpowqJU9dioM+XC7JWbv8nte0PboZzx1ZgmdvTBZqveGGG1LhYSvrI5i3rC5j/vu9DH+2hMZyXLzoVeGaCJcEsW7+ZzOuA8DY/3pReALvZcCOX1xp72UkkM2ThkgUX1y8hvxt5bDiDJIFHW+zGzLP3P5sQ8kAezLgK0vXCeckY3L99OHZkzFjUjhtPtnB9AdWC0+yK4cVo+aWqdLfqvafyT99xZZM5fKA2nuylW9fXroO7xLr3vq+snc70t2nzEe+fPwQvL71kPQ7qjn7yZ/9lQxr5utE1EZZOBxV7sYsm4DkGpjx4OtIMHEeM593Voz775e0T27t4LxRpcKxo9phBjWWlC5gBRVOLMNLN19GzlXZ/L7zhY3YsLc94zfW8QHo9/IwYOU8+vlWVP2whjxNNL/Hp+99DbsOZe59ZwwpwGu3H69S1RCJ4ksPv5EWvujzMNz3+TJc9ZkLAeAcwzA2azXuBCGrUEOW5Ar9NoBvARgDQBT8ahiG4WZI44cAAgAKcTxMcLjge8OBNOKy/QBOI74Hy3czYBjGQQBpbhBOlfrUOx+ip0/utbRDUWwO1Yj2xDIWKxVTKzvCVf1WB07zYnQUaCqMQQWdqCWq8CYNdXCmOZ9mwvDitBwvDp+XkTHobhpdANDSITeirGMgq9kiwtTx5QgNYDipCE7ZzyaPLBUqKk5j883QWWNW7G2jDaeOnhhW1EfIcCsqtLG8OA8XjinDtuYObDnQIZzP9fuOpP595513Ajgepy/6/kVjh5BjejAqDpWkrgNAwCdmSQtQNPMOoApdU5UHaDzQkfYb3XAgN1lbReF5PEfvlc0HtAtOL7hCHQLFQc3Jknw/Lh1Xjpc37hfmYfBwRj6f7CKbEGJVSKBdmWqWBxecUYa6vYeVLLW6zqCGSJQ0uoDMUh0UacbGfe1kOQ0z3tzZpvxOtLsP0x9YTbb76DH65Ir/RrT/S4m9iI3WLJuAZDgoZXQBdBitz+NBn4MoBBW27BfX6np6wz6p4SVj/w14mbK/APs06BQhEocs/Nc6Dhyi66Lx9zBg8bX2qOwL83xaBEsftonnvfX6nS9szJBVsYSBh17dqt2mE41sDaJfIlkX6z0A/4ckrftAYwyS4YFHkQz3iwE4H8By/gXGWABJsozlpt+9B+DTjLGQhWDjU6bPHWHvoU6AyQ0vOyx/ZoVz+gOrtWmvddnCnCoNTuh4dWP6nbZJhyrf9r0Vp8C8jpm5/SNKC/CTlQ0ZrIZLa3c4PrGwA1kNFtEYyCA63dKly6eeLzuRcDt/Zv70Sry181BGXsF8jdh8FexuikOLAzhMFIw0g3SIEHMx4GWp7475rxeFXzPHyL/wwgu46aabpHH6H0oMRJ0i0GY0RKLkZ05LQIigIkbQZYGzW7jUbcp5kZNhxqQw6WUWwU6eZ7RbbKR09cbx0OzJOGvzAaHhxfMr+HyyC0p527ivHfOW1UnXfzZGmxUMSTkhOg14e1er8Dd28tNUBr+5ZxsiUdIQ7uyNa53o6BjnPA+GaresFlikvRu3LX8PE4aHsPdwN6Ldfak8NF3mPTOsxeNVJ3rWvB4OGQU+kO4gXfl+RJt9nnKuvbObNnBVJ9cTR5TgEVO+tw6bow4Od/UpiVMoJ6Ydue4GeRwAqX5lzsOmSJGs198jjMfGZjrE/2Qj2x1wDoBnDcOY5UZjzGCMlRuG0WK5NgnAlwC8bCQTCI4wxv4G4N8YYwsNw+Az+d+RZEI0F1F+Bklyjm8D4HW88gD8B4C3s6GSHzmkEPvEshpAdix/djYbWeys6re6EC1g2YakyxilSyvrBHbuXRDwSilqwyX5GUYXkFR6RIqPLmtTthgsofXW9eJzvHizPi21CrK5ASCrRHsKVeEQXrjx0gEhRLBLUevzeuHzxLW8skKln5iLhulUtjDPJwytLDTV3hk7diz9jH7IlDfqGYyxjE2fjzl1PzfZplSnIHbIUPhcUcmKE0k5rys/im0aswUBr3B8CgJerc/5fLILs/K2qekI9rR2ImEkGVR3t3ZJ17/TiAsRRg8pJIkrKCeIHfZDlQFvLoZNOUM8TM40mA16+hK4/ol3UntZQyQqZf8UhaVyKnEZqDBEs2ySMTlz8HlnBVmkvR+hoC8V0vn6loNCGWZF0J9JfsUhMvK48/D1LQeV7L9m/YkKiXcCp1FMQb9X6LAvJOq22Y1CEdUnlLH0mtkZPQzCUHWrr13XQDuVkK3hlQ/gb240RIA/Mca6AaxDMsSvCkmjqQvAfNP3/rv/O7WMsd8CGAHgewBeMQyjhn/JMIy3GWNPA/hFf77WdiQNx9FIhko6xrXnn453LTleHgaMHFyAiSNKslL67Gw2OtNsIJQG2Yakyxglek9ZHhaHzuKaVlWhXYywL55AX4xWku0WC9QJHdWFzwMMDYnjxM8bNZj8nZ0TPw9zHuIngmxu8H+LPsv2+W6+gxkyKlwR2ruOoSjPp8WGKXSIUN5BDdeteW3k5+ennkEaFpJ7+oiT5XjCwNWPrE2j6lca+i7mFSsdUzaeRYVTBXweXDimDAejPSecct4sPyjWWiBzfAaaiZHPJyfga3PesjrsOtSZ9pls/as87jr7BQenM6dk498/aMbEH68CkKwlecf0SuleplvfksO81qn7jiorxCHipMcNRNq78eWla1N96gQqh4DP4xFStJvna1Zhu4r1be5nSoaZ4WHAc3MvwQwiLzRhpNPy6+RnhoI+PCVg/9Vpjy6c9GFDJEpGSbnRNpHT9cX35af35tGktlnrdSqP8JRlDkT2hterAD4JU1FiF/ECgK8jGcoYAtAC4DkAPzEMYzv/kmEY7zLGPgfgbiSLJncAeBTAfwnueR2AhUieiJUCeB/ADMMwVmfT0LFDi/Dc3LMHZKOzc7yb5/MIvZQeBoyvKM6qXbKNXLYh6Z7Yid5TJ6lY5T1viERx+zP1aQvTw5KbtEiJ6YsbUo/MqoZm29TtOqGjOhgaSp62iRJlZca0nRO/QfnikzOnipwTqmY382fcBkUNT5ESdPUmwKA2usgxJE68zIWcqXy9rt54SklYv349qqurMbd6LBm6JisOLcsJ7I2lK8vK8bNR9FQFpWNK81lmj7Qr4TQugsuPmk37MxjiOMzjQyk8ZkcgNZ7t3cmwJepzfp3Pp2zgRDbIHCp2zPlpVRUAaNnYaVJIa7e24M2drbhoTJnwu1b6b17fUgbzWqfacM5pg7T2wGxgN8RWBJnBS4Xs8XnUEIlq1fUj5Y9kfVtlqk5es4cxVIVDYJQ2j/TTJZ1okuqzhgrlR4eDmpAUnEQxyYxtuzng1P2tfaPyWZrzLqmvWq9TRboHNsYoO2RreN0IYBVjbAGA3xiGIQm4swfDMBYDWKz53TcAXKLxvR4A3+//4yoGysNu596hoLjYallRnpIxSgZVbLvMuJIpRiJl3vyeOrHfxUF5qAG1+L3Mjn/0OLI1CrIJqWQwHCmGdsId8wUhHdnU3lEZ3nZyNszzZWgoCIZksckTqRzHqNNQyVTqlOReFga8+MzZFXT7CY9uS8ex455XybO5kvCtbyUP9avCIZQXBYRyIu2eFqiS2M3rQjXHmYN1R0G5HjROvKzhw3Zk+UCfLJkhGwNzjicl88zhfB5C/hlGMvyX+pw/h8+nbOBGzpa5/yW6cga4A01XNvbGEjCQSSbBADTsjwrrW3ogVv7yfJ60OaJyHljzVd2GbogthQDh8JWB18vSZfMkc5iJ9Z3v9+BZy/6kQ8TBHbl+rwdxgibfLOtU+oDMKWoYznQQEZxEMcnaLssZd+P+FMx52ORJFktf9wOdxjEQyNbw2oLkid5CAAsZYz1AhnvXMAxjUJbP+VhgwDdpFz3J5rZGe2LSkDDZxkEpRgBw9SNrU7HUjQc6sGrzgbSQpapwSBk+oko8phe/M4GXbVJ9NjlfPF/FrpEvGoM3trUIvUR9cSNjnka7+xyHBKqUCt0wWhlBiFu5YTo4QnhnnW6fpw8ukPah7BSK939QQj/M5/+tt96Kxx9/PHlRIieoMS0t8KP7CK20DA0FMW9ZnbRIOIcq78qunJStB1n/AclNXJSzqYNsiwHbhWwMzDmeKoWnpy+BPB+tWPX0JZDvF3/On5M2nxzCbs6WKF/k9mfqHclSc6FWs2xsau8m824ORnvw3NxLcHdNI1ZvbYGB5LpvIYqjU606FkukOThUzgNzvuqe1k7hWqeMPA6/l6GkICBsK3+eLomLGUG/B34vbXh5iTydwYV+W7nHVA4ztb6LgplMfyoZBiTfB0gablRxeLMOQBmsoaAP1ZIyIUnQsqlyWDF2tBzVIlZRsRpSkBnbspxxN+4vA1/n1C41KN/nSvmNk4lsDa9n4ZbJ/jGHapN2wyijEnHtJujqeqKozcvafpFiNOex9RmKWW8skcZqA6jryqgYfajF7/EwMmxHBq4UOB0v3lfXP/GO7VyvbBKtrWMw4Yc1wu+1Hj2GKxevSS3qxgMdpADU8Wip5obu6Z1qk3YrN0wFt/N1VYb8UUk4Cu//s8ODSOpqfn+zkiybR9SYThk9GBFCMfN5Gd7a2ZrmRAn4GOmxlL2T28aMas3YpUI2ww7ZghuQjYE5x1NH4VHlxvq9YmOePydbowuwF0ZPhU86XY/mdWeWjTIWyXEVxagKhxDK92spPTKnIc+t0jll1WmfLDQOSDrUjnT3ZjhE7OZ8Fwa8mDJ6cFq+48yH6Dp5555eIqwTdd6owbZORKgcZjs6z5kVxcralbxvZERl5v6inAeinC6rzuDzehAXPCff78V9s87FDEm/itpsF3Orx5JraNgg5zmc5vuL+kZWm/XOP2/C5sgR6V6fH/DjcJezPPlTBVkZXoZhfMOldnzsIduk51aPdUXZ8BAJkTqU66oTLhGozUsH7+4VK4p1lus6Z3gyRYda/McceEsKA15bFPkUqsIhRzS8OuOoC2qLFglh6ru6p3+6SoUMOpv0piYxraybcBIc4vcy0nOpUnpkHk/e/9SsYKb7z5w5EytWrABAywnzPa2YVlUhVPjOHl6MocXBFFU1R2/MINsleyc3jZmGSFRZc21MeZGte5rhJEcpG1BjAAAThh8fN51TdZ/XgxgRSgUk54GIyY7nRpnnUzbQXf9O8kUoyIyNudVjsWrz/ozQvoDv+G90xjfo94CBLj/hdE5TcyDg9aBbMp5Ack1OHT8EgwT1GOdp7kWfObsio80y/+V/XHIGNuzNvDefR7onIkMK/akTdaeO6U4NxyXfYykZyXUADl3ngZ2SLkVBn7TsB9Vmu6gKhzB+WDEa92e25d29h5UU9Tr3F/XN1377Jml41X/YriavcpGc6WThVCb++FhBtkmrmN90cR5RIFZVOJYLhRX1ETQe6NA6iRkoSuWMJaURPqlKxn5u7iWYOSmMymHFmDkpjOfmXiJVnqeMLBFeP3900uvmxnitamjW/i6HGwWAOSi6WArWUdAd/4ZIFPOW1WH6A6sxb1kdGiLiwpQq6Bh5e1o7Hd9fF5XDxe0oJOiO8/0efOI0caT1lJElyo1NFhLG+38rMf8LTEqCWUkeUSL2ZjJGG4LUfD1zaDGao2IvMrXGZO/kljHDZZrqZMcpmxtAz0m3a3xxyGTGo2t3p/5tlnnhkqDw+1QoIZBc60WEfOBtWLFihWtrWwduGLMMQPX4cqmDjJeimDq+HMVBXzJkbHx5Wgg8Nb7hkvy0PaZquHxtO3knag7o1sY7GO1JErXcMhUPzT5+2qtrTIrkg5fYor2Mbu+qhmbMrR6bCu1T4ffr9qT0kxX1EXx56Vo0RKIoIOap6PoHRFFkMyaPLEVDJIqgXyzPuQ5gnvvceW7tUzPshFX6vR5bcyMbvaDpsFjXM4zsZCNHihjI1DeUngpAjzHYBmHSqYqsK1kyxkIAbgVwJYBR/Zf3AFgJ4AFLseJ/WsgSid1SNu6YXol1Ow6leZT9XoY7FIVj7QgFvdhlNSaPLBUSZ5iFSEMkquXdUCk6Iq+q18OESpnXw7Dw6olp+WdA0uPJ+9GN8bI7tubnu4HCgBd2uLIuG18u9JTK4ORkkArhnFs9FivrI1KDOWGITz/dzK286fIzhSeV8z5zJu7727aMsI/uvgQ2Ro5knHoFfB4svHpixn2sbT1reEgYRnjeqNLUOyQ0Nqtbb70V999/PxoiUdLbet7IUrJfnDCXUpgymi594FaRXF2Zlo1CT50+cG++25C11Vpg1kzZHmnPbKPM+3/Z+HLSmOZt+OZtd2Jd4cUnLL+NDBnXINTI83nwhQnDbIWDP2EKdxfllomiKKy5goVBeZ6MEwOdmgN+D5PmVaqeqVrDPg8jxzZEsMoxxrCBKDj8yuYDAIB7r5mEVQ3N2NbcgaNN29AcGK6V18QdndQ+JnKEqfom4PPgq1NGSNMsvjplhKN9zZacMQxtmeq2XmCGqEyCG7wEX50yIiNCwg7yfJ4MkhsRzjmtBLscP2VgkZVJyBgLA6gD8CMkCxav7f9TCODHAN5ljA3Pso0fC4i8O9yD5Kbn1OoM0HEO2BEK4ZJ80qtjB/OnV2ZQ7gZ8LMVqk/JYazhAnJy8nTtCfApx7ohB/V7P9FMyHY+nnfGy891wSX7a893AxBEl2t/1sOR4iTylMtg9GbSevJo9m1XhEKaOL1c+0zqXZfd0AsqDu3l/B+776iThZ70xAxeNHULOJ1lbNzUdgbVGaMDH8LOrzkn9X8fre9NNNwGQFyuVKeOyOT+3emxGUUsKPm86cxWQ7j0+0t2HgE8sJ+1g4752re9lczpFzYXlG/YNyEmQm4q6TLmdP71SKeOMys+7EqWhC2r/XHzt5NS6ChMnuV+YMMzxniVak7c/U497r5mUEUVhvf/e1k7irulhwHZAjcuBaA/u+2qyTaPLClBenGcrSkHlLJh0On06T5UgiSUMMqfqWCyR6kt+WvSH71SjvFh8QivCtuYOch8TXadO2j0MKZm8qqFZqtCvamh2FPFiZ+0eiPZgWlWFUqYyhqz1gvGSdvEyCW7tnRxOon3MOOe0QWlRTNXjy4V75PWXnpHVcwYS2Z543Q1gGJK1sF4yf8AYuwLA0wAWIVmo+J8aslhgXXYn7n3YuK8dvXEDAS9LK9C8tHZHRmx6b8xQxpLb8Vi7FUbDQzoob4qux9rbX/DXCpWnZuHVE/Glh99IO9r29Z928fbZzRujKPJF7ZMltprh8zLHrGsyJHMZDii9gB5GExCo3tXuyaAqv+eO6ZV4e1erdF5Y56fbBAiyd4p206QRB6M9aV50EURt7Y0lUD2+HCHJaSPl9e06FsPl97yG3riB7qNRXDqhQ2qQyNa27HSnKhzCyMEF2N3aJX0/APCwdOVH5D0O+Biq+09dnHpZVcyJHNmES1N9uaaf8Q5w7ySoIRLFEcn8shZ25bB7Gun1sNSeVLNpf0b0BO+vzfvaAGQq3NmcIMrkiWz/5HUVGyLRjEgFv5fhSHcfpj+w2tFcouTHqoZmpfyQzcHLxpc7mg/UvpEwkNEm3b2I17qUQRR6yu/f2knXvVTBLItXr16NBVdM1859jvbEyNNH0bquHFYsJPqYfHqJdg1Cp/UnRTqDzwuIqpPwsVx87WRpX/Aix9nkvlEhxR6WDBUfCPKgbGQEz7W06meiuW4c/tDxcwYa2Rpe05EMJ3zJ+oFhGC8zxhYD+P+yfMbHBqLJwhfNBWeUSesSUUyDvC7Lc3MvIRUBFemASCgkvc5GmiHndl6XzLjR9VjHBQqHbiiAx8LBay5d4UQJAGArBEEnnDkWN3Dnnzdh4VXnuG58JQRhnFNGlqAw6E9jrdJlGbO+q92wMZWhpmKE9AhylNwmQKDeqSIUlNacqzDRrVP9SrVpb1sXziHyxABgVFmh0Ojp7I2jM3XdhxX1EdKLKuo7M57esI+8PmNSGBNHlGgZXtZiy2Jj00Ao35/GbmobmgnYTtdUQySKvW3i97U+OVtlRZdlVvQMykkUTxjCUy+uzO0UUFn3xQ3sbDmKqnAIpxV7cFBQtdOpY8491t/MNvN16cQIzkZ+9FE1/5B+6ms3nIua2puajmDesroMx+x9s86V3k/HyWkNPbVTg0sF3pelpaUYU15EGiRWRNq7cfsz9bjls+PwxFt70Xr0GMqK8rDgikrh+3YR9PAb+/uNRx/JHBVO6k8CYp0hcrhLaAgCyT7RIV6yluSxM79X1kfwxvZDws+GDQrioCLc2CmyqRmXMOj5dqS7D03t3Whq70a0uw9fOePUJeHI1vAqBCA7NzzQ/51/KugIUtFGE/R7yEUjE458Y6cKtaqqkMsMiRNVHNQKXY81kKlw6JxyyE4HdVgmRUbjvGV12h4iOyE5G/YczqAfzhZ31zQiJujjoqCewqvTx3br9OgYalXhEH533fnCTf8H087S9vjrFGkWzXnq5OdgtIcM4fMw4E1TEVROhb342skpb72srXtaO7HrUGfqt6s278cLN16aapfeSkkq1JSxr6qXSbGQrtnWgnnL6oSeZwpmR9BAMAM2RKI4QCgN1Pftyjk7rGNAMqeFK3d217Du6f/Gfe1C414k27/8yFr0CWYOt8t/srJB+IzvPV2PMeVFmD1pCD5Yc0R7bTt5R7usvyKZboVdIzibnMMoUQ+MMeC25e8Ja5FRsoFDFipslhMcZsdsNvlHFaH0EEA7eeEq8L487bTTsLR2h5bRxdHTl8AvV21JrUVujI0pLxI4to4K79EbN7CiPoKV9RGcN7IEAR8j59G0qgqMKS+yta9xWHWGKqKkC5DsEx0dwRqxoju/V9ZHFCeLjJz70Z5YVoyHMnZWFWJxYFFNY1r0yMr6COYtq0tbF7VbW/D626fuiVe2tB8NAGYzxgLWDxhjfgCz+7/zTwPdnBK7ccI6R+BUjoZO/ScR+4zo2olCgKJKEsDaNzrKnBOWyUU1jbbaIbtuV7F0O39Cl86fgs67UoyS1DyS5UGaURUO4d5rJmWc3jzw6raMdaZ7T0Bv7S4nTn4oZkEAOHdkacZGnjCA7y6rw0rTBiRqq4g8oDdmpM1FyjNpB7G4MxarhIGMvJfRZQUIl+STNMdmKmGrQqe6rgM7RpHTHEBq/lPsljynZcZDa9LGXAe6smJvWxeZH2mV434i34Vft5J1mN/jy0vXYt26dbbWttN31GX9bYhE8fqWg1k9SwSV/JAxO/bGxYaJYSA1Rjc/lemsSxjAzU+JcwNlbafmvBv5R9Zbu1UywdyXq1at0o50McP63tT7iiI8zDCA/hMohtICcd7aHc++j6W1O4Q5fgBs5XZSlOpAct457WOd3931slyXCfSHFYuYASPt3VnlelF7qC7MhC0NkShufqpO6Izoc1jf7EQgW8PrbgCfArCeMfZtxtjl/X++A2A9gAuQzPH6p4GuQWXX06sSjtGeGMluduoeuNKwQ/5g7Rsd8gvZdyjhv3pri1TY2CHdcBKSw9vlhMbZ+htKKGnRuUL/Xe0Y73YMtVUNzVobrp176qxdiqVLdkB7QFKewaxgidoa8IpFtLkdbuVdypQeFWWxOe/l9e9/GuvmfwYVxXniL5sUIKrbspFZdhQWXXltXT+UYVg5rFhKY2xWqnXXse746iqgAD2e/LpHwsrU05dA79hqVx1zMnmi2iu58dxBnDDpPksEmfxQGe06rkNK3CYM4Pon3smYE1TbVc+SrW0dWnercydbmRMK+jJk8fe+9z1bkS4yiN63rIiQRxb0xhLkaWVnbzyDFISfLtl14BgKQ9BpH+v8jnKscEwcUZKa+yLSmmwcwdQeqgtzbUa7kQenCrIyvAzDeBrAN5Ek2Pg1gFf7/ywFMBzANw3DeCbbRn6UoGtQ2WXGUwnHSHs3WSy0py8+4HVW3IadGh/W0wvRbxmAaHdfqg8oFqdpVRVkyCYgPxWwc7oyt3qs1sZsRmdv3JGHXvQbaq7IaixZ26/7rrwNOkqmrjJnx3Hh5j1VBXlFaJFscpwCn2or5TXvNuUraK0VjZwnGXmDiIXUCmv/9RE7ovk6dVqXzSmeHYVFZ8xF6+fNnYfgF5zKb4wcSXnDqXy6hJEMl9FdxzrjS50uUu9HscrOmjIC85bVCd/NjNfelXvM7cIp629DJIrrn3hHO+zNSTgkJT9kRntDJJq1Qig6WZhbPVa4DlWPkq1trmDLZL91DOwwmVoR9Hvw1LcvypDF3/jGN2xFusgg2sO/dclo7d+r6v9ZDQ8nTIeyR/AQW7vQnd8qI5TrR1XhEEJEjTinJ3KyPbS0wI9ijZp0XJ/gZQk+anBseLEkQgCeAjACwMUA/rX/z8UARhiG8bgrrfwIQdegsqu4mj1vo8sKkE8U+BOBhwO5QQV6osDf16vgw8/zeTIUaf7bqePLU8aNgWTcL+8DWWFHWWimk2LNlKKvWQcwha5jMUcC3k48/pHuPi0j3c67uk3pDgxM8Vqde6q8lCKo6tLI5hT1OPN10Vg8PDtJs33GkEKES/Ixuv9vGSgvL3/GfV89F+GSfFLhsvYftY7aOnuVJ0fZjKMdp43OmFMEICUFGRH26I0ZqZM/WZHyur2HtdexeXwp5ZhSFKn346yy5jlz31fPxe3P1GNFfQTdCnnxuQvOkX5uFzJ5Qu2V06oq8OWla4VEO2b4PExLRtmNIlCFR7oB65yoCodw0Zghtu9zuKtP+k5V4VCKWEUEzthrLho8zEY4sJcx+L0M4ZJ83HvNJOEYLF++HCPLxJQA5cV5qBxWjKnjy1E9vjw1nlQh8KM9mYbm5v3uhEdy6KYuOMHGfe2oCoekhc7NsBvuu+AKee0vs340lBhn6no2yA/4cPlZQ6Xf8XtYSp+QhWueysiGXCMAoA3AAsMwfgngrf4//9TQJRSQ0eNSMCdnTn9gtW1mGDeoQE8kqsIheDxAXJJsS20WVeEQBuX7SYYxp4JSphDaSdJ3ekTupN12hD830v/acCCtuKXofWSslGa4TekO2CfuOFn31IETI8NAJo2wtS/NyfkzZ87E3b/5o5SJTGZUNkSiuO3perL8gKifqLvFEwYaD3SkqOOthV+z7XOzbFUlceuMObV+qPIB/PtUkXgA6CZO1aln8bU24Yc1oM5PrfmAqn60rl8ROZAIQb8HHzz7IDD7D8rvUqBkpUgeUHulrkMp0V+QNhuGVhFkxBu6Mjfo9+CWz45LI4iwwnqvPZL6YDKo5K3slGdny9EMEhA7J15xw0A8Lie/mDlzJgb/y53C31cNDwlJnyYQBBXdfYkMAgg7Y9IbSyj3Z2vqghuF3zl4yKUs5JfDw4CaW6bauj/fG27503vC9AJzX1EtkNV9lMHvYeRc47llMqKm4nw/WjrkoZKnOhwbXoZhHGOMHQDIfeCfEnYMKl3FVQSnlJxuJcWeKJQXB6UeTY+HkTTdMiOF8kYX5vkQ8HnIcEMqRNHu5u1kHAI+jyMB72Su9PQlcPNTdanNJ5t6RAPBXKdaZ06Y6nTWrjuBMMehCs8EA2nBcKNCZ2xWrFgBAHhu7iW48qE1wpM0r4eR/XZ3TaPQ6CoMePGZsyuE/Zvn86BLErYLJE+Ipo4fgkGSOmVOwGXri/URyFRznTGn1k9ZUZ5QNvG1OH96JdbtaBGytFG5lCpFrYegxAaAkYMLMHFEieN+lK1HD0uWLTjntEH9971C+75WODF0RHulrvwwO5NEz3DqGJIZ7Utrd5Ay1+9lGFtelDZGU8cPJctkWOeE0zwoVX/J8nvverlRSALiBJyoyrrmV6xYgekPrBb+xkpnz+GRWH9W9ruKUFC5D/q9LHny+tAa6fesctuJ0y4U9JFRBvxkW6aLZAMe9ZMf8ApzI81zjur7d/cclrIbUntJfsBLhhuac8u+9/R7+EB0Sukg6uRUQ7Z08n8AcB1jbKlhGM6r6H3MkI1BpQuVV4CCW4n4JwrXXTgSi2q2kJ939MTSFNCV9RFcNr4cs6aMIIXauIpivLVTUIQGSWYwWVHhVQ3NJM2vnc2bUuZELHYcvbGEIwHvdK5Qyfp25zb1rkM1alvJQK0zpx5s2T0HAl4PU4Zn6u4xPX0JzHzoDSQMA0G/F//52TNxw+Vnpj5fsGAB7rrrLlSFQ8jzeoQbn4fRdegoFkyvh5H9pSrOzaFTXNopmGxB9UM15tSaW3BFZdopAL9uLqQ+oqQAnb1xtHX2KvNGdE76ZDr3xBEltuauVTGSKaYJAzh9cEHq/gsWLMC/fXe+o3Ijbp2A23Uo9fQlcHdNY8bJCUU8oWLYkxntc6vHSk9brScUVJkM4ZxwqHiq9n6Z4bVfEc5pF6Ii45+ObUDFuC8Ix5RylMocO1aGXlVZHQAIePtTFxgj+3nmpLAw+sNuBNO4imJs2COWq7xuo8zRwkEVT6egqsHGixSb2ykaEwP0KapsD5a9E39uVTiEI93i8Tp6zH1D9EQjW8NrI4CrAWxmjP0BwG4AGSvUMIznsnzOPxVEngIgs6YWX+ivbD6gFet6IsKm3Ma6nfYYcAwk2QepEB/eBzWb9gs/P9RxjExUB+yf3lDXqVoWMj3xWCyB25a/pyy2bYV1U2hq79ZmALOCqhUkg7hAN8NbO1vTij+++H4k5bXP5tRjIEIbgeS6dIl0C0DytEgWimrXUI73KwrdffGUs4IbX7Nnz059z+8TG17xBBBLiPuNYkyVGRMyb7QZA+kMCrrgMZYpVWPKi5SF1AH6pLQ46MNpJflaa0mVd2RHtjdEorj6kTfSasv5vHL5s3prC1bWRzBjUhgXTv8KqVgB8vqPMllp56TaiUOJM9Oa70mdIOmcLFmNdp4Hta25gzys7osbqX603kulvNutUWdGNnu/22cMohSAzlGXkOFr7+4Vn67IwqPNa64hEsV7H7Yr28X3fuq0vjDgJfcQu047mTHLnTeqXEsOO3ubem9J79O51WOxsj4inAPUWpbtwVTOs9fD0sa3pUM8z/viCQT9HuW6t8ODcKKRreG1zPTvhcR3DACnbg+cYljZX9vDHOK1avN+AExYofyh2ZMxb1mdMpehenw57pgurugug5OQLbfQEIliHVFZ3QnCJfn43XXn9ycSe9AnSB4zIPf8RXtimP7A6oy+sBsCSJF7yOznmCk3RlZsm4MaO535Qilge9u6sLu1C4C+sSRSKKLdfai1GMcJI1nwU6fopwx2jWA7Bc/dhIyi3Y2Q4Adf3Z4yvDZu3IiJEycCAM4bWZrR9wDg9Yjn37bmDjLkJSBhQqOeY8ZAO4POHz1Y2QYdyPKPdAqpUxLl8rOG2lKY3MKimsaM2nKxeNJQlbGO3fxUHcaUF+F3a/eipy+dXISfKL29q1V62iw7AbdzUm2VK3tau9LYPkUQeekpJj1dhlcOqzErw10vNwqNdpXyPpD02aUFfhzuotkPrfB7GWJxwzWjbGtzBzohDpwyDLFxUVaUR+b7cPnKZbfqxNn8m08ScuP80YOV99AF1dcelsypU9XaMsPOfqH6bm/MSOvrZChsubA/KP1Gtgfn+TyICfaSoGW9UTqa3+vBs3MvTq2d1s5e4Rw457RB2ClsxclHtnW8Pq3x5zNZPuOfBrwYnKhgKlWhHNBj8Qrl+x0ZXW6z0dl9tswIsssKGAr6Un1AFUhUIdLeLewLEc1vwMdIpTJbxVrFZCgaO168dW71WPgIV0i4JIiZk8JYfO1krWK+3FhSzQ0rJTMVN677fjJQm0G0J5bRvmwKnpuhmk/Ww5+Az4M7ptPMUrJTIJ+XSQ0eDiqk447plRD9/BihMI6rKCbDBmVhI3dMr4TPotT6PMBUEyuZE+PaDgOdrI+ZzXvptoFa21ZxZdfoVMkMTmOu8z5UoXRVHb9UfamoeL7rsDVSLIWs/7uy31phlisVIb06TdZ+pGpG8nAvXYiMWQqHOo65Wrg7XBJUkl2o5OnCq9RMlcVBHyqHFaN6fHkyGk/5C30MzZMbzaJ3pyjiPez42teNHjDL5DumV2bIWJXMtguRUQEk19h3l9Up2TrNsMMwqBNhYO3rO6ZX2mLhlrHFTiGMV+t1ak8tLfCnrfvH/+MC4Vh969IzhL8/FZBtHa9anT9uNfbjDrveLL44uOdvyih3PehOqMvdgo6w9DC5x90KszCgFr8dZPaFdeejd0I74VUUc6NsTEX9x4u3AsAlY8uFv5syajAemj0ZM/qVYjO988jBBdJ22pkbToS/LihHhKguTrYFzzm+M3UM+VnA68HKeZel9eULN8oNDqoWXfX4cvzlpkvxwo3Hx4YquRA0hVrw0y4gKS+Kg3qOB5VxwNnDKFhZuTweD+ZPr3RcdNeuM6gqHCJPNPxe5kj5VbWBmtuXjS/XLjUhgmrNbNjTltGuKxevwZzH1msblHk+j9KJF2nvRswQ9ym1fZnXD0UdTzljdOUAZUBZYae0i8qQNX9uJzrD62GO9lZqDkwZNRiLr50sdUaqctbGlBdJPweSJ7Q1t0xFKN+vZWTqMh8G/R5cf8lIaRSA6N0piviEkTw1AtTzJ9/vzZDJyXILyZI0xUEfioM+XDSmTO9lNNAQiUqjW+zirZ2t2mtcx1Fv7Wu7pXJka4qqITjfYtTqGmh8rKz769ih6vl8spBtqGEOLsKuomleHFXhEJ6dezG+8shabNjbnvFdql6Ok/a8vuWgMNzOTej0RTwBTDp9EIrzfFhtStYVwapAUjlWTtu5tHZHxqlAb4zOK7Lz/OKgTxiWIFPEqP7jBXspSmLz5iyim+Zhhnafa4VOfobT3B++SYhYwqy5XnYKnssS+dftbEN5sTjsZUhxnu34f518D36/n/xlE36/bk/GPa795IjUv5ctW5ZmfFEFVT0MuPIT4YxnyvK1eLFPEd23nTWhAyf5e9IcHstnOrmAqjZQZBzzHYR6A8dDYTfslue7Hu7sE4Y41m5twdu7WtMUpRGl+ULGsJFlBfjVV8/F//x5E94lEv8pBP0ekkJfpMhZ+zhbSm4dmWolP+HzVVQ6A6DJZqrCISVJgQylBX50H8k88VDJT+odJwwvxpjyIlw2rpzMb1blrKmMPvMeqivni/Jo5j6O4qAPf/r2Rfi/hxfh4i98U9h+n0ecoyZrx10vN2LGpLBSdstk83pT2KxoHenCOt+oUhROYUeumveWt3YeQktHZnjnhOGZa87OHqbav+776rm46+VGtB49hrKiPFx34ciM71JznWKW/ighK8OLMfZ3ja8ZhmF8NpvnfFyhyyrFkEyINysxHiaegAuvnoirH1mbofC8ufOQLeYbgN4IO3piqVyjbHJxnDzbisb9UTT8dHqqLzfua09uMIYBMIY8n8dEgXy8jU9v2Ce9r4TFO6OdgP28ot+v3aVx9yRERpfqJELWf9uaOxwllLtpLHHBvKimUbjRWpmV7KIqHEIo6INIDTOPia6yp3r3ur2H8Yt/mYjvLqvL+ExVrJIC3+j43L5t+XtCA2znIbExbL5+1113pX3mYQwJQWK6h4lZCmU1WzbuaxcqqIMFBYYBYFPTEfJeKgxEaQK791K1QaR0TKuqcJQra0e57xHx1vPPLAblgSPi06UDR3pQFQ7ZKpuQ5/PgCxOGYW71WOxsOYo3trXYqifGkW0dPZlMzfd74PN6cN7IUmFNKus+1hCJ4von3pEa2E4IcADg7GHFOLOiGBGBUqmSn9S+dfeqLbjvb1ulp1AtHT2Yt6yOnHuyE7E8H9PK07Oiu09N4nT5WUNRFQ7hrrvuwid//jfhd4qD4lQJWTtajyadYCrZ3bhffFJ0d00mhX5PXwLXP/EOQkGf9joWMfy5XZYEsCcD+d5C9feja3enseI6gYx12Lz+Iu3daczVfD1OGC7u16c37EsjpqEYFH/5Gffy8dxGtideHmTqp14AowCcDmA7gKYsn/GxhGiyiIqJehiw+Nrk5DXnfyUMCAsRVoVDuHBMWYYya02Y1IGOoj1QRZl1Gat4X3EKX6uS4mHA9z4/PkM4UvTYQNIb6fN6lEX6zEqBHW9tQyQqPJVUIVySry3w51aPxYvvR4Shq+MqislNVpZQXhUO4d5rJgnzEAH7OStV4WSRaxEuHFOmrZhSCi01JjzXi88ZOwXPZz78hjBJO5EwUpuB2ZO34IpKYfkBXehQ41Nz2ZzHM3PmzFQtLwAYV1EkPPEYV5EZntEQiUpDoHvjhlBBae0UJ8rrMLBScLtQKfWMbNtgVjp0xtDqOAp4GSaOKMGR7sxTLAoqlvFNTUdSjHtUYj8/Ca3XYIDj+MKEYSkHwe3P1KfNFQ8D7r1mktZaprzkQGaxcBH5jUymdvclgL4Eare2YI3FMATSFeqKUBBv7jxEGjFcwXVs7DPnRia11g0DytC/vrghrWcmc7olDKR9X3d/VrGhm9955syZaD3nBuH3qBN6GW1/qH9v4fPqysVrhM5UkTxqiETJk8NIezci0C9TIjLQB4IfxYkMPHRUrOO0EtfdgI7DoqcvgXeJ9fyO5eSfikB46p0Ps2rnQCLbHK/LDcP4tOXPVMMwRgH4EoAiALe50tKPGUSTpTdm4MIxZWmxqivnXYYZk8JY1dBM1lWy4mCWsfIc1rje4qDYTh+IosxcyVfBbCjI8prsEIIc7uoTGl0+bzLHRhTjLItptsJpjlwo6NPOjakKh7D42skZMfa8TU4TykXzEEgahW4WV6bmsBmqXBvdXK9PnVGWiuOfOr5cyqI2uFB8ilPQX2dmTHkRpowqxRlDCjFlVGla3oQTIgedHLQ+wpAxO3DMRheQLEwugui6cr4SGj9lYFE5Vzqws8504ITwwm4bVGNonse7W7sQae9OEdascYGRkWNPa2dqrVA47tjTUw3N703JX4rBVQQrCQ8AbfIbXVBOBE6cVLu1RWrEcAVXpugy0Bm+25qP2s6ZcRPcyLTKIdm6tFKAm9tfGLBPWu1hyHjnFStWZOSEHv+++HpVOIRKQVgckKw7Z/5eAdFOsw7BZfTXfvumlnGkk5dnVz/yMODh2ZPJ3G4RdOSWcP8hXnIgaxTr9gfVBCuhE3W/vYfE6RSnAgYsx8swjJWMsf8D8ACA6oF6zkcVMoVTVExUN8TmJ3/ZhC3ExurEI2L23FI05ANVh0dnwzbTu1KnODyvyXwqN15SvJCCh3lISn6dnBwOp4Zqhc2CwzMmhTGmvAiLahpTpx881EbkQfR5aBZGVdvNjJG6aIhEpUWuVVDl2qhyvRbVNKbF8APJmH4ZCgNeiFThwoAXv359uzBk4rm5l2D11oMZn63avB8XjRkircems+6pDcp8fdasWVi+fHnq/xs/FM/97Qczn6ecrzbpRXvjhuMcUTvrTAdBvwefqxqWcS/ZSardNqjGUOYBdqL/FAa86OqNp/1Wo4506nsATdMdCvpQFPQj0taB/Lw8lBb4Uzl+AxEGqlrjfJxe2XzA8TPswKzgyk59ZF3NjVq7eZ8AyBw6uxCd2owqK1Tm8JrB23/xL14la+VRIfuXjivPePdZs2bhE5++RZhb+InTS8h2RInT2839J7x8bU4ZPVjYd129cVy86O+47sKReODVbbbDR1Xzmzohl9H3jykvwsVnDtEa66njy5X5o9Spu9/LhCed/iycYyrYLXxuRdwALr/nNUwcUYJpVRWkDjFySCHcLQDjHgaaXGMHgO8O8DM+krAbMqPzfSrJHnCnXk62Mfh2obNhjxmS9Go1RKLY20ZvGtZ7FebZn/qqBFbdjdSp4Fm7vSXFhGQnv86aIEzVNYolDKzeelB6P7dCvWS5K7pzSkfRk+V6yaivqXGkijL2xRNphpX5fhRRQW/MSI0FNZ7UPDVfp04nzJf/8Ic/pP69sj6Cw93izepwp5jERTZfA16WUdBSliNpN1THCjsK60oF2UJf3Mi4l05ooJ02qNaMSs7p5ptyfObsigyyk4372rWUaq5u/WhGlTBfsasvllR0PD5098XRfSSOSH/42qfOKHM9DFRVbNkpuYWuIWqGuQ4kcNwA/9pv3xQWpKfGrcjB3sMxf3ol1m5vQdzyyl4P06pTJQKXebIoAxl5sKw0yOiyAnzY3gVz+qHPiwwGOyApo/6+rV0oK7958Wjh/VfWRxAh8hWPxRJpoZXzp1di3Y4WWFMhDWTmGdmBan5TetPCq84RrjHuKJ4/vTIjX1KEzp4+ofw0O4+iPTHhXlda4EevwPjrSxjanAB2a71OGF6MFfXK20rB633KyHTOHFKY3UMGENnW8SLBGPMBmAXAvQq4HyMk6z5l1h6gFE6d8JYn3twr/C0DXAljONHhETob9lP/SCYbq6j4rffaS7D6qeBGWOXc6rHaNLtmWCO3dMIc7CaAP/jqdunnboV6Ue2yE7Ioc1LofI8CH2NRaMZOInyhqZ1WPt7XzJcRjSflTDBfLyFILAaZ6qD86le/Sv1bVpgzlsgcE9V8nTiiJEMuDCnWq6k00OUpVEVIRTmNbpfRUK0Z1fyc2k9DP7qsQJmUz+9rDdnTpVpPGMnIhntf2SI8yKT4O3r6EjD6ny9qj1PI1rhTcguGZN40n6/hknzlb4J+T5rRxVEVDuHys4YKf6NzEu0EXk9mfcUQkQagi01NR7Dt4FHyc7+XVhVlZImlRXnwMGt7xff61a9+heUEeQh1XafIsHntUs92Cp35TelNMnACIh1bun5fJlmRNQyfqgnWTZxU8oLVFPjeePk9r2HGQ2tsleR44i2xngokT+t11qMOnqs7deklsmU1fIz4qATAhQCGIZfjJYF1VdGrTCe8JU55vgHXjCOVp9eu90MGGUEER3d/vK/MIBIJRxW1LgWZkqT77lXhEPL9XjI8ww6cMrBR6FZkQ7sV6pVtyGJDJIpod1+GV1k01pTH8byRpcLTv3EVxeSphxNiCDueaGu/HO4UJzm3dx0nrjh9cIGYxr7ouEE2bdo0AMl+2y8pzCnK8VLNV7Oiz3H5Pa8JQzJFGIgcUY6WDnmuoKhWDEXb/u6ezOsNkWhGKK81HFm1ZmQha0H/8fBmVTkHTsstWj9zq8di1eb9SgIGA3BcZuNgtMfVMFBAHmVx2/L3HN1z8qjSNOr4aVUVaSxrQNIJeuGYMhyUhAGb26jap8zo6IlJ2QVlEJVoSBhAOxGyxsEAnDWsGNGemFAJ39PaKc3rkRleMmxr7tAuKTFt2jQsf0lNFGSGan2b2yHqO7vwMuCLgnIbKoj0puufeIf8/rGYvqMn3n86ZV53uqQ8soLplBxUnTRTUSO8jbLC0KcPLsB9s87FjIfW2D6RtqKNIHc6FZBtqOFnILYeDgN4A8DvDMN4JctnfCyRFALpXdcbM/C1376Jy88aKlzQTmLCTyQoZVVUI0VXWI0cXKAVIkOF81jDQ1Igdpny4gCi3TFSwaa8WzrhSQMBpwxsFKhivGa4MQ+zCVkUCX6GZIFaHuuuW6fnbUuOF1fqqFMPJwj4PNoGm/n9ZUU2fSavdxdB9d64vyMVLtLU1JTqN9l+Zpf6Pt/vEc7viSNKtPNFBipHFEj2U1+cdiaIQp6ovIs2SxhmQySKqx95I02O125twZs7WzMKZMvWjNkw46yGojIYKgOV03JTz7hozBAyzNgNjKsodn2PkhmtTkK2Az6GTU1HUuFssj0KQOq5PI/NykLJvz8sFCRD3kSQsQvK4NRJ4WEMNbdMRUMkKlRqE4aYoppDVNiY94ETiN6jqakJQEHml0ETlajWN8e4imKXHDzichtOIGMODHiZLRIKcwkh3TUR9HvgZQwxwqFGyUGdk2Zr23XDgrkM0dX7PqrIyvAyDGO0S+342EF1+kEtqo6emGOh7PNkhqPx625A9U6UsmqmH9cxSMzP0T2ZojyjC66oFNI09xHuFL/Xi1AQaDma6S3xMGRswKp3p/KFCvJ8WZ946TKw6dD+coTyT0xN9WzyBSl63kH5/pTRpWsEU0qdW6cwfi9DKOgTzicrrO9/dw0dRhP0H1dFKAXUwHFSmcOHDys3zOKgT0h9nzQAxeulKCguByCjeTbD+s5unpgDQFGeV3qKK7q3KNxSdF3kPAOcFYnWMVhkhgYD7RTikOXi2IcBszrsYUlyI6cnOSoyE1Hf6Mq20gI/KkLBVOFaq/HZ05fAqobmtGfIZAiQWVjZSei4k1Is1BzwEnv/cRyfp9RJApMkE95hcVDoKtLjhxYJaf5FzpbDhw9jfEWFkPSKcs6o1jdwXMYsqmlUGiV+L8P0c4ZLZJd7dH8FAS/pkOOhwbpGlO5JnrUkzZ0vbCTLMFCRGjp741ALEZjuCRyXYXYcdx9FnBgt658MOoqfylvnrD4WJTmZbYXG+n1rOIbonagFSdHgU8X1nCRMizyjohASANIFHYvH4feJCRQSBu2ptMvoRbHjycALldpRSjktv7VK/IOvbhduWPmBEyMSsglZdMISR805SqnLlnmJo6QgQIbplBfn4cIxZcL3l9WRAYDDXem1yFbWR4Qrn/fJ1KlTsXyl3BAqFhhRfD1SCgJFJV0VDqG8WMyMl+/3YlRZgfCd3T41ptYyhyiBvLw4KAyHsYZhygrODkT45NzqsVj5fkR4WD96SIGyj9ya0+GSfLBEDIbHB8DAgSM9SBjHE97tjpnTcbfKkNbOXuF8mziiJMUUPP2B1cJ7WcdLlecnos13Qthhd55QIaMqvTvQvw5kJ1Q+rwdxwY1KCzKLF+vm1xlEBMW0qoqMa1OnTkXtanF4G0VIQq1vs4zhxcv/oWCsBZKBMA/Nnoy/NTQL98eAQp7YgSzMjxsgTsN+RfAwZET/FBKOMwBknq6SbMnH8NbO1rQTOB2/RHlxXlr4tSo02udheOBr5+L7z7yvNL5PNWR9FsIYCzHG5jPGVjHG6hhjF/RfH8wYu40xll35648gdJKzqRpDZtgVylTxW7/Xo1ULhUNUH+nmp+qU72QnZIh6N7sJ0+Y3tiaUr2potm3AHemOKesMiRLtdYkeOKhkdw8DPIZYiAwpCqS9n24u1O3P1CPS3o1jsQQi7d144NVtKC0QC1xZAWW3YR0vXUVN1ddu0FpThAh2aXaL8nzkfCrK85Hvv7R2h9K3yudgVTiEy8aXC7/D+2TJkiUa6zP5RHPi9FeWrpOuIRlpA2WUDRsUJN/ZTVILQF0z7OpHMuUgFW5pvS47jVf1tZOablXhEAoIVs1dh7qU99DZc1TgJBMXtLyMdfM/gymjBmvXl6SQzbibZUgZUWPPzNanK6dlMoT6bOTggjQCBR3CC1XOsHWO8JBRuxhc6E+1XwQGkKd2otMUXVlKfU9UKmbJkiXkqey7ew/j8ntew8WL/o7L73kt1R/U+uYyZm71WNz+TD1W1EeSRbQV4PKd2h95P7qBTiJEnLHkvK4Kh1BeJJ7TTjCqrDBjj5UxWVJyUCRHPCzJYDlzUhgXjRmSMWd0/BFm47oqHMILN16KqcS+BiR1lRmTwqgIiQ3EgSPEzx5ZSWHG2AgAdQB+CmAEgE8gWTQZhmG0AfgOgHkO7/1JxtjDjLHNjLFOxthexthyxth4y/f+wBgzBH8y4nQYYx7G2A8YY7sYYz2MsfcZY7OdtE8GXZprznRDFSa2m/tQOVysuMYSCVsbG1UIUwTzO1ELUgTq3ciNgbhPwOchFRgnXue+eEKLAcx6b7tsf1RfLb52Mq4893Thb84blUkEoAKZq0R06MjB4hj7UwlOWeLsrCeKiYr0vBIKwMjBBY6KVevMXfN35k+vlPbJ/fffr1S8Dxzpwcp+pwwv5ivzJAZ88rpvo8rEdL7UHBuIOlCqtdwrSGKfMSmMh2dPRrgkH3k+D8Il+Xh49uSMMExK6TOH/YmUZ1XhbxlkCozKUDHPaTtFb8Ml+Rkstvfffz8Ad8bMrXHXWfe6clp2L5kzzexIsRYdtkK2P8jmiJOQUV47j6p5dNn4cpJcQ3RZV5YmbISr3X///RgaEhd27+iJZRQX//LStaSM4bLVriOXh06LSHeA43uwE8eJFYzYg81XLxxr38imINpvqHGcMqpUGHYOiPfGlfMuw+vf/zQemj2ZnJ8qQ+h0y75QFQ7hiW9egGrC+Orui6MhEiVl/PnEGJ4KyDau6B4AxQDOBXCw/48ZLwCY4fDedwC4BMDTAN5HkiHxuwDeZYxdaBjGJtN3jwG43vL7TI5N4OcA5gP4fwD+AeAqAE8yxgzDMJ5y2E4seG4jdj6dpDudPLKUrL1jFSrcW5dM0l6b5iUI+DyYVlWRipMdGgqCAdJiq5RSSG0Ar285KCxkamfDMy9c3XA/2YZDHWOX5IuLDR6LJ1LH8dYQFSehNR7GtHIHrAJLJ3ROh/ChKhzCAwsXIFA5K+2YXaXkUqDGMuBl8HtZxtxYu6NFu36H6J2yzcnRgROWOCe01qIwRCqW3ssYmI9lfL52xyE8MOtc2+3RmbuqtWfuk5kzZ2LFihV4bu4lWFTTKAxjTBhJemZ9RUW+ldql03arRpwZOrlmojUyY1KYVDw4qDyEqePLpbmGE4aHhM6Q6594Jy3/QrSO8nwedBG5obLQRw4+pyf8sEb5XYCmUefzyY0x072HStaI1r2HpYe16YY4q2SI7DPeTpnTYuaksFRWyk4BnexrLR3HhGGYvO2zpowgQ5t9Au+pbn5dwOcR5jKL5sfMmTMx+F/ulN7PDHMJA2os7Brv3CEhG3+3QqJDQZ9Qp0kYx0OgdXNlgeP5W0NDwbRQP3PbrZDVGJNBlpNKzc+p48thAOQ86+wRk3ncMb0SawT1zHi9M+odvnXpGfiL9C1OHrI1vL4A4H7DMBoYY2WCz3cCELvv1bgPwL8ahpHKSmeM/QnARiSNp38zfTdmGMb/yW7GGDsNwPcALDEM47v9134HoBbAPYyxpw2DiPFS4B+72xAoTwqS1VtbyNMZO2pKwjBw29PvpZRv80SmFrpdT1hHTwyNBzocGyyixSxakGPKi7SVc2oRjSkvEibdWr10PX0J3F3TiFC+Hxv3tduOuz+zoiiVF2UmBTGDEmIyYSRjfASO091Oq6pA+Is3YkeGcHJ2cE6N5aiyQqHSGIsDi2oaUzkRMpwsJkdAnyVO1wjWNRg9xBGu3+fBiNJ8fLA/va9jcQNPb9hnO59tWlWFdMPVXXscK1asSH3niW9egMvveU04/jKmLSv4aRFngbS+GxXGQl13y2C2C6eGHdVeTkRAKc9UMrtOYekeiTJvp0SGDstmKOjDUwQ9PZ9PboyZzj10i1pb5XbCAG5/ph5jyovSvmeesyLCJJUMoT7TyVEuL85T5m5TBsPGfe0YWVZou6i2FVaSBdlpabQnluGMM/ePjEq/N5bIcPD5vWIn4ooVK8gcPAqqEgZ2jVR+eiIb/3nL6LQLOzn5gwhnMnCcFKkqHEKeBisuQ3r+lp3SNrd8dhwefHU7evriCPq9+M/PnpnV/i2Ti7J5RtWRk7EcbmvuIMfKOPyh43cYaGRreOUDUo4Ax65KwzDWCa5tY4xtBnC29TPGmBdAoWEY1JnvVQD8AB4x3c9gjC0F8CSAi5CkwM8a1JE9ZRiJ2LFiik1UtNCzSZ4230/lzbJSd6tgh2KYWkQ3/nGD9rus3tqStil5GDAsFEzRNkUkxW5Z/w9XNTQLNxOSnl6ChkgU1z/xjhbjI6VsO2FKA5IKvHVj9LCks4CCtWYKJcTtMjm6DSdMaPx3ViXuxfcjqbBAmVE0eWSp0GM3rqI4RVFtRd3ew7bWACDOgQCSynA1UW7CCnP/tO7ajMfv+HrqN9RpTVlRnrTOihXv7mnDl5ceECrEdk9DsiFcoaCTJyRK9NeBqr3ZhEhS60hmXNnJz8zzeUgaaY5qCT39nDlz8Pjjj7syZjr30JU1Irlt/Z6uw0jl3BF9phPaNrJUXSCWWjt727oy1m15cR6+dclobN7fgZc27teqGxgK+lBzy9TU/1VzVUZM9PqWg+ggQhhjiURGVEVf3MDOlqMZc2TOnDkYN/0WWzpMU3s3yTQM2GP1tRr7VeEQplUlWRZf2XwAG/YcxoIrKsm+emXzAVusnjLmPvMzdMbzsv5TdnPbdfablfURLKrZkvp/d18ci2q2YERpgfLEn4J1PfNorduWv4cmyd4ieku+h7USNbn4XiJ6383i7fiUQLaGVwOAqQB+Q3x+NZI5YK6AJYNiKwBstnxUACAKoIAxdhjAMgB3GIZhNqEnA+gE8IHlt+tNn7tieFGwm9ekgvV3Ki8593I1tXcLBSW/n3nhiISqmbp7IGBdRMm4dn1PvHUBJ4xkzPZDsydj3rI6RNrpPuJeF6p4oG6BXw6VB9TOaRyvZm/n2bc/Uy88oqfClYD0szWZkjIQOTm6yOa0jcph1GFlu3jMYKHhRRU6BpLzcWV9JI1ZcsEVldKNjerDrt44plVVaBldafMufyS+vHRt6r0mDC/Givr03/DyCyImUAptnZk0wTxsLuBlYCzdEUV5uznsGqgq6ITfrWpozkrJsBtyowvhHJBUubXmSMhw1vAQ6SjgmDC8OI0S2qxQ8hwvwJ0xU91DV9bofG8gHUY6so9SIs2gwiZF+0VLxzHc97dtuO1z4/Di+3phaVZdRDVXZe9FOaMA4BjBSnfXy40Za+7+++/HgR6frfInvPzOivoI/F6G8uJgmmzlusz1T7wjdSh5GcMtnx2XJld/8pdN+P26Pan/R9q78d1ldcgn8mSPxRK2SgGJZDCHeXy8HiZlQATE9Qh1cNfL4pIlovExQ3WiZk6j0WWpttaKE9VJNMNsKIv21zNOYc72bCnMHgBwLWPsDgA8c8/DGDuTMfa/SJ4i3U/92AG+DuA0AH8yXdsP4JcA/gPAbAB/AXAjgBrGmLnrhwNoNoyMnWt//9/SnZcxNpQxNsH8BwCpQVgjklR5TU5g/d3v1+4iv8tj9WtumYrLzxqqvB9fOKeViL1zJ0K5Bo4rkLp0oVRAHm+vqt0Jw8DK+ghZDNPuWNlN7pVhd2unrSRep882C0BVroEIA1kQV6ddVlgToVXKuIx45jerdwqv7zpElygYUZqP7y6rS2OW/O6yOqyUOEmoPowlDOVvAXn/WL2cHLd8dhxm9BMozJwUxuiyAoRL8nHGkEIEidMUqngpT4K3Slvu7T5RONItDuUxY6BkmR2yIRFEc4AqTQAAb+1s1ZYPxUQ+sBm/XLWFJAB59NFHtZ7jFnRljc733HAYUeQKOrJPx/ASERjIiI96Ywksqtmi5cgT6SJzq8dKg9ll73XxGPskBqKQ5kcffVT43g/PnoyZk8I4Y0ghwiX5KCCIYfrihlC2VoVDSnbTuGFgUc2W1O9W1kfSjC4zVOyIuoycj67dTX5mNihUYYZ2ncFmtHSI9RzqOiAnfrHCjg5inUeLahqFRldhwJtG9LOyPiLcX19vtFJOnDrIyvDqz6v6IYCfAdjaf7kGwBYA1wJYYBjGC9k8g4MxVglgCYA3ATxuasN/GYYx3zCM5YZhPGUYxjcA/DeSxBzXmG6RjyQJhxU9ps9luBHAJsufPwvbasSw+NrJGHRkGyqHFWNE/AAenHE63qp5Bs8//zzWr1+PhQsXoqurCzP+7TtJ5SCloST/9jEDXqRfS3sGgHc3foDlr6zD888/j8ceewzvfdgubDgDcFXBNrRsq0NNTQ3wYZ3QMGxdswxNTU1YsmQJampqUFtbi3jbPuE9jzZtw/bt2/HYY4+l3umWH9+LG//3Hzj71v/FvGV1uOxf/xPzltXh3PnLcd3S1/CrR5/Ck08+iY0bN2LBggUAkgm1ADBr1ix0dXVh4cKFWL9+feqd7ln5nnTh+hhw/lCGcn8vPjWyGIZBfDe6HzU1NRjE5GFUJUEv5i9/h/z8g2cfBAAsWLAAGzduxJNPPil9py37j8CtoouGAXztt2/iwtt+iyde24TpP/0TLln4Ir724Crc8YvFaGtrw5w5c1Jt2NbcIfWQU/iEsTP1Tmvqtwm/s3bjdlxW1g2/J/3+Qb8n1Udz5sxBW1sb7rnnHtTW1qKmpgZLlixBU1MTbrjhhlQ7AeCGG27ImHv33HNPxjsBwK233opNew9B1K9/W78p7btz/+tnuHrJG/2bRBQr6iPY06pS/A2s/2APtm/fjltvvTXtfoc1lCYrth9oF17/wbPvp72TeT1dVtYNL+h5f+fz9Wlzb+5//QzzltWh8pYnMG9ZHV75h/VgP/lemz9sxa1/fFt4z8WrNqG2thZ731+HyrZ1+OO/jscndi/Ha7dfjniX+LTVyQby479swqxZswAc71fd9SSSEaJx4nOvvUs9XrubmvH6e9u1555V7nFZbn2n/3t4EX75+aH4xKBeDAvGcd7wIAYbqlPr5JwOeBkOvFOTNqZf+dbNUlbK3lgCsxc+BkC9npqjPQrZYAhD9uYufg4bN25ENBp1dZxUMmJu9VhTmY1kw/weoGD3mrRx+uDZBzP6yO8xcFlZd2qcDm5/X/jGge5WrXda/so6XPXw6gzF83PXfKO/nTxCRNy/HT0xfO6abyjH6e7/moeHZk+G/9V78NDsyYgdFDt9dFGAHsycFMaID/6EqnAo7Z2O7muE30PLm8jffp8ap/9d8Xdcc99LOP/O53H9o2tx70sbbbcl3p00cs3r6dixY1i/fj2effRB3H3VWQitexgPzZ6M3/zPdzC3eiwSh3YjgBgSsT6o9tSbl72T0o3uWvoE9rbpFeO940//QFNTE27745ta3/cwZK4jIylnVTLiEJlPa6AqHMLMmTPxk5UNyjYcPRazvZ6A5NyjHEGxvr7UdxsiUVz6/Ufx6bv/iit//ixue7xW6NTjsscsy/+xRT/P6uG/NqTJiDc+EOueiXgclW3rMMjowA033ED20YN/Fe2BpwZY5gGQg5swNhLAVwCcieRevAPAc4ZhZCcpjt9/GIC1SOZoXWgYhtTdyxjLB3AUwO8Nw7i+/9pKAGcbhjHW8t0CJEMQFxmG8V+Sew4FYOW1HAvgz1/66TLsipfCQPK0QDf3SXQMy5BkfzEnaPM42c6ePry7tz1N5AT9npTlP3r+i+Szdi+6knwmpzEXHS2Lvm9+pux7Voh+p8L0B1ZLQyAYgF397zZvWZ0w1NLDgJXzLtNKfn549mSSVAMAXrr5Mlvtp9rkNjwMGTlKTp5t7k+Abv/MSeFUKMHdNY2o23vY9vzPBqp2qb6nIl2x3odDtsacQERTztEQieKLi9cIP/MwYOcv6DVNoXp8OWqJsCDzPa2gyDjKi/PQ0ZMZbiiD7DluQ3e8nMgmCqIwHADSMQr4GC4aMyTFWkuxwQJMSrBROaw4LXeHglO5xO9fU1OD6dOnA3BGVDOQv1F9z+4eaIWOTFxau0Pav9bv6vSDnXUugnkfFEG2Vvi+l20bOM4bVYrn5l6cds08p8xw+ky+plVjYQaXTWf814taPsvioE+YtkHtH2acMf9F0nzk/a3bjt2LnMnTi3/xKhnd89LNlwHIlFsUsYtI9tiRM9Z9YcIPa4SMmIUBLzb/9Pg8ofoodmgPmh69CQDOMQzDmp50UuFKFKRhGHvhbkhhCoyxQQBeBlAC4DKV0dXfnm7GWCsA89nlfgCfZv3c8abrw/v/lt7XMIwMunxeh+GuL0/EhAkTVM3KwKKaTOpmA0DIlD9lVSKtjFjm2HRKmTR7Naj8FirPQTd5WudI2UkcvSr23Gt6OVlhSzPpAn+fDXvacLizD7FEIi02/D//9B7pDbbbforhpzjoJ+l9nUCUo2QnsZjDa3GB6TCOvb2rNfX56q0tWL+rdcCZDXXZ1GRzYuKIEmzY05ZBtiILC86WTcyKn6xskNZL8RHx/R4TdapuOEfQ73HcdioRvPXoMSy+dnKqLEK0J6Yk5/AwdsLKEHgZoEP251aOD5V7eMEZZcIxoshSKOY0EbW3GbphviLSHTOovWRoKIh5y+rwZkM3Xjxcl2Eg6uRaOs3P1M0lU31Pl/2QgipUkT9/ZX2EXG/bmjts9wPfu65a8oayRpgInH7byRy/u6YRj3/zAtdC59sEpz07dujXFdUBX9N2QkhTclWzeyePLMV60/4H6LN6BnyMzIHjhCG65yJ2SsCYMa6imDS8eLikSEel7mWFHR3EY6EDL8jzCQ2vAmuYNFV/zs2N2mVkm+M1oGCMBQGsADAewAzDMNTnrsnfFQMYgnTGxfeQJOGwMiJ+yvT5CUNDJIo1hOfZbgw6v07VD8v3ezO+q3tv4PhGwgtDihZ4tpXsKcytHivNizjdxBAlK2xpBn+fBVecjdLCQOaClxQX5bXPdIsmimLWn5t7CX40o0r5W6fgG4752SqFjWPc0KK0/1Pt53OAyiVaVCNO2nULqnal3kcyJ+ZWj0WbJXTQw4B7r5lEbmJFRLFzp1DRt59OMKCZr6ty1oqDPnxuXAmem3sJSeUOJBWzryxdJ5zf1DrkThsuH3533fnScDgAOH1wvuMCwnZhpyC401wvc74PxV5qZQrlCJfkC2Uq1RbZOtZV+CjSnTOGFKTW0uJrJyNgyevzeRne2tmKFfURHOoLYEV9BDc/RVNrU7CTn2kXuoVtZeyHKujmm1GlJ/h3dfrB+j47W446Mro4ZHM8JJFtfP66lQ8pUqivvvpqAPo5ucVBn7LICnfs6ILvfwGfer/0sCSphc4+JEJBgO5vXuZAF07XjmwmbWvuIMfb2juyEjvW/jmjTCyTrboHVeTdet1HqGuSdNiTDttaBGNMHCBNwzAMY5KD53iRJNG4CMBVhmFkBN32G2Z+wzCss+NOJOeGuUrkn5E8lbsRyULMnCXxBgBNADLo6wcSS2t32PIc8OsyemaKdrSzN57yiNiheLbjldZl8HJCvCALCTtqEuB2asrwhEwOnpC573AXuo6JqXEBuvaZDJQH1udN1s0aCFi9r5fvayepa80otxT5Nt9D9hwr1my1V4jZCXQ84LI5Yff0F9Cj9rUiFPQhStAtW41+K44S7JPm6yIlxozTSvLRteHPWFpQIKXzBZCqlSea39Srm+eA+UT51Q+aheyZR4/FT1gZAqr/RHAim3TDoKhRtivre4hE+ykjS7Dw6oladXyoE4Rdh7pSoa9JgyV9wBMJAzGLG1lnTuh+lq1Sb+cEKZs26O4zMlkxt3osblv+nrQNVNmLbMDnm2h+nCkpiWGYfp8NUydH29FjmP7A6rS5uXDhQtz8w19mvDNlv15+1lAlfT6/v+6pC9//QvkBZUQKJ6FyyuopCxluau/G7kOd2veyy3jMsbeVfgafK6Lxvmx8OQbl+7V0Q2v/XPfYeuwSha1bdA+q1mhZYSCNbZWKQ9EoVXjS4MR92wa9g9hhAM7S/K4IvwLwJSRPvAYzxswFkzmxxzAAdYyxZQC4i30agC8iaXT92fT9fYyxBwB8nzHmB/APJOnuLwPwdafFk82wY6jIPAmU11Il8K1hYmbIanSJNg27YRA6ws1JMVSVJ8ecPG+npgxFoypie6OQjbK4tHbHgBldQKZCJ6sZYobsRIR6jkgwG3Ae1qIDOwUiqTkhU76o+9sgpUthcGGANLw+cXqJ9LdRgpXPfF3mKACAilAQb5d9Gj02c3rM81u2Dq0n7XyjpfIzqXcaCHZB6llWeFjy5NBOHR5APwxq8sjStJBcQC4P7YYJFwb9aUaXTHbL+pnTSItqS9rxOciMWEpm8DBGp+Gndmjih4aCZBt0cMEZZajbexgMybG9w2Zeq8wJ2tTejXnL6nCkOzN30oHfJ4WALznfqPkxTPLu3MhwEr4uQtxAhgPz17/+tTDENmFkhr7ytSMzRPl3+B7wlaXrlOzIfP8rDHilBWqBpJPKXKLDLmQnl1RdNApm5kM7eqisLiCXTSJ9MZs8bkrHsF6nWvbu3vZUyo0bToCTAduGl2EYl8s+7yfCuAPAdwDEAfyvo5YB5/b/PbP/jxX/B6AdwEoAnwcwB4AXwHYACwDca2RS3M0HcLi/bd8AsA3AvxmG8aTDNqZg11ChhO5USyE8M1SGhayehrm4H3UP84KN9sRseaVFbZtWVZHK/XCykTZEonh9i5wS1OdJP0/W9T7J6FLtwKmyqFNfyApeh83ct5uajmBPa6dwUzJDd8O06/WfWz2WzGUYKJpuJ7kRojlBrcGKUJC8f8DnEZ4w+TxiDxsDMJLw3AHAz646R/aqZEHjsqK81L9lIU08r8upoqRThoFiDKP6l3qnaE/M9VNSVUHogNeDWCKhXcfNCp05HvR7MsiSKHlolsEXnFGWZK/de1ipiK02nTCrDBDZqQUPfbWXFyNWiimIZFHAlwxj7I0dX3Mr6iMoL85DYcCrLGwO0DJVdJ1aMSrHiuiE8+1drcLvqnKu51aPxarN+zMMXF6byomTR4YLx5SlSJdE80OmhPM6UaJ9XpYrmOfzKOnQ+dzc/eQP0ffZ7wu/w3NyrWunrChPeDKV50sny6kKh5DQSPrh+5+uo1JUnFvX6AloFDHXBafLt7s3UjT75UWB1PfdLmqvG3VFGWincOqWNlxLWGCMVSBp2HwbSfbB/wPwc8MwHAWfqgy8/u+0A/h3G/dMAPhF/x9XodrsrAtyWlWF0JNwh6IQnsywoIq7ApnF/az30A2ZMYdBiBaj9b5OC5PqtkeVT0LB5/GQNYjswGnNKlV4mAjWorv83zrC3rphFuT5hGElE4bbe5+qcAhTCaa8garn5VYBVOr0V2So8PvThafF4Q4GgM4e8anL/OlnAYDUy3/dhSOFp7DXXTgy9W/K4VJenIfH/+MCMqRJB3wMZco6dapEFXS/7sL/v71zj4+iOv//59lLbiQhAcIlXEQQpKhFvKC2FWz7tdAqrfpTKm0VrdaC1n5rtdXSe2mtFrVWRdt+K63WolUrWrQFq63gnaqIgYhcFFECBAghCbnvnt8fsxNmZ8+ZOTM7u5tsnvfrta9kZ+fyzJlnzjnPOc95njG4/dktKWVc19iW1giyifV9cFurMaQs1TDzokuqcqmuKO7pdBaEqWexvNM5ZZ2momgIw8uLtEbATZlVRpM5+KZ6LsBhg151X3ZjIkTAd2cejY27mrU7ZrLOe92B1pTAUYCRHHgvoGUQqwwH2fY9ik6daruJl7rniEElUpeqIxLrDt/d24JuB2Mn6A6m2ZFVe9uor/ju3pYkI8Z6r7saW/Ha+43S444ZOdA1Ubcp08oVKzBv6VrlYI3s3Tn7uOHSfFtfmjY6RU/cBmGAw+2f0zsikx3wbvRM0khirou5jt1r26gaFNx/qLNnIMePK6WqT1Jb14Qt9XL9s/c9VLPS+UDay8+IaDgR/RrAuwCugrEua5IQ4qt+ja6+iJvbkn0x+XWPrsct50/xtShTxf2v7HDdR7WAWNdlZsKwMk8J9PxQW9ckXaQuw+9IfmVJ1NdxVvy4Tpq4uYfJWFW7R7pdJ/iJfT9VYuxfrXrH83O8ftakFANYp2x0F8LbCWqNiCpAh2qkbcue5p4ReTuyyIMm6xT59V56t8H1PXr53QbpsdbtN8yalGJgFEQI9106rcelyQ/WZ+j0LK2zb1Yefl2eh+Wldxvw2IKPo1qigzoBDpz0xl43bXdIbA1AGfpKV5dkSZKLoiEs/Owk7DrY1pNIesX6Opx1x/OYt3StUs9VnSanmQiZzCp3OXPw7bpH1+MLU0ZI9zENetV9fXfm0UlrbuICuP3ZLVgwY7xr/WPFWhfNnDxManTZcdMN1ej93ub2FD3xm/zdS93jtD6ztq7JMW2Jif2O7AFPvGAdRJHhpGcq13wA2FjnnO5FJ1DFhGFlmD9/vtL0W7fjgPS9WVUr94iRbV/4WedBbeBwH0rV1sowy9Nr0BidJOY6hOhw/ey1bVQ9GTMCpldq65owb+lanHXH8ynt2pOJv5t2yWWx91+DnvHtTfh+8gmXwhsAfA3GDNefAfxcCPFeQLL1KZymT1UvpBkNLAhq65qw+6DzaI6J7CXUdZlRBSXIVDhmN7pi/gyvE8cOQp2PPDZ2dz/VTJPbLJSTe5gqBHaQrnuqc/kJOexlbZ2J35DSgL6rgtO1nWR1Or+fEThV52rdjgOu79Fr2+WGl7ndvJfqgcXojAkURkI4duTApHtaMGM8nt64Sxm62Mr0iVWoT+SSsp5jcnU5bph1tHT2TdWhUUXyW7fjACZXl6O8KCLN4eGk52564zX0dJfi4ejqkkr3ZXIIAKs378WrtnQL5jN8euNu6TUKwoSiaMj1vkyDy63D0t4Vx38VMxQbdx0OyqO6L1U0QD91v2mA6OKkGyr3sK6YSPL2mFxd7ikQkxUvdY8qeXdja6e0HGVMn1iFclsQgwt++5IvjwnrIIrs3g85DAY6RV91Wje1eU8zHr/yE0n5SK0upea1F8wYj4HTf4jLHpF39lXtkkou2XbTQ+TGf25Szny5udra/RqsOuPV6HGbXdXFmi7Ha9voJIPX/oZT3629K44b/5maPsmK/ZmlWz4RxUBMb8BPVMMROGxwRQDcD8OlsF8aXCZOFblb9KJ0MRVed+Gt7CV0cpkxDQ2doATp4rXjFJXEDNVxvfPiSmDFdPdz6gACwDl3v9Dju79pdzNWbdyFx6/8RI8cE4eV9USQs6MaeAzSdc/JiPDzHL26I6RjvPvtNAF6Bp+x9mJ3UufAXJjulJsnKKzlr1of0d4VUzZ0LR3dmDl5WJLRdOHgD9Ew/GTHXFsEOC6anj5xKP71dj3Wf9CIuBAYXFqIH589WelOHFdUSOZ2Pwa0m9541d2DrZ0pRo3XmWxT981659sPv+kYPdLugu420HTcqArcPWM8Lr//NUdXKbOb8b5DpDIT1SCdW/kFXffrGiAmTrrhVqdby93PYBHgre5RubNHQiFPawPtMk0aXqY1Q2jlxCMqk+oD2b2fe/eLyuNVs9qA4Tal0l4CsGZzPZ6p3YP2rhje39+KL08bjX2HulLKfcmSP2PCsI95apd01sBaGVdVihOPqMSeg23Sdra82PCEUbm5TT2iEiMriqU647U+CypCpDVdjte20cmdTyW3qn/l1ndzS51ilr31+jrlEw6RNLLloAGF+MD16NzgZ8ZrG4BCGHmvbgTwHoBKIqpUHSCEeMOXdH0Ip4rcLXpRuosVvRgrqpdQ9cL+4eKTpLmR0plxcMJrA15WFE76rjuTonKDcsMMNe7UATzY1pWyYLqzW+CmlZtw/1enAfDuv18QId9ujTLMiFCyTk+m1mZZ8duBMyv94eVFCdcYAYCS1tE4vUv6Bp+9YIzvRdEQ2iTvWkGYtF3CzPOcMKbSdW2cagF2TMgTsAPGuhgzVYJpFJ32kTGYNevwAvCz73w+5dk7RaKUGQjN7V0YV1Wasq+JWwJMPwa0m9547cx0xQSeuuoTnjvgdrzO1JvyutXd1vIYPrDI0fAyg5zo6KHK2DGzG9TWNUkHj04bN0QeqbK9OyU8uA5e6ns33XhEo063pz7wOkvnxWArLQxLZ4NKEwOZKj0dWVGEE44YpAy+UlOXGjrcKbF7JAwssgXxkd17p4P3iJObXtQhgEYsLpJmydu6YvjjS+/jhllHp1x//PjxOGKE2niWtUsLPzspKS2Mk7w67+iYRH5E1VxJWWGkZ+bXzLVlPidZfRYiY0BAht/BXyv2foGufprt6H/fk3tUqKJrO/Wv3N5ltzV2Y2w5K3XLZ8roCulaua994kh843bXw3OCH8PLdCCfCuBhl33N+iDssl+fRzYKAKAnAaAswpEZvchLFC0ZbgpfFAlh7JABvsNu20lnxsGKrMy8dpwi4WTV0u1Yv65w4QqHCBOGlmL7/lZpng23KG9b9jQrR7utrldeDUwhjAXOfl0b7UyuLsd3Z6a6jtmfo9fz6uLHeHdrOHUW4OsYfLJQ2p3dAves3oZpRw6WGksDS9zzvgBG0s8zjh7aU8ZuIcZPGqsOmKNy5TMxQ4MDQHHx4UZtcnU5xgwqkbplqcpH9V7dvHJTiiuUWfaqkMxmAkw/sw5ueuM13DWR/zw8VrzO1Jvyqsq7MBLCZ44Z3qMLOkad2flVrXXS4d29xmzZTSs3Sd+B5o5uqdtjXWMb6uDNZRhwNpSrK4oAkNR9VsYbLu+Deb100dWXqCKzazQcctTT/Yc6lfcqq5sAoLggrAz8Q5qrZZyC/plrnmRRip3OrnKJ/PUzWzD/jKN6vtfWNeGP7xBqX6mR7m8aMPZARGb99tMna7G/pQMhIkwZXSEdENJ5R015VW5u7+8/5Diwe8v5U5LW7sUFcN2j6zGuqjTleaoGCsIhQjREypx9yaSWvmkEyoxDQM8ALSkIK/VP1b9yepfNda/XPbpeeV27rugMpBRFQ/j5F47Fms31+M2zW9HeFUNRNIz//fRROL3KvT3OFX4Mr0sDl6KPs62+Bd99KPllXLVxNwCRVEmGCCiKplaQ6a6PcjNWiAgrvzXd9Ty6DYpfNw0rqpGTW86f4jFPiOg5n9M6CXsHp03RIIi4wG1zjsfZdz4v/d0tytuEYWVKw8taRarcsFR0xURShW53bfS6XurJ9XX41apkoytEwC3nT1FW0F47VU74Md51Gk63d8npueno0Dc+eZTU8Io6rNkzKYqG8NcrTksqX7d8QDfMmoTnN++Vjma7XdGaMmHt2rWYMWNGz3dVNKuSwog0yqJqoMJaFnb9UK25GTN4QM//Xo0eN73xGu56YHH6QXYA7+HXzVFwlT5+5pjhPeUiC/8twzS4VOVeXhSBgHOOINN4+68iRPrGnY04ddwQvLxlNwoLC1EUDacMOHhpz1SzBHdcONVzRFy3OlWVr/Ke1dtQ82EjOmMCBWHSCl2vhcKS6YrFevRU5j7qVH6qkPlORlNXTKS9/nrF+rqk2Qfru+4UWEhFR3e8Z4Z05uRhjh1yABhcWpC0j/X646pK0dzehbgA4kIo82up6jAr5qCQ6r3sjAnHgd1VtXu010Cq1u/G4sIxKXSSPN2p5w56HawVp4HL2+Ycn/IuE4xky6YL+7iqUqXLtH1Q5NV31WkaJg4rS5rgsEbJbeuK4fZnt6D6U4P83GJW8JPH675MCNKXeei1D9DelTxNKot+FhfqJMfprI9yW3viNwCFE+mOEjsFHLF2nLbtbXFMNNjS3o2Ll65Vdk5N7C+1qkTicF53YIY8deoANrV1STvnZhJKQO2G5YSqQjf/l/2mchuTRdSKi8OulED6YdtlKRSsI6a3nD/FU5433XfEaT/Vc5s5eZjrKOCEYWXKUThVkAYAiIYJs44d4TrqKMsH5BSuX5aU14o1x91ll12W9JsqxP26HQd63DasDfb+Q/JAAXas+qHKU/Tytn2+83XpDPrY66YQBJ5Yv0t5Tj8ucna8zNRbR8F1BiB09d5c66E650NXnIZ7Vm9zdN8JJ3wNVTrV0S0SuhhGZ3s3WhRGnFvaEZMgBvFMVHVqOET43HGH3z+rsbWjoTWlHvSay01GbV2T8p3Z23w4VLfXADMqN1K3HFUbdqa6J9qJhsmxrbVjvut+DC/gcAJlp4ERk5b2mGPEQJ126kCrezL1N3Y0orauSenm1tUtb7N1PGHs6M1ouWM/dxDrYEsUERedBi5162aVe6jdJVPlvioEkiYSVHnpHnqtt67wCjCPV39mx75DAMnDc9tRjVKn4wLh1DkD5AEoco1TBWVdrP65O+QzTyZN7d1KVywTr26QThXT/a/swPwzjnKsZK6fNQkv2yI3FUSSc7TpzJCkK6uT25iqobMek85Cetmom2rE1NoZcup86XZund4l+3MbWl4EAvC95TVaa22++PuXpb87pQcQAimGqhej9oITR+H5LXtT8ie9v/8QTjlyMF7ctk+aD6jUsv7xmmuuwX33HR4zU5Wjvf9myqQKoy/D1I/J1eUYP6QUb9uu1RUTuHnlJtyXWO/oFa+DPpvrW5S/HWjtwoHWrrRnc726OFqftVtnRVfvnWb9nNahWCkvNnRGtyut2s+adkTm1WAfcAkiuq+qTi0IU4/Llc7sCpB+pMbz7nnRMXGweW7PLtcKAysW13NDdaJC013aShABtXTstk4Hg0eVR9Aum+ocVsx1rir2tsiNaR1PmJRr+TRY3c4dxDpY1buk43Hg9s6o1tc//PqHSbPcTqVj7S+oPIy2BhgFOmjY8AqAMUMG4EP5rGgKslHqdPJBmVw/a5LS8Cq1BaDoDbhVUGYur3QIETCgMIITLDNNOmxx6KjtszRMqkpmcnU5brtgCm785ybsb+nA4NJCLPxssguZ0wyJF8zy8tJ4OzWWwyw5gFTPaGh5kWPSX0DfLfCmlZtww6xJWi6Nup1b1WJmu3H3jU8e5doJs661mVxdrmy8nRamy0aj3RpHt1H5uDBG5mUuZYc53Hhaja7auiZPs61eO1dN7d09OXfsRpeJ2/o0k3TXGNbWNeFtRd4YO+l0tq3GztMbd2t1dK0GqtM1dfXeadbPLue5d8sNA3PNrJfZD1WIbdXggsplOl3XPlWd2tYV9zS7YiLTex191Kn7zHPrzHhar7lXERnOZcJLGl3Rjp/BwKAi87mhur2Swoh2VD7doaMte5ql67tN7Ov17fkOtV3onSKieMDe3gWxDlb1LqkGdQC49glMVC6f9u2yuAiAsS5XZ82rW7LsXMKGVwBceNJovPHvhiRFMBIdJq/xMsPDAkhxwUrX1WJydTkqS6KK6XR5hZqpwAk6OFVQXiOEqYgLYz2DLHeO6qUG4OhfTRptU21dU1KHvq6xLWWBbYvC1csJpwrfy3opp8bSeueyZ1QQoaQ8LKqOk25n/fnEYIHO7I+90leFRf/e8hqsqt3j6Nqn2wmzrrUBoOyMOnVSZaGN3daaBaH/1lm42bNnY8WKFQC8J8acMKwMW/Y0K9Mc2KlrbMN597yIydUDlfvonCqINYZe79Wqt34C1tw5dyqufnCdVjQur7nCZt/1gvbaD7fzRUIEWRfe1JlISN/wkuWamlytTjsSZB4wmexOeCk+ayLq2rom3LxyE9ZYXNpV+qhah2XFHOByc8/SrQvcHpXVvVGJTuNmwWxjnHSdyN0oBJzbY8A4hyztwwcN6oEne/unIwdgvJevKNYXAUberONGVUiflxfXWdItHBesywMAb+tgVUtUnPon9kEdr/W0ysXSur22rkmpD3GhdoW279dbYcMrAMYPLcVjCz6SYkw98vqHPZGWpo6pTMqRYypukAEMVO5AsgYpk4ETdHCqoHQXk3vB3rgXhEO+fKx1miY3N7LauiZpSHI3nCp8L+sknNYE1luiOcmekWz9mqzjpDsSKqCe/ZB13KyV/qzb10jXR8iihcqeiVvFLDNe/VTmPz57snS9m6pxTGfxswrT6AKcjeKCSEia3PTZt/coo6ZVlRVKAyysd5jVmqoxC53uGkPA+2yddcbdb/2oM6LsJ1dYSUHYMTCGF1QJ3M3tkXAI0NBBVa4pwNtsSBAua05J6f3wyrv7e2ZunRLD2vVRJ5y/dQ+nKHRB1gVu741TNMwTx1Tg0o8f6WlNLgCtEZaiaKjH/VRlxIVD5Cn3WDRMvvsxC2aMx7/f3qP8/bhRFY7lqOsKXRQJKT0PiiL6/ZOVG3bh6gfR8zy8rIP9Z80u6Ro92aCLl/xdQbjq5jNseAWE9WWTjVKtVUSJClppdcnWdZ1GjVUVVDqNMMEIhSqr0KznLSuOot2jPztgzmQ64+ZG5nUU3mTM4AHKZ6NT2VufRYVidtQ6yis776zb10jPbb9nL2tenNY9OumPW8fO64JikwEFYXzqI8OkHYtCh5w1MsYOKcG4qlLttS5OMwVesS6Qvuaaa/DrX/8agDpp5glHVOLnXzhWWt6TRpRLc6V8ZEQZhIB0bYhT//OGWeq8QCY6awzdZqWcEoTasRpD6dSP1o6PGS2PICAS+eb8Rs2bOqZSuZ5V1WdWlY/qXKZB7HSt6opitDTUY8bUo10HeGQRCzOVO9BJZit2GUJkhFyP2WYfzIhxgPMIu11PdcL5Wwe40smN5AXVuUwdqVe0h5NGlOFvVxrRc2WRJv14zIXJeOZWnXz2T4tx4sQL8LqknpkyukLaxpUXR6V1T6kkOqvaI8hyL4lH53Q/6S4LMTnRIVXIIJecV1a6YiJloFHX+FPlibT3c/zoqGp7mACZuWm+NpkYeOxtsOGVAbw02irlfO6des/RttwSlupcN8iK3u+osZeR0hABZ320OqmCVUXusjbufoNbTBiqThhrvY6Tj7XfMk5nPFfXZcXtGrqLh2WjbnWNbdJGVbXu0R5p0K4/Osad24JiWUewKx5XvnPjhgxQrluS8UFDGy6//zVlBE9Z4xjUuomopQN41VVX9fyvesZlhRFlg00Kl5iSaBjVlSWe5dWpz3TWgbrVL7rvjD2VglO9rBORMd2orzLmnDhK2VErih5ex6taH2gtH9W55pw4yvFakTDwh4tPQkFrPY466qiU363I6gBZcAvd2T83I9upfKx8d+bR2LirGVv2NGNYeRFefnefNDcWoFdX2+s+VTh/K+Y6SLcZgyDXUMmMW512gTQ8A1QeHKoBvuPHVOJvCz6WtO2qq67CpkMl0jbi0o+NlZ5/TGWx1PBqbOvq6QOYej9z8jDH6KaA4fl33j0voliS9gdIrlPT5WPj5IZXmPzl4vMzcK4aUJs0wn3dopuOqgZTiOSmOiWsXrd3bmhZAZrau137MgFPgAdK7wt3lwd4MWpUytnc3t0TCe68e17scXlQUVvXhGZFdB+ZkaG6bhAjjyZOL6sTC2aMR1FUTzWJCHfOnYqV35qOO+dO7emQ249Padw9+rObDChyz/sju749d48fVEkdddAdRbJfo7auCVc/uA6zbl+Dqx9c1xNO344soIXZ+TSfzaIvHCt9LtfPmmSsYZlSjUnDyzB7SjUeW/BxrKrd46g/PWtfplSjrEgd/haQP5OiaEjq8mYmS5bhdWQ3FhfKkUtViGcd/Q+HqKesqspS15AZHNbxNWsOz1S+v/+QdO8t9eoGTxUZcEt9i7JsVW+YboPo9B6bwXfc6hfdd8ZMpWDiVC/r1MeZwCqfnbauGGrrmjBv6VqcdcfzWLG+Dtv3pwZlMctHdS5rolwZHx9fhcnV5Un65IS9Djg78W7b33U3Q9Y0EFasr1O2i07lY2XjruYemcqLo0qjCzg8K6NCFgijqa3L1eA310HW1jU59he8tIVuyOrom1ducm0X3t7d7KjvTh4AR0oSGQNG0Cs7a9ascdVLOypXPVl01qdr65Vy2vdVGZJdMRHY+3//Kzuk22MCOMKS69ALXgd1VQNq9u1eddRpMEUVgdNcv+rWPzrUEUuqQ1Rtf3WFXqTxXMCGVwZQKc4wmxsXoNfJcjNWekatFBXggdauno6zWWF4fVn84HdWzdqhdkNmVFqPVzbuigqnMEKOjeYORafVfv1bzp+S1ME0c/fU1jX5LuN0jGLdCtm+oNze2bEnXTbR6fQ4PRd7B83J5c663Tzur1ec5qjP9mtPn1iFU44crDR+VNeWvcN+eX//IWkDbpW1SOHaevzoip6yMpN+2tnb3N7zzldWHjYwVWtQ6hrblR0KVXLaWFwon2tFiXyQQjdpseq8gDEqrTJorc/OyztjPU4VGRPQGzzKBG7v8Hn3vIjVLvkMzfO4vVuq301D1qpPVuwDNSr9tr/rbsfrDOLp1nE6KTOAw/WHrK0kGEFFrO2KWV/qPAOr/E6DoPZ3QNXJ1MFeR9fWNWnNEAKGgaZC1V4SgAZFFEZZUIzKykrPfQYv77dTpEIv+wb1/u9XlA1gDPD5GRr22kdwGlDTOa9MR90GU6JheXtlpj1y6xN3dMeT6pAzjh4q3e+oACcRgoZdDTOAkTh0d0qwi5ffTU0canfH2NnYJl1A7dRAuM1mtHXFesLpWl1xgkpcaWJ3BVGtr9CpHMwX6/X3Dzj6OhcrOp2urj6KGa/BpUUoCJPSVeSgYlbRjlsG+xOOqJRO8asoiKRnFOu6rFhLxUtACt1OjxcXLC8uDF4WFOu416h0NMhASXFxeMG7zI3qzrlTcd49L0n15FDn4TpC5dpk9f3/2emHDQknNxaVq4rKjbm9K4arH1wnzcU0vLxI6mY03IPxKtMXt+A71mfnFnVNdZzbQEKQLtm6OL3DupG+zPMAziko3N69kSNHpvyWbsCmdNeR+MnzpzqmuqIYf7j4pKTgRTet3NQTCOiEMZUpQUX8rE3ZsqcZt805Xjs3km7ETBl2N9l7Vm/Trs9eU4QABxJNqeREAuoZKdks2ciRIzGhPSp9HqoBLy9riYuiYbR5ML6cIi16ff9l9ftgh3Vc9U3tjrlZZfgZOHcaULPiJ3+XLKDUqto9ytQrpYlBhR5D7s7npeuEIyFKWr+nClR14Umj8aB7EeQEnvHKAJOry3HquMEp21UuTDrWu5Ox4qUSsLtqqUYevSKbHXl52z7pvk6jyXYuPnWM4+8HWrv8TfurwrgKgeNGVSgPa2rTiyrm1lH4qsJnXYUsF5QXdF1WrK5ZXvQqSBdVE6+zsrr67NZBcrpG0EkZaz5sdHSjemeXXLc37Trs/uP2PrV3xfFbS73jpN+yUNi1dU1oUUTTiwko3aHfV4R63uEQAloHnVkKk8nV5YhorJcgGIMq5j246b5XfdeZCXLDS72pwiwflcuwuV11LXP7qlWrUn7z61quc7yOa7xO+dj1Q1XHWI0uk7Xv7Udze3dPihK7zvsxxoeWF3maMVDdo86SILubrBd5ndwJHVIYorFVnnBY1v6uWrVKeX8vbturnD391qcnqAVIUBQN4cKTR7nuZ2X4wCIUR+UDu17ef1X9PnOyvK9nnv+CE/Xlra4o9hWRWhUszL7d66yW7J6/kRg0cEqJYdaR96zehjGDSqT7tHfHk8573aPr8a1PT0B1RTEKIyFUVxTjlvOnYLzGevxcwYZXhqhXrC1wq+zc1gfJ8NoJyMRorazRVOWBUWUul/H02+5+2fes3ua5Y9OomLlqbOtyLGt75CsVbh0FL2UAAN0x4eju4Ya94lStC7InUJZh9+4M2kXVxGtlr4tK/wsjIddrqBKY+qUzJhw7nE4hhc0OrY4uRYeM7vnfSb/tI9RmA+o2UizrYKs6a37SOFhR6aWs81Fb14RuzfDeayydaS/relSYddIZi/+Ds+983nF9kg5e6wyTEAFHDhmQpNu/W/OudF9zu+pa5vZrr7025TdV/iqVO6+ddNeRqGSuLIkq6w/dOkbHqPQz+GSGrNcdNFLd44ThZSiIuFtfVpm9yOu0LtPp7VLmPZR0vq+99lrl/XXH5NGAa+ualO7vVWWFSc902z5vAz67D7ZL6z2v7Z1Kd/72xk7lMQtmjPf0vssGCnRoU8xIyrZ7Gaj3M/u7t7kjqY58zyVAjUl7Vxy/WvUO6hrb0NEd78mbuk3hRtkbYFfDDOE10ouJuT7omw+t65nmNtcHWRPwWvEy3Q4kR1QKCi/G3POb92pf/60PGl332bDzoGcXF1VOotbOmKObUVgzMoDb1Lwqe7sTqnxXuljdAf7fPS9Jo0E1d3T3TOMPKy9CQYRSkoCrwqBngkxEh1O9m/ZkyTJ0k8rqUhgJ+V4Laf6+1iHZp8nebRsAnAHA2Y3OnvPPSwOaIq/DrHI6qN4tWefD61oMs2Mqu4a5rkeVt8qKmzurnwhkbu+/3TWKAJw+saonf6TV9UcVVtvcrrqWuf2SSy7Bww8/nPSbau2gbvoFpzZTx5VYJfOB1i4s+sKx0lDogF4do/OOem2HgcMh63X1QHWPW/e0SPMxyTBl9iKveWaZy5wfZLlFL7nkErw9+TJXua3cs3qb0h2woyuGld+a3vPda/upOq81+qmJU8RNle40KbwICIZOptve69ClmK5Ubdcl267YsmUdD732QVZl8AIbXhnCrePthNv6IDtmo/S5O57Xks2MqCQbHfa75stL2FsB92SOJjoudh3d8UBzkjlVGsePrtA6h1NHobauSen77oRuw+pGbV2Tcn3ZuvcP9Py2aXczCiIhTJ84BPVN7Un3oOrEZIJ09FJGOu9m0Bw7ciAA+XqbnY1tjkaKOYjj1rEtiobwwMKLe7476bc9CW1a7qZEcvl9RhQ18bI+1U8H4Ll36rFgxvi01sDqGKxBd06sYdLt8uqmk3DDfHJ2owtQrx3UDY3tZx2JFScXpm8+tE45cKmDzkCqXS/f2d2stYYqCD3w4opuyqy7vhwwyla1Bs8JLzm+Hn74YRz3k1QXVrvcVpzKLtghssOsqt2T1P65rW30mhLAj9y+869mqI4OMg2CX3bscw+ElivY8MoQbh1vpwbdzwj45OpyREKArheP3TBJZ2F0bV0TDiZC6Fpf4YJIKCXAiM69WBlcWiidmbGiatj9NmhOSVcXfeFY7fOoOgp+IyIVaiRv1sFpUbV9e2d3HAOLo7j/q9MCubZX0l2wLyOdwDJ+koU6ncvsVMpGnlWdIPuxTkKZQQKu//qXsWLFCgDyUM4m9s6NbgMqM1yjIZJ2hlU59LwY2LozoV4SKJuYa2EeW/Bx37OtfvI/uXHCmErHxfZmmHQrZpk+9069ltFVmYhEqbqWmX5h9uzZPfpkogry4rSm0Eq6AZ8GFEaUngzWQDZ+0B2sserlxO//QzkLaMWLHqiey8Bi9+TAgHwNpJn7crtDRzVEpHSZc2LskBK8J3HxM9MfWJ/t7NmzccK5P5TeX4jkiYud3u+JtnJ1e390sb/bbnlbVboTiwupB4XZznuR129fpygSkg4Cq6LpAnr1tJ/ZX7+omr9Bpao0K7mHDa8Moor04taR9Oum6NULyvqyekn6bEU2kmp1ybl55SZp5aHb2Fz28bG4aaXch9tE1bg5XaMkGkKrpFIoccg/dOKYCk8uBir8VpIqI9YrXq+/ZU9z4LNOujjppdlh8COTXxdGVULQsMLIANTRsU6w6JPZ4Vz9Tr3SBcVKJEz49sNvYsKwMpQWRpRGmul+Z+0kOwW3KLMZZW4NaCQEfPa4amnZlxVH0S4ZNCmThJPPhIEN+E86ns6MOeBusPqZYb3gxFGOHTH7e+1nluvr08c5Xqul3UhNMuFLP0vpOAcxk5yOa7HKoDdJd2bplCMH442E+9fUMZU9Lpwm9jpSpzn2Wj6q56KKIGplxsQqXHDiKNeE1jIi4RCee0cvD5aVQQMKpYaXzBBesWIFnlxfJ72/7848WloPOD3xmp2NSTrq9v7oYu9XqPTq6Y27eyK+ygYUHnltB/740vspx31p2mjP8g71meZk0vAyvL6jUbpdhm49LRtEMaMaPrm+Lq3By0kjyjBhaFnPeesOtErvoRfnT2bDK9voGDh+GzCvSyesFYjfdSay+xEAyoujmFxdjutnTcLL7+5PMhq8hEZ/6V33tVCykKxu5aUyUmNCnWC2wdaw+e0s5noa3uv1h5YXZaRTrINK//ys69PFycgsjoZxAKkdHFVYXgAojMjDGFv1yexwzrp9DZo0nk1XTPSkiFBx5JCSHrkXLlyIG2+8EYBDpDGkJhw2G9Bz735R6tJYOaBQ2VFWdYRlM9R+B37cUL3LVgYUhKWjvul01GV1eIiMxKjHjhzoa+DCbbG9vUPoZ4H7S+82YP4Z6muZHRzZ+5aJFCVekAVssOI38qrMgF373n7Hfdzq10iI8NnjRnguH9Vz2brXPZDAy+/uS2qLN+1uxlNv1SnXMllp74qhXS+TShIbHQKr2N+vhQsX4sOjzpHua+qlHaf324wibdYfS1/a7iYuomHCrGNH4J81u5Su/fZ+hao97UhE3zPfE3s9pgr2sX6nEXTHS3ANv0ZGqyJokmq7l3paNohy9pRqZdmGCfjcR6t76o6te5rxtqRcBxREks57xuL/SGXddVCdhijXcFTDLKObFDYT0dys2A0TVaO0s7HNMUqgnsFmf8n0LUQ/QSh0QquqZo86u+Pai8RVldAXf/+yY5n5XUtU4uAi5gUv1y+IGDOA6YSJTgeVXqrW9d2URuRHQB3613yWzZJF4YCzRqvC+MsMmSDD8tc3HZ5tmjt3bs//IQf/fVWONNVkQotDb0zVEZa9X34Hftxwc/UiACeNHST9LZ1nIavDn7z6dPznujN8p+5wqwvt0Sr9lN3r2xtQW9eEF7fKU4FYkdUBQaYo8UJtXZNjQtp01nDqRDT0auQOLSv0VT4qHdAJ+tPZLVLavXSXDbulKHGKYGp/v+bOnau8P9V2t/fb+g6s1wjUVVVWhDvnTu1J5quDW6oWVVv5X5vxbvLG+wdw8dK1eH6L/uzcGzsO+EpVsXmP3GC3piuxEkQ9rQpQFhNGWZp1h8ozo7Yu2ZhX6YCOm2+uYMMry+jkIwH8NWC6D3PGxKoUw0RVeTS3dzuGP3a7n3tWb0uKigeo85nJ8BN6urwokl6Dr5w6TN6uCp/sVmaTq8u1oyNaGaBIFu2VydXlqB6o55pw7MiBKbMgJtmIXKQKI61a12dGzPSLWyfLad2VClXwC9k96OZb0+FQZ6ynIa6pqQFgdFCdgnHUfNgobbxVAxUd3XFlGgdZ5DLVdt160StugR1E4uMlX5wuQRshbkFU7NEqVWVXXhRRjpC3d8dx3j0vOgaqsKKqA1TpPYLIZya71nn3vOhoRKQzcKnT2fRcF/oMXqAbITKTlBVFkgaE/WJ/v2pqapT356UOtWJ9B3R02jyfudZRhmywwRxkUa3DlulHm4OhvmbzXk8eTM3t3b5SVajKRADS8wRRTzs9MWvKHNUzb+uKo7auqacu2dss758E1IxmhF4sWn7iNSmsFbdGq1BD0wYUhHHfV6elNELWyqOsKHVmRTVq43Y/mRrJdkKnElB1bouiIeVIvTW3RW1dk2siWKdZIafFqyqOGDzA8zEqdCvKde8fSMrtJTtHup0pp+NVs7+qBftmxEy/ZFNfx0iep/1+fdjnSZgN8a42Q9/cymb7/lZ5463oKMYTCZTTyU8FpFcvOiErYzvrdhzALedP8eRhkAkDwg234Dqr36lPkkNVpg9dcRpKHAZxPM3cSOoG1azxk4m/QeiLFbfZpjAhLaNXp7PpdYDAb6CkoAIspcMZRw9NGkwol/QX3CiOhqTPRHV/qu1ObaK9/tCpSs36wul5ytoCc5DlM8cMlx5jPZ9Zd2QKL94oTgPA7V1xXH7/a1p1ipd62uma1hD6UQej+qaVm3rqEtVsb3WFPAFzbyD3b3E/w68boZsLFGAsgHXDHi7aLtudc6diZEWx9HdVheN0P+mOkHhtaHQrgZOPHKzc3qxIrnygtaunvJ3yh1hRddhPVLg3OaFKyu2HFsVshB23GQEdvXRC53jZzMGCGeOVDWk6RlImZl5UOnxI4aZnvV8dw8ttl/auONZ3Gm5oumVjb7x1BwqsxxUojlFtn3bkYJQVRVBeFJHOyvtBVcZWmtu7cd2j65PcXNyMLpXOZtIgc6szmhLRGM1rOtXNqnN5rW/NBMBWVLPGN/5zU0Zcll11Os3Q2DqdTdk+Tpc100h4xU+7YUJQv3u6yNpXp5kk2SAuIG9/jzvuOOX9qbar2rHKkmhK/aGj22Z94dQ+OrUFbrpirTsyiW49P2aQvK9nYqYe0qlTdHHSQasmlRapZx3X7TjgOkDU2undOyVbsOGVA/y4oOj4mR/S6Eyb4YCd8Nr5dLqfdEdITnZpaAjwVQnMOXGUcrvTIm2zvHUrNlWZ3TBrEgoi3joEb++W+137YdMu/fPUN7UrK1uVXtpHylTo6LWMydXlmD6xSvqbm5Hk1Dl201c/XTiVS4lOgBMnz6IjhwzA7CnVWsEnXn7fMAq8GJBWHVetg3I6rk0R2tu+3eyMrNm8F83t3Whq78arivUP1mN0DJzaXf4MTSdUOnuzZRQ2yBkdkxtmTXLdx34fqrpZVv8URMi1vrVjJgC2oqobVWuw0p1NdtNpP94FVqydzbGDS1BdUYzh5UW4Z/U2xw5pYUQ9q+h3JldHB1TcOXcqHr/y46hWDKw6MaAgrGxfnXJSjqosluqZ7D4efPBBpV6q7lvVjnV2x1PkPGWcfLDVillfOLWPB9u6lPWOm2HiJ+CNH3Tr+ZYO93yisjplwYzxmDDMiCxofQ90ULULQHL/NN2lFe/u7b15vNjwCoBf/OPtjLuc6LhAuc3AOFVgVoJ0+0l3hOT6WZMcp5wF4GsdhSpikFskIbO8dd0ZVWU2ubocj1/5CVtD7f46BhXQwstagQnDypQdOJVe2kfKVKTj2nf9rEme9dRths1NX726/oVDhO6Yt3ULuuw62IYFM8bj7CnVmKEwQk26EMF597yYEoDBCauOXz9rUspIpaoszOO6FPdt3V5b14TL73/Nk/GtO8taW9ckjSapQtcAUO0nG4UNMgjN5OpyVBa7u3Xp3Ies/nn8yk9I3ymv11PVjYMVeXXSXcfnti7y6BF6bYKby/OCGeOxu6kddY1tUpdcex2p0v9QGq6Pk6vLfXVIwyHC2VOqMbm6HH+4+CTPA0ijB5X4Wqf44YE23HbB8aiuKEZhJITqimLcdsHx0vPceOONSr1UXVdVh1rXt5pcrzVwEXM8L2CsvzLrnbPvfB5P2mavnAais7Eu2ktfzSnCrRWr3Ol6uaiiRQLJAwuq5QQhMnKcuaF6/3oDbHgFwHOb6jMywmklXRcotwrMStBRFdNdZC4cYsa5rK1VsvZd+Yj6a9sbHPPBNLV3o7auSdrYF0RCmD6xKqXMZA16bV0Tblq5Cc+9U4+djW1oauvCMRruJ0FV3BFNC8KtEnfSP51OZzp67UdPdWbYnPTVa8qGaIiUZa37DFRY5b7gxFGuRmF7VxyravdouRvJEq3edsGUpA7Ud2ce7Wj4uoWoMRtwWToIQK7rXgw1rwaPbl2q2k91v27vrBf3xCOHussYRDRGlYuYzvVUA3cLP+s8UGIvhyfX12mViylzVZncsLPnppOh05n0OjsvFB3MuIBWH0GlF35itVnbNCdvARV+dSoeF/j2I2+irrENHd1x1DW24duPvCm9/9mzZ3s+v1MdKjOMTzzCucNulq1u3RwXwDcf0h9w1ynHqrJC7YFYkxOPqPTVV4uE9K5hlduvl0rPNRVLYgojyev+FswYnzL7SQDuuHCq1gCRnwBm2YLzeAVMELlnZOjk9lIlcQ2HyLM86SSyDJKbVm5Ct8OgdVHU++hfbV2TMlpiR1cMAwojyt/NmZzHFnxcK2eNLL/Lqo27EBdAt2VR6OrNe7WMSD8NoCwvVUEk5BgxsrwoghlHD3XNM+OWYNet0+mk1zpJm73qabrBM7yOoYVDhHCIpGUdRMNgJre+7tH1WmsOaz5sdMw5BhjpGMzEyya1dU349iNv9kQorWtsw23PbMZtFxyPVbV7POdtUhlQVuy67pYQ2P4MvQxSeBklVuns1DGVWOMxWbyXXIC1dU1Y9/4B2Wm07sP6Pg0tL8IrtpxO1uuq7oWQ3PGXXc8pn9e4qlLpdlk5WNfBuOXpM2eCZAG43YIgAXr5iTzXHfbCsl3Pqd5S6cUt50/pmZXxgn2wxWsyYb+ukR3dsRR36c5ugZtWbsL9X52WtH3FihWec2O6tWPWZ1hb14Qah7xiXs5rRZYMWoVbewkYQSXunDsV593zEt5wed9NqiuKffXXSgvlOSatFEQITQn3ygnDypTRnHXr24IwSXPCyQxNe1MVTnSS7lm9DcPLi9AZE9h1sE06IOrkKZVr2PDKAF4afJ3OJaCXnFIktC+EGI4r3oqatqMQR7hne1/EGuXGinmPte1HSX93KlenkRmBZJ91e1kCyZW5W2Una9Dt4fVNZMF57Nf32gCqGrKOxHfZ/QH6Fbmpl5ff/5p05sLNUFTpNYCMJEhWJbv0Y9Cqys7+Gygs3X6o03g+5v3IdNbtmhOGlXlaN7CjoTWlMbOfU5aO4aaVm6RpIR5+/cOUDpSJ9TpJ1xBhRwMKkHfo3e7T/gxlzzqEGKYUb4YA8FbbRIwZXIbjRlV4SmTrpLNr39vvKfG9l4Sk96ze5jjbITOYTXQS/Fqvq1ovPGl4GY4aVoZn1m7A/0w71rG9ktUfqu06Ouw2qKlaa6QTSEjHqFLVHU3t3T2dUmt5CJX+I+zaR3AKUKIzwGLX80O25XX21AOqc/TUYZpE0IlzKlbj8cYZ6EaBco3quh0HUuq79576LY48a76nROp2PZXVyWZZG6ltUgWSHaNzXiu6fT5r3aFO0mwYDB9IBgzsz8T8368nTNRhHWJhJIRTxg3GK+/u7zHSN+1udnUxd8NatkntoU1HjUH35PLpjglc/eA6x3rQPOeb+wq05MkFbHhlAF0FlDWGT66vw/SJVbh+1iTfo/tfGrwSFw1+Cn/efxYe2H+W9xvoA5j3+Jf9ZwH4fNJvbqNmbpWUddZQVZYqNyh7Zyxd10D79XWiX1plaGrrkjZkbvcnCxOtwlw3YO9M684iyPT66gfXeWqAddGZObZjLVMrTu+Z6jf7dutorExn7ViPf7RpNhbMGI9vP/ymVG77gHuI5OtA7TLJ6i/VAIhqu9s1nDrZKgPC6V2SPcMFM8anRA/70uCVuHroQwCAO+svxMFRX/OlT6q6WGcW3IqXWRS3ukRldAH6i/rNa2xWXOvDxjb881vT0fqFo1FSEly45nTX1wHq4FI6Qad0BmRUsxV1jW2og2RwyPIC2vXfrX71GqDEjl3PH9h/VtIgj2rWwn4OU+Z7Vo/Wek9uG/NrzCx/BdPL38A3d1yv3C8eFyn1XeHYc9DicTbFXp3J6l3zGarOYT+mtq4pZRDUrU/lZeDOrDvO+LAR2/enGleUuKsmSXRlqxwAev4/OOxr2te34pQHzQyNL0u6bW9LvHgMWM9mvZ+/NCSXq6ptcRt3MM95X/w0/FJLouzT79Z4EVEhEd1MRHVE1EZErxLRmUGdP0T60/KyxlDAcDvzs1ZsYHEU1dF6XDhoFUZF63Fh5SpUR+sxsFgdlrO3M0oSgcl6j3MHPw0c2pH0u5sPslMlaa1MZGVponKDsq8R8GLA2LFff0Jpg+P+Mhlk7kI69+d1kt6+3mr6xCqccuRgfPvhN30FnclUPi2v68LsZWriVHaq32TbraOxTgay7Pi/XzoGk6vLlXnWBIyQ1pEQYRC1oljiliuTycusqpOemG26U1nZKYqGlAaE6r2triiWPsPJ1eVJa5Wqo/W4aPBTGBJpxJBIIy4a/BQa9251uANvuHkvyNbseFnj6FRvjawo8mXg2dnT1I7auialO6q5/dZbb9U6ny7prq8DoPTs0PH40AkoZa87ZNEBre1MaWJtmUz/3dIceA1QYkWm59XR+qSUB27ul3aZ9+x6x/W6U4vfxpnlr6KAunBm+auYWvy2ct+SwkhK/dbRHVfOWqrquAGFye+3vZwJRhRC1btmP2Z0oVFOTvvY6y+/gccGD5DPyNQdNN7Bclu/zSrHRYOewkWDn+qR6epTUs+ls3ZUlQfN7Meq6o0xg0p8xwAw18+llr2+66sK6zm/MvIljHYPZJkT+p3hBeBPAL4N4C8A/hdADMA/iOgTQZx8zKASbQV0agz9RMMaXl6IK6oew4joPjR0l2NEwT58rWo5hpe7V9a9lQ9T3NdE8j1G9wFv35Lk1+HWaderJIW0LAGh7QbV3hVP5E7x42ucev1vDH/cMbqDypCXEQ5BeX+A0QHzijmSd9uc47H2PcM9wSn6kxOZyKdll1Mn2It8pkCtG+rf4tLtE4aWAlDr7GE/9eTzjircj8Ef3Imrl72Bl7ftU8ovhBFFqkGUSDo1qbL+7qT/YPKI1DKWDYAAUOb8A8xOUeo1vj70sJ5ZKY6GU8J0W1F1jk1DTdbROCy3wBVVf8OYgl09x44p2I2LKh7xHjFFgltwhtq6Jpxz9wtJv59z9wuYOXmYdmTOYyTPxWT3Qef3Vfe9OdDaldLxtGLmgZw5c6bW+ay4pXFwC/ri1sGVuZE5bbeiOyBjrTtUiYPNd9kwUuX1wZZ697WvMr2YOXmoy53I9fxrVY+hvSuGe1Zv08hBmSrzecV/Vb4nRhUVx42jlqCQuhATIRRSF34x6m4oV8UqznVQEWVvT7NbeyQvZwGBNYmB7CED7APQqcdcNni5bQ2duq4vK4pI9UQ3WM7m+hb5nQjgh09sQEPS7KZVjjKMKdyFMQW70dBdjuqCfZjY8LukMtWNPKgq1zGDjX6sqt44blSF74BpISLIyvXywcuT7kHV5qixnbOwEdf1UoevfmV4EdE0ABcC+J4Q4jtCiN8D+BSA9wH8KohrqEJgynBrDL2O7g9vfwXTy95AtwjjQKwc3SKMGWWvY1j7q57Oky10Kqjm9mQ3kdMG1CTdY2c8DOxaCdSv7tnHrdM+uboclSXOs4D265hl+bGyDThFkvxR9az2NLXjtHFDHK+le/3jI68k3aeuDDJOKXlLen+nDqgBkJ6BIzNWvEZ/Sjelgd9EtvbjZC45Kt04dUCN8revDn5Cuv3aKUYHSRkpT8iv2RkPo/ndFdi7bRU6ZYsDNbCfMybCOC4k17F9h+QdItV2wDD4pOVR+jqmD9yYsn9bV0waptvEqXOs6miYI/unDajBZ8pfQZRiiIsQ4iKEKHXjxNBzju+ULm6z7E5r5HRnYO9/ZUfKNhOZClh1+WBbl3by3PYu9cxDa8Jtb+fOnVrnssrilsbhVEWepXJFB9eO6jXQfT28Rt91amdq65pwqDOmrA9OLH7LVRaZXqyqVc8WA2o9n1X+Mk4dUIPn3qnH0xtTXZjt57DLfGrRWuV7EhPAZYOfwPjCDyAAdIooBICjCnfgq4P/Lj1GlT+qS/Gwtu6RGymmG6lTnQwYOv3Aq8nvj+yY6ZZjnM47feBG/PWK01L0xEuodXvfxsrr7x9I0lurHJ0iiijFEKVudIooukVqH0g38qCqXD9sMAa8pYnBYbhB+o3eHVO0C6eXvpZ0D05ti4zUNpIw66O+RMw4/crwAnA+jBmu35sbhBDtAO4FcBoRjU7n5F6nnN3yj3jq/MbaMa/iYQwKN2FfVwUAYF9XBQaFm3BJxV+BmPcZDDt+O7Oqc3nNBVFInfh61aPJ99g9EOjYB9Te3HOPOp12pwXX0uskyvKKwY/glS07U2R1aoS9zh6prl8Rbk66T9m1dM9/xRD5/c2vehTlBd2+o1gBagPQjP6kQzopDfzmGZEdZ3fJcdKNK6sexoKqRyS/HcRVQyXbI00YW38XEGtX6mw0TEq9r0g8r0LSaaCSOzSyczbEKlPeJRPZegOn7QBQHO6SllVlpBlLpj6Dcz86WMtly4p1VhVAjyvrTSs3STsaHd1xFFInFlQ9jKpIIwCgS4SNzgoEBlIDsPGXadePbrPsTmvkdDv8but7rPpt12XD5VhgxsQqT2Gq7ZhadOCA3to+E52OYL2injQD/aQTVCcTOLUz96ze5lhXfKv6cVedk+mFkw446fmQSCOurHoEnR2tjjmqVDJXRtRtT1moBVcOfQQRiqEzbswCdsYjiFAMVw19GGWh1M59Z3cspewiJJS+y3HFDFmIFPWjpT0z60erUadzjGyf/V0VGFbYgiVTn8HkYanufemGWpdhlWN/Vzmqoo2JXwSGRg9gv6QPpOuqrypXc7vZDk+fWIXDvhf+l8MAQFm0W65j4SY0r/tFzz2ocoxFQpTULxhQEJY/q84yDE7fQSYj9DfDayqAzUIIu7asTfw93s9Jxw0Z4CvXlUypTTz7DW9biolFO3AwNgCxRNSdGMJoig3AxKIdwLal+ueSkG7SPDu6FZR1ZuqCQf9Kucc4IkC0Aji4secedTrtTvkrZNexluUFg/6VIqtTI+x19kh1/Q4qS7pPOzIZZBGInO5vUskHWDV7a9qRA1V4mZXzm//Nb+OnmqmzlqFT2X20ZAs+WrI55be4CGFgpAVxUNL2TirveZ4qnS0tisqvKZL10Z1kRZCds7CgIOVdMlGtLXFac/LNsc8r9bis/R38+qQ3tFy27MjqoucVaxkLIiFcMOhf+GjJFhAJxEQIxvJ1QkyEQSSA/f9Nu3706xrrxQnZbX2PVb9V0VTLi6M9i+adUBlnpgzTp093PYcV3aiBMnTrT1IUpmp7uji1M1v2NDvWFZNL/LXJTjrgqOcQ+GjJZte6wk/b84tRSzAw0oKYCEEkupQCIcQS9d4vRi2RXIlSym7JOWMxxGM9M2V0hVZ7rXuf1mNk+xQUFGDAgMEoa39HWhZe1ibr6qVVjoGRVhRRJ2IihJgwDI6BkUMp9bbuu6RTr0+uLsfA4miKc7hfg/Jb415Qln1XQ03PPaj6aNFwKKlfcOLYQdJnFY0W4OAhz+Jlhf5meI0AsEuy3dxWrTqQiIYS0THWD4DxAPC7i0/yPSI3uboc9391Gp765un+ExYf2gFs+wOKQx04GCtN+qkxVoriUAew7Q8pQSi8EPRIjm4FtegLxwI4vGjSfo+hEICCSqD7UNI9unXaVa6Gx1U04vIRzzqWpT0wgnk9VSOsmq6XobpPIqCsrCrlPq3IZLjjwqlJ11adHwAOxksxpKgbI/b9JS1dWTBjfNohZ9PBb2AOt4XEp1e34kuKsjsUL0RpuA2loTa0xg83WlHqQnG4AyHEUUztiJIxQyR7njKdPbJ4n0IfKEUfHbGMbMp0gAgYXl4kfZcAYOFnJ0lPq9qOQzswp1JPj712uL2sZZw5thMXD34KpeE2QCDRITWIIWw0gN1NwJa709Z5p1n2E8bIE7dOVWyXoSzrBFb9dXoH3Ab0iqIhXPM/E6S//fjsyQCAJUtknWk1Os84XffiIYpgBVWlmQsrT4LaFwAANhRJREFUrWpnpg1tUdaz5eVDERVtvtpklQ6YATWkei7CAAmUhtp6Am2ozqGSWdn27H0ZZ5a/ihDi6BLJAyhdIoIQ4tJAG0QipexWPnRvj37ZUW3/5cyBmCupy4iS2+sji/f1BNpxuk/zGDN4hX2fcIiUdSTgbfBAJ82UVdbWeCEGRQ4ihHiP4RWiOAZHmoDwgCSZdN8l3fIOLNiVol0AjLIPxw+/F6o+WqVtrd4PzhiQ0i4TGYmoG9jw6hUUA5DN1bdbfldxJYANts8TAPDCCy9g9erVWLx4MRoaGjBv3jwAhzOxX3PNNdi6dSuWLl2K5cuXY+3atVi0aBFaW1sxZ84cAMD1X/8y7pw7FSfUr8QVx0bw5nNPYtmyZaipqcHChQuTzjdnzhy0trZi0aJFWLt2Ldb940Yc2v9eQunsbzPhYKwUzXu3YfPq27Fy5UosWbIEO3fuxPz585POO3/+fOzcuRNLlizBypUrk+7p36/VSgtl7dvvK+/JPO/ChQtRU1ODZcuW9dxT2+53pefr3Ps+1q5di+XLl2Pp0qWYNKAVJ3e9hU+Vv4Yh4caUeyQhcLCpGY1tIXQf2oW/3PIVrXs6boQ8ms/5Q99AFepB4QEoLQghQnFLgAOjLIdEDuKTZa9haGEs6Z4euOsm3Dl3KqLPLsadc6fiJ9+6HK2trfjbvb/Bz04fiKmDYxhW0IVPjitDSVxeI3yy7DUMiRzEwVgpCIRomBAVnTiqqhQf7tgOFFTiwO53cKB2mfQ53fy9q5NkePZPi/Gbs0fjmLJ2VJfEMbPidWk5hkOEctGGWKgUrQe2Y+0TP9HSPfM5bd26Fddccw0AQ5fvuHAqIMzOsdEtjoaAQbv/61n3vL5PqsavoG2/4z117n1fetxxoyqwfdmP8OfP7sfg8AHpe1YWPhwEptzyf1m4FRHEICiMaCiOivAhDCyKoLirCcWFEdTtawfa6/HIby6V3tO5Q9/EkPDBlGsWRQhk00cAoHgM1RXFGNq4ASPKCxFGHEOKQzh7dDeOKWvHyPIoPlP6MoZFD+JgdzEKI2FE4p04cnAxDjbsRXNLCw51F6Jl/7s4ULus5zn97gdfx11zp6Io1oqCMKEs3IWvTSaUNW6RP6e6f6CjYRsKiipQHBaIhoDSAsJAakdBNIRdDR1Aez2W/OBsLJgxHmGYaz4MXSkIE7rfekr6nF54SzLYI0RKzVcYCeH0Qw9gbNF+AOiZBQCMAZtQvBsUiiIWiyPe8gGeW/Zd37o3tiKCo957HLOnVKOofR9mT6nGJ7tfR2z/+1i2bBk+Kt6F3au8IBLC/n/f6/o+mdd+5LbvYXhZAVRm5oRhZT37Nu7YJN3niIoC3Py9q3HimArp72VRgZ+dPhB7n38Qt/6/Y1DQ1YLCSAjRzmbcNXcqXvrrXaipqcHJJ5+s3T4tX74cIxprUkJXF0VDqHvmj2hoaMDixYuxd8s6XDcFmFTSgqMGF2F45048tuDjuP7rXwbgXkecOl6+lnZkQZvn9slPvWfuO2/ePFwy+s2UepYAlMQPoWJAQc97/5dbvuKp3ps0oBXlkW7YdeCTZa9heCSh5wiBYHQ+QwREQwIikTloeGR/T10BAJ8YPwjjwg04YmAYZw6Ut7GFkRB2132IWLg8pR9x6M1foYC6DONO0veIiTAKqBuXDFmR/Et7c889me/T9OnTMbTjQ3yy4F2MKC8ExbtRXVGM0TuextlTqqXPqfZv12LiwDY0dxagKBpBJN6BcUMGYCC1o7QghJZ4KYYXNOKu07ZhUvMbPWUlq1NNmQ/GSjE8uh/DI/tT9mnr6MLBpma0xorQvHcbDm15JOk5LZgxHiFhr8uA8DvPpuje0HJ1dzNEQMmhXUmyloXbEEYsqR6LiRCioTjqd20DCirRsGsTDm15BE/95Xf4/rRCnDSUUBXtxP9MqMAJ+/+DydXlSW3u1CECswftwaBCo30uDXXi5s9PwCO3fa9HTgBo2blFKue4wcWe3qclPzgbxbF9aO4qlJZ9uyhD457NQN0/cGhHDWRUF3Qk9WEnxp5HFXahOzIQYcRRXhTGoEgnutrdE6fnCurLyXW9QkQbAOwRQnzatn0ygI0A5gshfqc4diiAKtvm8QCe2LBhA4455phMiKzHoR3AmnPQtH8btrdXIVmhBcYW7UX54PHA9MeBAWN8XeLqB9el5MQBgNlTqn3lwbHnLQKMhlg10/ejZf/AnLarMTK6Fx90DoV5jxUlUYypLAYObQcGHKF9j6rr//3SMZj4zkVGmQ44AiBCW2cM2/a2IC4ERhfUY2dnFa7e+SMs+dq5vl3yVOU5qqAefxx+HSYMpZ7r9yCE5/u0E3Q5OqGbHDxovOqW9nGHduCDJz6D0u66pLIDgCh1YkLRh4AAtnSMQpcoSGzvwvji3ShAJxAqBMomAOHECLzG89z87kZ0P/d5jIgcfl4hAsZXlQJCIHZoO3Z3DcX90dtx4RmfUN7f7NmzsWJFovOTqC+sOt5DADrm5xpedEX17syYWIXy4mjyOQY2As99DmhKGCJUkCxLrN34Xj4JOOMfaeu8E0G8D6p7DxHw5NWnJyXjdtJlI8rii0kR/woiITx+pZ6nRZI+aZLp+sDve58RDu1A27OzEWt5H3Vdw1AUDaOqtBDFBeG03zGZDlRH6/Hn8T/FuIIPDfW26bmItSMmgG0do3Dpez9BXdfQlLLx1TbsfRkdT38SUXSgPV4Ae9+jKNSFDhHFl7b9AuvaPtLzy11zp+LsKckORn50yms98+T6Otz79Gr8fNAPUG27TzMC8ciCehyID0JrZwxDIwc8t5O6ev7k+jp848F1KduJgDsvnIpxVaW46v+W485RP8PI6F7s7qrE2MLdiKIbnSICIkJRqBsULgAGjAfa6wJru+0E9m4lnld38/vY1FyJuDj8vEIkMKmsAZGyscD0x1F7sELvmgodaGtrw8aNtTj5hzhWCJEazSmH9DfD618ARgohJtu2fxrAMwA+L4TQfvMT7oYbcm54AcDmu9FVcyN2NXejsfvwiH9FpBkjyiKIHrcQmHil79NnolHz0hDX1jXhkYe+h68NehhdIoyDsbKeDmixOAiIbmDyDZ7uUXn9zXcDtTcBFAEKBwEA2jpjONRSj3isG8+Fv4pjz/heWo25rDxDBNxx4VScXfx4yvUBAB0Nvu7Tft2gy7E34reT53bcrv/eCtTehM64UXaAUc8PK2xFkWhCXAgcjJX2/BYiGI1J7KDhh1869vDFNJ/nrv/eisIti9HRHUJXpOJwBy4dfZDouBeZcnkNz3XR5ruB9d8HupsBhIFQwiVKdAMiBkTKgSk/7xM671hv2DqyOnnFcjEwkkl61T1lWf//8/lajNj+c6Wed4dL8Vj3Aiyt/6xSH/y0DQf/dR4G1D8BIYAucdgNLEpdiIQIdeWfwwUbvoX9LR0YXFqIhZ+dlKKraeGnnBP9pYMdAg1dZSiKhox6NXGfu0b+L37//LsZbyefXF+Hnz5Zi/0tHQgRYcqogVh0znFJAyj//dfPcab4I7pEGBGKoypyAALGWqcQCaBoBEDhjLfdgb1biefVGQthd0cJ2rviKIqGMLywFQXheNI9aF9T1mdra8Ou7bUY/202vHIKES0GcA2AQdYAG0S0EMAvAIwRQnzg4Xy9x/CKtQNrzkX33lewu3soWrsIJdE4hkf2IlJ1KjB9ORD2n8wXyH2j9vYH9Yg/fy5Gx2vQFBqBwaUlKI4IoHUHMPiUQO4RQE9ZYv+rQMkYowGLdwd+HVV5Xn7pV/CHi/dn7PpZK8d8JNaO5n/NRqhhLXZ1DUVBNIqqAWEUd+0EBp2Elo4Y6MBryb91fmg8QxHz9zwD0Md58+bhvvvuC/ScOmWVqWt4qoti7cDqzwN7/mOMgocKjAHsWAdAIWDYp4AZT/QZnc91PQxI9IlJJdv6P6wgbT331TZ0NqL7iaMQ7tyPdhEFYBgEBdQJKhwCzN4CFFS43pNvnfJTzhrHvF3X1DvaSUubs7trCKqje1CENmMOLloKlIwF2j7oO213Jt4LyTnbWpvRum8zhnydDa+cQkSnAHgFwHeEELckthXCWK+1Xwhxqsfz9R7DCzAq3LVfB7pagJJqoLXOeDGn/R4YdkaupQuGbN1jDsuyoaEBg7rWZ/b6/UFXMoVT2UHIfztqAbD1Hv/lnebzamhowKBBg5I3ZkMHeoue7fkP8NJFQPtuGL1RMtYgFg8HPvYA67xHpPrEpJJt/Q9Cz/3I/PZtwJs3GINL4aKEC28YmPorYNK3tERPS6f8yKxzTG+qv0w5omVAyzZjCVnZeKCrue+13ZkoV9s5u5rex3sf7MPR1/U+w6tfBdcQQrwK4BEAvySiXxHRFQD+DWAsgO/mUrZAGHoGMGKmMeXcsd/4O2IWMHRGriULjmzdYw7L8t5778389fuDrmQKp7JT/Xb0/6ZX3mk+r3vvvTfwc2ZD7kDlGHUOQFGjIypixlq70eeyzvtAqk9MKtnW/yD03I/MR38LGDgJgADiHcbfgR8BJn5TW/S0dMqPzDrH9Kb6y5Qj1mE833AUiHf2zbY7E+VqOyeJGFY65ynPGf3K8EpwMYDbAVwE4A4AUQBnCyHW5FKoQCACPvIdoGQU0LHX+PuR6zKXyCQXZOsec1iW06ZNy/z1+4OuZAqnslP9FgqlV95pPq9p06YFfs5syB2oHJO/a4wQmxHhSscZsrHOe0aqT0wq2db/IPTcj8yhEHDy74zZLnPW6+TfJvK96JGWTvmRWeeY3lR/mXJ07jOeb+n4vtt2Z6Jcbefsig7DLU8FJ3KQyDNX5jFCiHYA30l80qUAALZu3RrAqYKjsuQsDGptRkPJWTiwvRlGwMb8Ilv3mIuy3LRpE4YMGZKV6/cHXckUTmWn+i3d8vZ7vFWngjqnF3qLnlWWnouqQ0Yeo72l57LO+8RJn5hUsq3/Qei5d5nLMbJ0Bsqb/o2m0hnYWV8O1OtfMwid8lPOOsf0mvrLlKP0XADAoPaHci5TOmSiXM1zbo5Pxwf7NwGJfnqvQgjBH58fGLNmord9QgRx8jjjb65l6ev3mOuyzPT1c31/ffnjVHaq39It70w8r2zoQG/RsxBBnDLe+ORaFv70n0+29T8IPfcjcyQEMe90429fKWedY3pT/WXK0Vtkyvbz8nHOi3JtK9g//Sq4RtBYgnWcD0CesZJhvDEeRmLuLwCQZIplGM+wTjFBwvrEBA3rFBM0kwA8CuDURHyHXkO/czUMmJbE3029LWoK0zehwz7O21inmCBgnWKChPWJCRrWKSZoLDrV4rRfLuiPwTUYhmEYhmEYhmGyChteDMMwDMMwDMMwGYYNL4ZhGIZhGIZhmAzDhld67AXw08RfhgkC1ikmaFinmCBhfWKChnWKCZpeq1Mc1ZBhGIZhGIZhGCbD8IwXwzAMwzAMwzBMhmHDi2EYhmEYhmEYJsOw4cUwDMMwDMMwDJNh2PBiGIZhGIZhGIbJMGx4MQzDMAzDMAzDZBg2vBiGYRiGYRiGYTIMG14MwzAMwzAMwzAZhg0vhmEYhmEYhmGYDMOGF8MwDMMwDMMwTIZhw4thGIZhGIZhGCbD9HnDi4hOJqK7iGgjER0ioh1E9DARTZTsO4eIXiGiRiLaT0SrieisXMjNMAzDMAzDMEz/gYQQuZYhLYjoUQAfB/AIgLcADAfwDQClAE4VQmxI7Hc1gDsAPAXgSQBFAC4BMAXA/xNCPJZ14RmGYRiGYRiG6Rfkg+H1MQCvCSE6LdsmAKgB8KgQ4iuJbZsBNAI4RSRumojKAewE8G8hxBeyLTvDMAzDMAzDMP2DPu9qKIR4yWp0JbZtAbARwEcsm8sB1AuLpSmEaALQAqAtG7IyDMMwDMMwDNM/6fOGlwwiIgDDAOyzbH4OwCwiupqIxhLRJCJaAmAggN/kQEyGYRiGYRiGYfoJfd7VUAYRfQXAnwFcJoRYmtg2FMAyAJ+27LoPwOeFEC9rnHMogCrb5lIAEwFsANCZchDDMAzDMAzDMNmkAMBoAKuFEAdzLYyVvDO8iGgSgFdhuBqeLoSIJbaXArgZwAAYwTXKAFwDw5g6XQix1eW8PwHw48xJzjAMwzAMwzBMQHxBCPH3XAthJa8MLyIaDuBFAFEYEQ3rLL/9E0C3EGK2ZdsgAFsAPCOE+KLLuWUzXpMAPPr444/jqKOOCugumP7Ot7/9bdx22225FoPJI1inmCBhfWKChnWKCZKtW7finHPOAYAThBDrcixOEhkxvBIGTTocNGeqPFxzIIx1XGNgzGDVWn4bB2AbgCuEEP9nO+4JACcKIUZ5FZKIjgGwYcOGDTjmmGO8Hs4wDMMwDMMwTIBs3LgRxx57LAAcK4TYmGt5rGQquMY+AHvT+MzwcjEiKgKwAsZ6q7OtRleCYYm/YcnhUQARL9djmEwye/Zs950YxgOsU0yQsD4xQcM6xfQXMjXjFQewHEZCYy8MAHAtgDOFEP/WvFYYwGMAPgfDl/Mfkn2qAOwGsAbApyx5vEYBeBvAC0KIz3qUlWe8GIZhGIZhGKYX0ZtnvDI50/M3IcQyLwcQ0WAA13m8zq0APg9jxmtQIqJhD0KIB4QQe4loKYDLATxLRI/BCK5xJYBiAL/0eE2GyRgLFy7EjTfemGsxmDyCdYoJEtYnJmhYp5j+QqYMr2sAvObjuJbEse94OOb4xN/ZiY+dBxJ/FwBYD+AyHDa0/gvgYiHEGs+SMkyGmDt3bq5FYPIM1ikmSFifmKBhnWL6CxlZ4yWE+I0QYrOP4zoSx+70cMwZQghSfSz7dQsh7hJCTBVClCU+nxJC/MernAyTSWpqanItApNnsE4xQcL6xAQN6xTTX8hUcA2GYRiGYRiGYRgmQdYMLyIKEdHF2boew/RVjjvuuFyLwOQZrFNMkLA+MUHDOsX0F7I54xUF8McsXo9h+iQPPvhgrkVg8gzWKSZIWJ+YoGGdYvoLgYaTJ6IfOfwcBbBQCCHLpdUn4XDyDMMwDMMwDNN76M3h5IOe8foBgEkARkg+wxyOYxgmASeSZIKGdYoJEtYnJmhYp5j+QtAzXq8D+LEQ4knJb0UAWoUQeRPQg2e8GIZhGIZhGKb30J9mvP7P4ZxdAH4a8PUYJu+YM2dOrkVg8gzWKSZIWJ+YoGGdYvoLgc549Td4xovJBK2trSgpKcm1GEwewTrFBAnrExM0rFNMkPSnGa8UiOhnmb4Gw+QTt956a65FYPIM1ikmSFifmKBhnWL6C9lYb/X9LFyDYfKGmTNn5loEJs9gnWKChPWJCRrWKaa/kA3Di7JwDYbJG3bu3JlrEZg8g3WKCRLWJyZoWKeY/kI2DC9eRMYwHjhw4ECuRWDyDNYpJkhYn5igYZ1i+gt5E9qdYfKF6dOn51oEJs9gnWKChPWJCRrWKaa/wIYXw/QylixZkmsRmDyDdQoYe8NTuRYhb2B9YoKGdYrpL2Q8nDwRxfMpabIVDifPMAzTNxh7w1PYftNZuRaDYRiGyTD9Opw8gBezcA2GyRtmz56daxGYPIN1igkS1icmaFinmP5Cxg0vIcTpmb4GEZUS0U+JaCURNRCRIKJLFPvOIaJXiKiRiPYT0Woi4mFQptewYsWKXIvA5BmsU0yQsD4xQcM6xfQX8sUFcAiAHwH4CID1qp2I6GoAfwWwD8ANABYBGAjgSSI6LwtyMowr8+bNy7UITJ7BOsUECesTEzSsU0x/ISuGFxEdT0RzbdtmEtEaInqViP43zUvsAjBCCHEEgO847Hc1gP8CmC2E+K0Q4nYA0wG0AOC3nukV/PrXv861CEyewTrFBAnrExM0rFNMfyFbM16/AvBF8wsRHQlgOYAjE5tuI6Ir/J5cCNEhhNitsWs5gHphiSgihGiCYXi1+b0+wwTJvffem2sRmDyDdYoJEtYnJmhYp5j+QrYMrykAXrB8vxhADMBUIcQpAB4FMD8LcjwHYBYRXU1EY4loEhEtgeFu+JssXJ9hXJk2bVquRWDyDNYpJkhYn5igYZ1i+guRLF1nIID9lu+fA/AvIcS+xPd/AfhsFuT4Joz1YHckPoCx3uvTQoiXnQ4koqEAqmybxwcuIdPvaWvjyVcmWFinmCBhfWKChnWK6S9ka8ZrF4zAFyCiEQBOBPC05fdSAPEsyNEK4B0A9wG4AMBXE7I9RkRHuRx7JYANts8TAPDCCy9g9erVWLx4MRoaGnoWiZrhUa+55hps3boVS5cuxfLly7F27VosWrQIra2tmDNnTtK+CxcuRE1NDZYtW4Zly5ahpqYGCxcuTNpnzpw5aG1txaJFi7B27VosX74cS5cuxdatW3HNNdck7Ttv3jw0NDRg8eLFWL16NVauXIklS5Zg586dmD9/ftK+8+fPx86dO7FkyRKsXLmS7ylH97Ry5cq8u6d8fE596Z4ee+yxvLsnr8+p+Y0n8+6ecvWcHnrooby7p3x8Tn3pnh577LG8u6d8fE595Z5eeMHqZNe7yHgCZQAgotsBfB3A/wE4BcCxAMYJIfYkfv8jgClCiBMCuNZJMAJoXCqE+JPtt38C6BZCzLZsGwRgC4BnhBBfhAKHGa8nOIEyEyQ7d+7EyJEjcy0Gk0ewTnEC5SBhfWKChnWKCZL+nkAZAH4A4DEAFwEYCuASi9FVDuB8JM+ABQ4RjQMwC8DfrduFEA0w1p993Ol4IUS9EGKj9QNgW8YEZvotixYtyrUITJ7BOsUECesTEzSsU0x/IStrvIQQLQC+rPi5BcAoGG6AmWRY4m9Y8lsU2VvvxjCO/Pa3v821CEyewTrFBAnrExM0rFNMfyHnCZSFEHEhxEEhRFeGL7UVxjqyLxIRmRuJaBSA0wGsy/D1GUYL01+ZYYKCdYoJEtYnJmhYp5j+Qt7M8hDRNwBUAKhObJqdMKoA4E4hxF4iWgrgcgDPEtFjAMpgBM0oBvDLLIvMMFJWrFiRaxGYPIN1igkS1icmaFinmP5CRma8iOgtIvqcj+MGJo71k9DhOgCLACxIfD8v8X0RgMrEtgUArk58/yWAhTACa5wphFjj45oMEzhmpB6GCQrWKSZIWJ+YoGGdYvoLmZrxOhZG7i6vRBLHlno9UAgxVmOfbgB3JT4M0yv54Q9/mGsRmDyDdYoJEtYnJmhYp5j+QibXeN1ORO96+QB4HUDm49szTC/m8ccfz7UITJ7BOsUECesTY2fsDU+ldTzrFNNfyNSM131pHl8XiBQM0wcZP358rkVg8gzWKSZIWJ+YoGGdYvoLGTG8hBCXZuK8DNMfKC4uzrUITJ7BOsUECesTEzSsU0x/Iefh5BmGSWbt2rW5FoFxIV23mmzDOsUECesTEzSsU0x/gQ0vhullXHbZZbkWgckzWKeYIGF9YoKGdYrpL7DhxTC9jGuuuSbXIjB5BusUEySsT0zQsE4x/QU2vBiml3HffenGpmGYZFinmCBhfWJkpOOCzTrF9BfY8GKYXsbs2bNzLQKTZ7BOMUHC+sQEDesU01/IVDh5KURUCOAEAEMBvCiE2JfN6zNMX2DFihW5FoHJM1inmCBhfWKChnWK6S9kbcaLiL4JYBeAFwA8BuCjie1DiGgfEX01W7IwTG+Gfd2ZoGGdYoKE9YkJmv6qU30tQi6TPlkxvIjoUgC3A1gJ4DIAZP6WmPX6N4ALsyELw/R2rrrqqlyLwOQZrFNMkLA+MUHDOsX0F7I143UtgCeEEF8CIJtPfh3AMVmShWF6NWvWrMm1CEyekUud4hHd/IPrKCZoWKeY/kK2DK+jAPzT4fcGAIOzIQgRnUhEK4moiYiaiehpIjo+G9dm/NOfOm+VlZW5FoHJM4LSqf70HjJquI5igoZ1yhmue/OHbAXXaAQwxOH3yQB2Z1oIIjoBxhqzDwD8FIbheSWA1UQ0TQjxTqZlYBg3Ro4cmWsRmDyDdYoJEtYnJmhYp5j+QrZmvP4B4AoiqrD/QETHAPgagL9nQY5FANoAnCaEuFUIsRjAx2CUw41ZuD7DuLJq1apci8D0MtId7WSdyi9yPfrdm/Up12XD+KM36xTDBEm2DK8fAAgD2ADg5wAEgHlE9ACA1wDUA/hZFuQ4HcAzQoj95gYhxC4AqwGcTUSlWZCBYRy59tprcy0Ck2eodIo7qYwfuI5igoZ1iukvZMXwEkLUATgRRlTDL8KIangRgNkAHgRwapZyehXCmPGy0wqgAMCxWZCBYRy55JJLci0Ck2ewTjFBwvrEBA3rFCMjHwcHs5bHSwhRL4S4XAgxCMAwACMAVAohviqEqM+SGO8AOJWIwuYGIioAcEriq9LJmIiGEtEx1g+A8ZkVl8k0vfGlXjtuXq5FYPKMhx9+ONciML0Qv/Uf6xMTNKxTTH8hW3m8xhBRsfldCLFXCLFHCBFP/F5MRGOyIMrdACYCuJeIJhPRsQDuh2EEAkCx8kgjCMcG2+cJAHjhhRewevVqLF68GA0NDZg3z+g4z549G4CRGHDr1q1YunQpli9fjrVr12LRokVobW3FnDlzkvZduHAhampqsGzZMixbtgw1NTVYuHBh0j5z5sxBa2srFi1ahLVr12L58uVYunQptm7d2pOE0Nx33rx5aGhowOLFi7F69WqsXLkSS5Yswc6dOzF//vykfefPn4+dO3diyZIlWLlyJd9Tju5p15+vzbt7yrfndPDVv/WpezrppJMCeU77V93l+Z5a3nq6V+he8xtP9vrnpHtP7Ttqcqp7J5xwAtcRmvc0bM7P8u6eZM+p/tGfpnVPJ510Uq+7p2w8p86927XuqfHFB/vMPQX5nPY9dZuve3rhhRfQaxFCZPwDIAbgSw6/fxFALEuy/AJAJ4x1ZgLAf3F43dk5DscNhZFrzPr5PACxYcMGwWSWI65/sk+dNx2yKVNvvP++QLbLTed6fmTyekw2rpEpeoscQRDUveRTmZj0tnvqbfJkiiOuf5L10ge699qfysSK3/vesGGD2cc/RmTBtvDyyZarIbn8HgUQz4YgQojvw3B1PB3AR4UQJ+PwzN9mh+PqhRAbrR8A2zIvMdPfOLD6vlyLwOQZ5ogjw3hB5YrI+sQEDesU01/ImOFFROUJF0PThXCw+d32+SiACwHsypQsdoQQB4QQLwghahKb/gfAhwA2ZUsGhlExYPIMAL1z/RnTN5k7d26uRWDyCNYnJmjS0SluK5m+RCZnvK4B8F7iIwDcbvlu/awD8DkAv82gLEqI6IsATgZwu0isOWOYXNK1d3uuRWDyjJqaGvedGEYT1icmaFinmP5CJIPnfhpACww3w1/BCBv/hm0fAeAQgNeFEK9lUBYAABFNB/CjhGz7AZwK4FIYYe5/k+nrMwzDMAzDMAzTP8mY4SWEeBnAywBARAMA/E0IsSFT19NkJ4xAH98BUAZjxu0HAG4TQnTnUjCGMYlWjc21CEwGGHvDU9h+01k5ufZxxx2Xk+sy+QnrExM0rFNMfyFbCZR/2guMLgghtgkhZgohqoQQRUKIjwghbhJCdOZaNqb3kSu/8UO1q3NyXSZ/efDBB3MtApNHsD4xQcM6pQevZ+v7ZNLVMAkiKgLw/wCcAGAgUo0+IYS4LFvyMExvpXIGJ1BmguXGG2/MtQhMHsH65I1sz3abnfNczbD7gXWKSYdcepR4JVsJlI8AUAvgzzDWVF0KYDaAiwBcAuBsAJ/MhiwM09sxE1EyTFCYCSYZJghYn5igyYVO9ZXZo74iJ6NHtvJ4LYYxy3UqgIkwAm58EUApgOsBtAGYmSVZGKZXM/T8H+daBCbPWLFiRa5FYPII1icmaLKlU/lgxOTDPfRnsmV4fQrA3UKItTicKJmEEB1CiMUAnoURbp5h+j17H78p1yIwecacOXNyLQKTR7A+MUHDOsX0F7JleJUA2J74vwlGGPmBlt9fBvCJLMnCML2awWd9K9ciMHnGn/70p1yL0CvgkeJgYH1igoZ1iukvZMvw2gFgFAAkwrbvhOF2aDIZQHuWZGEYbXLRUWtauzzr12Tym1tvvTXXIjB5BOsTEzSsU0x/IVtRDf8N4AsAzKgBfwLwPSKqhGH8XQTg/izJwjC9muIjT8i1CEyeMXMmL6FlgoP1iQka1immv5CtGa+bAPyCiAoT328EcB+A82EYZMsAXJslWRimVxNr2Z9rEZg8Y+fOnbkWgckjWJ+YoOnPOsUu0P2LrMx4CSF2wHA3NL+3A7g88QEAEBFlQxaG6e3E21tyLQKTZxw4cCDXIjB5BOsTEzSsU0x/IVszXkqIqICIrgDwTq5lYZjeQOHoY3MtApNnTJ8+PdciMHkE6xMTNKxTTH8ho4ZXwqg6n4iuJ6IriKja8lsJEX0XRrTD38LI7cUw/Z7mN9jtgAmWJUuW5FoEJo9gfWKChnVKDrsh6tNXyipjroYJI+s5AONx2KhqI6LPA+iEsa5rJIC1AK4G8FimZOlvjL3hKWy/6axci8H4ZNCnv5ZrEZg849e//nWuRWDyCNYnJmhYp5j+QiZnvH4B4EgAvwJwNgzjqgXA7wE8CeADAJ8UQpwqhPibEEJkUBaG6TPUP/pT950YxgOzZ8/OtQhMHsH6xAQN6xTTX8ik4XUmgD8KIb4nhPiHEGIJgCthGGNrAHxCCLE6g9eXQkSFRHQzEdURURsRvUpEZ2ZbDoZRMfT8H+daBCYNnNwd0nGFSOfYFStW+D6WYeywPjFBk65O9RU3M4bJpOE1DMArtm3m96VCiHgGr+3EnwB8G8BfAPwvgBiAfxDRJ3IkD8Mkse+p23ItApNnzJs3L9ciMHkE61PuyTdDg3WK6S9kMpx8GEC7bZv5/WAGr6uEiKYBuBDAd4QQtyS23Q9gAwyXyI/lQi6GsVL5KV7jxQQLr59ggoT1iQka1immv5DpcPJjiegE8wPgo4ntE6zbLb9nmvNhzHD93tyQyCl2L4DTiGh0FmTICn5Hw/ryKFpflt1Ky1tP51qEJPKlXPsb1ud277335lASRofe9J65ucv2dn2yy9+byjbT9NV77e06le/0Vb3pi2Ta8FoE4L+WzzOJ7Xfbtr+W+JtppgLYLIRosm1fm/h7fFAX0lVi6375rPiqe3O757E3PBVYufiVQXcfL/s57Vs4YqKv86VLX9M/U94gn182yIUs06ZNC0yG3lKW6Q4uBXEf9vpJds6+UMd7lcuuT0Fcz29d76d8g7y+Ljptnddjgrhmpu9bRw4g2DoqiOODPk9vvHaQdWEmcOqz9VaZdaBMBRMkIs8Ou0KI+zIhiwkRbQCwRwjxadv2yQA2ApgvhPid4tihAKpsmycBeHTIud9HtLInRRn+9e0ZOPO21UnfrZi/Wfcz/5cda/1uRXa8E7J9rNe1yubleNl92be5XcvPvThdI9O4ySu7V13ZOj6sReGoycrrmueTfVfJGBQ6eqJzDic9kG1Tla/su9v/Xt8Vu7x2+VQy6l7Tfl43+fw81x9PC+Ona2OO51F991JuXnEqNwDK66t0SKWfbs9HdW37Pk46oIvb+Z1k9yOvn3rVraysdZRuG+JVj/y+r17QrW+yjW5Zqr77vaZOfRDU+e10fFiLNbctAKD/Pgf9rLy2Hbrvpuwe0pVP9ze3OtLr++i23e8z0/ndRKd97DpQh33LfwEAJwgh1rndXzbJmOHVGyGibQDeEUJ8zrZ9HIBtAK4RQtyuOPYnADjcHMMwDMMwDMP0fi4WQvw510JYyWRwjd5IG4BCyfYiy+8q7gbwiG3bcQAehLF2bFPa0jGMkXD8CQBfgDEYwDDpwjrFBAnrExM0rFNM0EwC8CiAzbkWxE5/M7x2ARgp2T4i8bdOdaAQoh5AvXUbEZn/bhJCbAxCQKZ/Y9GpbaxTTBCwTjFBwvrEBA3rFBM0Fp1qyaUcMjIdXKO38SaAiURUbtt+iuV3hmEYhmEYhmGYQOlvhtejMPKLXWFuIKJCAJcCeFUI8UGuBGMYhmEYhmEYJn/pV66GQohXiegRAL9MRCncCmAegLEALsulbAzDMAzDMAzD5C/9yvBKcDGM/GIXAagE8BaAs4UQa3ycay+Anyb+MkwQsE4xQcM6xQQJ6xMTNKxTTND0Wp3qV+HkGYZhGIZhGIZhckF/W+PFMAzDMAzDMAyTddjwYhiGYRiGYRiGyTBseDEMwzAMwzAMw2QYNrwYhmEYhmEYhmEyDBtePiCiQiK6mYjqiKiNiF4lojNzLReTG4joZCK6i4g2EtEhItpBRA8T0UTJvh8hopVE1EJEDUT0ZyKqkuwXIqLvEtF7RNRORG8R0VzF9bXOyfRdiOj7RCSIaIPkt48R0QtE1EpEu4noDiIqleynXW/pnpPpWxDRCUT090Q90UpEG4jom7Z9WJ8YLYhoAhE9REQfJp7tJiL6ERGV2PZjnWJSIKJSIvppov/SkGjjLlHsm7O+k5dzaiGE4I/HD4AHAXQBWAwjGfNLie+fyLVs/MmJPjwKYBeAOwBcDuAHAHYDaAFwrGW/UTBCm24F8E0ACwE0AHgTQIHtnL8EIAD8HsDXADyZ+H6hbT/tc/Knb34Sz/hQQp822H47HkAbgDcAzAfwcwDtAP4pOY9WveXlnPzpOx8AnwHQAeAVANck6pWbAPyK9Yk/PvRpNIADALYDuCGhA39MtFNPsE7xR0OHxib05X0A/0n8f4lkv5z2nXTPqX3fuS74vvYBMC1R4NdZthUlHt5LuZaPPznRiY9JXtQJiYbgAcu2uwG0Ahhj2fY/CX26wrJtJIBOAHdZthGANQA+ABD2ek7+9N0PgIcAPAvgOaQaXv8AUAeg3LLt8sTz/4xlm3a9pXtO/vSdD4ByGINBjwEIOezH+sQfXZ1amHiGx9i235fYXsk6xR8XHSoEMDzx/0lQG1456zt5Oafuh10NvXM+gBgMyxcAIIRoB3AvgNOIaHSuBGNygxDiJSFEp23bFgAbAXzEsvn/AXhSCLHDst8zADYDmGPZ7wsAojAqBnM/AeAeGKM0p/k4J9MHIaLpMOqcb0l+KwdwJgzjvsny0/0wZsesz1+r3vJ4Tqbv8CUAwwB8XwgRJ6IBRJTU/rM+MR4pT/zdY9u+C0AcQCfrFOOEEKJDCLFbY9dc9p28nFMLNry8MxXAZtsLDwBrE3+Pz644TG+EiAhGR2df4vtIAEMBvCbZfS0MvTKZCsO17G3JfubvXs/J9DGIKAzgTgB/EELUSHY5DkAEtuefGAR4E6k6pVNveTkn03f4HwBNAEYS0TswOqhNRHQPERUl9mF9YrzwXOLvvUR0PBGNJqIvAlgA4A4hxCGwTjFp0gv6Tlrn9AIbXt4ZAWNEx465rTqLsjC9ly/DmKL+a+L7iMRfle4MIqJCy757EqMq9v2Awzrm5ZxM32M+gCMA/FDxu9vzr7btq1NveTkn03eYAKOz+gSAVTBGe5fC0LE/JvZhfWK0EUKshFE3nQlgHYAdMNyi7xRCXJPYjXWKSZdc9510z6lNxOsBDIphLFC20275nenHENEkAEsAvAzD3x04rBduutMBfR3zck6mD0FEgwH8DMAiIcRexW5uz7/Ytm8QOsX1W9+kFEAJgN8KIcwoho8RUQGArxPRj8D6xHhnO4y1Ln8DsB/AWQAWEtFuIcRdYJ1i0ifXfafA+/xseHmnDcaCQDtFlt+ZfgoRDQfwFICDAM4XQsQSP5l6oaM7ujrm5ZxM3+LnMCIs3emwj9vzb7PtG4ROsT71Tczn9qBt+zIAX4exTqE1sY31iXGFiC6EsR5rohDiw8TmxxJrB28mogfBdRSTPrnuOwXe52dXQ+/swuFpSivmtrosysL0IohoIIB/AqgAMEsIYdUFc1papTsNQogOy77DE+vE7PsBh3XMyzmZPgIRTYARSvkOANVENJaIxsKo6KOJ74Pg/vzt+qdTb3k5J9N3MJ+bPRBCfeJvJVifGG9cCWCdxegy+TuM2dWpYJ1i0ifXfSfdc2rDhpd33gQwMRFZx8oplt+ZfkZigfoKABMBnC2EqLX+LoTYCSNnxEmSw6chWW/ehNFwfcS2X5KOeTwn03cYCaNuvgPAe5bPKTD06z0APwKwAUA3bM8/4T52PFJ1Sqfe8nJOpu/weuLvSNt2c33CXrA+Md4YBiAs2R5N/I2AdYpJk17Qd9I6pxfY8PLOozAqmyvMDYlFeJcCeFUI8UGuBGNyQyL63F9huOtcIIR4WbHr3wCcbU05QESfhtGZfsSy3xMwkkZeadmPYCyE3wkjqaTXczJ9hw0AzpV8NsJYwH4ugHuFEAcBPAPgK0RUZjn+IhhreqzPX6ve8nhOpu/wcOLvZbbtl8PoxD7H+sR4ZDOAqUQ00bZ9Loxw8m+xTjEBkcu+k5dz6hFkMrT+8oHRiHUB+BWMSuLFxPfpuZaNPznRh9thJN37O4Cv2D+W/UbDCC+/FcDVAL4HYx3PWwAKbef8VeKcv4PROTIzpX/Jtp/2OfnTtz+QJ1A+AcYi3zcSDcHPYficr5Icr1VveTknf/rOB0Y+JAFjkOjKhD4IADeyPvHHhz5Nh2G074ER3fBKGImNBYD/Y53ij6YefQPAD2DkyRIwDKIfJD4DE/vktO+ke07te851offFD4y1Foth+H62w4jnPzPXcvEnZ/rwXOIllH5s+x4DI5zzIQAHADwAYJjknKFERbAdRkSdDQC+rLi+1jn507c/kBheie2fSHRQ2mCs2bkLQJlkP+16S/ec/Ok7HxguYD9O1CmdALYA+BbrE3/S0KlpMIytXQmdegfAQgAR1in+aOrQdof+01jLfjnrO3k5p86HEidlGIZhGIZhGIZhMgSv8WIYhmEYhmEYhskwbHgxDMMwDMMwDMNkGDa8GIZhGIZhGIZhMgwbXgzDMAzDMAzDMBmGDS+GYRiGYRiGYZgMw4YXwzAMwzAMwzBMhmHDi2EYhmEYhmEYJsOw4cUwDMMwDMMwDJNh2PBiGIZhGIZhGIbJMGx4MQzDMAzDMAzDZBg2vBiGYZheAxH9iYi251oOEyL6CRGJxKclB9d/03L9J7N9fYZhGCY4IrkWgGEYhslviEho7vrJjAqSHhcB6MrBdRcCGATg1zm4NsMwDBMgbHgxDMMwmeYi2/eLAZwp2f42gK+hF3pjCCEeyNF1/wEARPTzXFyfYRiGCQ42vBiGYZiMYjdaiOhUAGfmyphhGIZhmFzQ60YVGYZhmP6LfY0XEY1NrG+6joiuIqJ3iaiViJ4motFk8EMi+pCI2ojoCSIaJDnvZ4noeSI6RETNRPQUER2TpqzbiehJIjqDiF5LXL+GiM5I/H5e4ns7Eb1ORFNtxw8noj8mZO8gol0J+cemIxfDMAzTO+EZL4ZhGKYv8GUABQDuhLHm6bsAHgbwbwBnALgZwFEArgZwC4CvmgcS0UUA7gOwCsD1AEoALADwAhFNFUJsT0OuowAsA/A7AA8AuA7ACiKaD+BGAHcn9vsegIeJ6GghRDyx7W8Ajknc03YAQ2G4YI5JfGcYhmHyCDa8GIZhmL7ASAAThBAHAYCIwjCMmWIAJwkhuhPbqwB8mYgWCCE6iKgUwB0A/iCEuMI8GRHdB+AdGMErroB/jgbwMSHEy4nz1sIw8P4PwCQhxI7E9gMwjLPpAJ4jogoAHwPwHSHELZbz/TINWRiGYZheDLsaMgzDMH2BR0yjK8Grib8PmEaXZXsBDEMNMGaQKgA8SERDzA+AWGLfdCMp1ppGl02uf5tGl237uMTfNgCdAM4goso0ZWAYhmH6ADzjxTAMw/QFdti+m0bYB4rtpjEzIfH334rzNgUplxDiIBG5ypWYjbsewK0A9hDRKwCeBHC/EGJ3mjIxDMMwvRA2vBiGYZi+QMzjdkr8NT07LgIgM2i6Jdu84FcuCCFuJ6IVAM4BMBPAIgDfI6JPCSHWpSkXwzAM08tgw4thGIbJZ7Yl/tYLIZ7JqSQShBDbYMx63UpEEwC8CeBaAF/JpVwMwzBM8PAaL4ZhGCafWQXDnXAhEUXtPyaCcWQdIiohoiLb5m0AmgEU5kAkhmEYJsPwjBfDMAyTtwghmohoAYA/A3iDiB4CsBdGyPazALwI4Bs5EG0igGeJ6GEAtTBcHs8FMAzAQzmQh2EYhskwbHgxDMMweY0QYhkR1QG4AcB3YMwo7QTwPIA/5kisDwA8CODTMNafdQPYBGCOEOJvOZKJYRiGySAkhMi1DAzDMAzTKyGinwD4MYAqAEIIsT/L16+AMUj6BoC3hBBnZ/P6DMMwTHDwGi+GYRiGcWcvgPdzcN3nEtcenYNrMwzDMAHCM14MwzAMo4CIxuFw0uNuIcRzWb7+KQDKEl/3CiHWZ/P6DMMwTHCw4cUwDMMwDMMwDJNh2NWQYRiGYRiGYRgmw7DhxTAMwzAMwzAMk2HY8GIYhmEYhmEYhskwbHgxDMMwDMMwDMNkGDa8GIZhGIZhGIZhMgwbXgzDMAzDMAzDMBmGDS+GYRiGYRiGYZgMw4YXwzAMwzAMwzBMhmHDi2EYhmEYhmEYJsOw4cUwDMMwDMMwDJNh2PBiGIZhGIZhGIbJMGx4MQzDMAzDMAzDZJj/D1e3CKeOG4ZNAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "def _histogram(a, bins=10, bin_range=None, normed=False):\n", + " \"\"\"Calculate histogram for data.\n", + "\n", + " Parameters\n", + " ----------\n", + " a : list\n", + " Data to calculate histogram for\n", + " bins : int, optional\n", + " Number of bins\n", + " bin_range : TYPE, optional\n", + " Range of bins\n", + " normed : bool, optional\n", + " Whether distribution should be normalized\n", + "\n", + " Raises\n", + " ------\n", + " ValueError\n", + " \"\"\"\n", + " from numpy import asarray, iterable, linspace, sort, concatenate\n", + "\n", + " a = asarray(a).ravel()\n", + "\n", + " if bin_range is not None:\n", + " mn, mx = bin_range\n", + " if mn > mx:\n", + " raise ValueError(\"max must be larger than min in range parameter\")\n", + "\n", + " if not iterable(bins):\n", + " if bin_range is None:\n", + " bin_range = (a.min(), a.max())\n", + " mn, mx = [mi + 0.0 for mi in bin_range]\n", + " if mn == mx:\n", + " mn -= 0.5\n", + " mx += 0.5\n", + " bins = linspace(mn, mx, bins, endpoint=False)\n", + " else:\n", + " if (bins[1:] - bins[:-1] < 0).any():\n", + " raise ValueError(\"bins must increase monotonically\")\n", + "\n", + " # best block size probably depends on processor cache size\n", + " block = 65536\n", + " n = sort(a[:block]).searchsorted(bins)\n", + " for i in range(block, a.size, block):\n", + " n += sort(a[i:i + block]).searchsorted(bins)\n", + " n = concatenate([n, [len(a)]])\n", + " n = n[1:] - n[:-1]\n", + "\n", + " if normed:\n", + " db = bins[1] - bins[0]\n", + " return 1.0 / (a.size * db) * n, bins\n", + " else:\n", + " return n, bins\n", + "\n", + "ev = espikes.get(\"events\")\n", + "ts, node_ids = ev[\"times\"], ev[\"senders\"]\n", + "hist_binwidth = 10. # [ms]\n", + " \n", + "fig, ax = plt.subplots(nrows=2, gridspec_kw={\"height_ratios\": (2, 1)})\n", + "ax[0].plot(ts, node_ids, \".\")\n", + "ax[0].scatter(t_dopa_spikes, np.zeros_like(t_dopa_spikes), marker=\"d\", c=\"orange\", alpha=.8, zorder=99)\n", + "ax[0].set_ylabel(\"Neuron ID\")\n", + "\n", + "t_bins = np.arange(\n", + " np.amin(ts), np.amax(ts),\n", + " float(hist_binwidth)\n", + ")\n", + "n, _ = _histogram(ts, bins=t_bins)\n", + "num_neurons = len(np.unique(node_ids))\n", + "heights = 1000 * n / (hist_binwidth * num_neurons)\n", + "ax[1].bar(t_bins, heights, width=hist_binwidth, color=\"tab:blue\", edgecolor=\"none\")\n", + "ax[1].set_yticks([\n", + " int(x) for x in\n", + " np.linspace(0, int(max(heights) * 1.1) + 5, 4)\n", + "])\n", + "ax[1].set_ylabel(\"Rate [s${}^{-1}$]\")\n", + "ax[0].set_xticklabels([])\n", + "ax[-1].set_xlabel(\"Time [ms]\")\n", + "for _ax in ax:\n", + " _ax.set_xlim(0., total_t_sim)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot membrane potential of 10 random excitatory cells\n", + "\n", + "This helps to check if the network is in a balanced excitation/inhibition regime." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "for i in range(10):\n", + " ax.plot(mms[i].get(\"events\")[\"times\"], mms[i].get(\"events\")[\"V_m\"], label=\"V_m\")\n", + "ax.set_xlim(0., total_t_sim)\n", + "ax.set_ylabel(\"$V_m$ [mV]\")\n", + "ax.set_xlabel(\"Time [ms]\")\n", + "\n", + "None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Timeseries\n", + "\n", + "We should verify that the dopamine concentration is the same in group and nongroup neurons.\n", + "\n", + "Note that the timeseries resolution (due to the chunking of the simulation) could be too low to see fast dopamine dynamics. Use more chunks to increase the temporal resolution of this plot, or fewer to speed up the simulation. Consider the relationship between $\\tau_d$ and how many chunks we need to adequately visualize the dynamics." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig,ax = plt.subplots()\n", + "\n", + "ax.plot(log[\"t\"], log[\"reinforced_group\"][\"n_avg\"], label=\"avg dopa group\", linestyle=\":\", markersize=10, alpha=.7, marker=\"x\")\n", + "ax.plot(log[\"t\"], log[\"not_reinforced_group\"][\"n_avg\"], label=\"avg dopa nongroup\", linestyle=\"--\", alpha=.7, marker=\"o\")\n", + "ax.legend()\n", + "\n", + "ax.set_xlim(0., total_t_sim)\n", + "ax.set_xlabel(\"Time [ms]\")\n", + "ax.set_ylabel(\"Dopamine concentration [a.u.]\")\n", + "\n", + "None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In any case, all synapses seem to be receiving the same dopamine signal.\n", + "\n", + "Now plot the average eligibility trace $c$ for group and nongroup neurons:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig,ax = plt.subplots(figsize=(8, 3))\n", + "ax.plot(log[\"t\"], log[\"reinforced_group\"][\"c_sum\"], label=\"group sum\")\n", + "ax.plot(log[\"t\"], log[\"not_reinforced_group\"][\"c_sum\"], label=\"nongroup sum\")\n", + "ax.scatter(t_dopa_spikes, np.zeros_like(t_dopa_spikes), marker=\"d\", c=\"orange\", alpha=.8, zorder=99)\n", + "ax.set_xlim(0., total_t_sim)\n", + "ax.set_xlabel(\"Time [ms]\")\n", + "ax.set_ylabel(\"Eligibility trace\")\n", + "ax.legend()\n", + "\n", + "None" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA24AAAGjCAYAAABUuEYkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAABJ0AAASdAHeZh94AACeRUlEQVR4nOzdeXxU1fnH8c+ZmewLSSBh33fBFQUXFK27LRar0mpbwbrhUitaW+VXqxaXKm5d0KoFtVWsVkXFBa2tgluLu4CyhH0PISF7Mtv5/XEnwyQECMmQmUy+71dv78ydO/c+N3kM88w59xxjrUVERERERETilyvWAYiIiIiIiMjeqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE4pwKNxERERERkTinwk1ERERERCTOqXATERERERGJcyrcRERERERE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PERy3777dRzllHQUrS3cCoDFe3k9AKS38hzR9iRwPfAMTjfOAPCGMWbsPt53DE5X0CycglSi4L333uPII48kNTWVgQMH8uijj3LbbbftNnedMYZrrrmGZ555hhEjRpCSksL8+fMB+OKLLzjzzDPJzs4mMzOTk08+mf/+978N3t/UMcG5odkYw9q1a8Pb+vXrx/e+9z3efvttDjvsMFJTUznooIN46aWXon799df18ssvM3LkSFJSUhgxYkT42iI15zqffPJJ8vPz+fDDD7n++uvJz88nIyODc845h+3btzfYNxgMctttt9GjRw/S09M56aST+Oabb+jXrx+TJ09ucExjDAsWLOCqq66ioKCAXr16hV9/+OGHw7+THj16cPXVV7MzNBpYvcbHrHfiiSdy4oknhp+/9957GGN47rnnmDZtGt26dSMjI4Ozzz6bDRs2NP8HK1FzwgknxDoESTDKqY7NWkvl+x+w/rLLWX3Wd9n57D/CkzV3+83/kXH00ft9TOWUdBStnYB7AzBsL68fBxS28hxRY4wZDfwIuNFae19o29+AJcC9wLF7efurQI61tsIY80vgsAMcbsL74osvOOOMM+jevTu33347gUCA3/3ud+Tn5ze5/3/+8x+ef/55rrnmGrp06UK/fv1YunQpxx9/PNnZ2fzqV78iKSmJRx99lBNPPJEFCxYwZsyYFsW2cuVKfvjDHzJlyhQmTZrEE088wfnnn8/8+fM59dR9NtDulw8++ICXXnqJq666iqysLP74xz9y7rnnsn79ejp37gyw39f585//nNzcXG699VbWrl3LQw89xDXXXMNzzz0X3ufmm2/m3nvvZfz48Zx++ul89dVXnH766XtsybzqqqvIz8/nt7/9bbjF7bbbbuP222/nlFNO4corr2T58uU88sgjfPLJJ3z44YckJSW16Gdy5513Yozh17/+NUVFRTz00EOccsopfPnll6SlpbXomNIyM2fO5MEHH4x1GJJAlFMdU7C6mrJXX6Xk70/jbTRtTca4E+h88cUtKtpAOSUdR2sLtznA9caYF4EVoW0WwBhzGTARuKmV54im83Ba2B6r32CtrTXGzALuMsb0ttY2+bW+tbaprqAxs/Wuu6j7dlmswwAgZfgwuk2btt/vu/XWW3G73Xz44Yf06NEDcOZiGT58eJP7L1++nMWLF3PQQQeFt51z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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig,ax = plt.subplots(nrows=2, gridspec_kw={\"height_ratios\": (2, 1)})\n", + "\n", + "ax[0].plot(log[\"t\"], log[\"reinforced_group\"][\"w_avg\"], label=\"group\")\n", + "ax[0].plot(log[\"t\"], log[\"not_reinforced_group\"][\"w_avg\"], label=\"nongroup\")\n", + "ax[0].plot(log[\"t\"], log[\"w_net\"], label=\"net\")\n", + "ax[1].plot(log[\"t\"], np.array(log[\"reinforced_group\"][\"w_avg\"]) - np.array(log[\"not_reinforced_group\"][\"w_avg\"]),\n", + " label=\"group - nongroup\", c=\"tab:red\")\n", + "for _ax in ax:\n", + " _ax.legend()\n", + " _ax.set_xlim(0., total_t_sim)\n", + "\n", + "ax[-1].set_xlabel(\"Time [ms]\")\n", + "ax[0].set_xticklabels([])\n", + "ax[0].set_ylabel(\"Average weight                                                      \")\n", + "\n", + "None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also plot all `subgroup_size` weights over time for the reinforced and non-reinforced groups as a scatterplot." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + " group_weight_times = [[] for _ in range(n_subgroups)]\n", + "group_weight_values = [[] for _ in range(n_subgroups)]\n", + " \n", + "senders = np.array(wr.events[\"senders\"])\n", + "\n", + "for subgroup_idx in range(n_subgroups):\n", + " nodes_ex_gids = nodes_ex[subgroup_indices[subgroup_idx]].tolist()\n", + " idx = [np.where(senders == nodes_ex_gids[i])[0] for i in range(subgroup_size)]\n", + " idx = [item for sublist in idx for item in sublist]\n", + " group_weight_times[subgroup_idx] = wr.events[\"times\"][idx]\n", + " group_weight_values[subgroup_idx] = wr.events[\"weights\"][idx]\n", + "\n", + "fig, ax = plt.subplots()\n", + "for subgroup_idx in range(n_subgroups):\n", + " if subgroup_idx == reinforced_subgroup_idx:\n", + " c = \"red\"\n", + " zorder = 99\n", + " marker = \"x\"\n", + " label = \"group\"\n", + " else:\n", + " c = \"blue\"\n", + " zorder=1\n", + " marker = \"o\"\n", + " label = \"nongroup\"\n", + " \n", + " ax.scatter(group_weight_times[subgroup_idx], group_weight_values[subgroup_idx], c=c, alpha=.5, zorder=zorder, marker=marker, label=label)\n", + "\n", + "ax.set_ylabel(\"Weight\")\n", + "ax.set_xlabel(\"Time [ms]\")\n", + "ax.legend()\n", + "\n", + "None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Citations\n", + "---------\n", + "\n", + "[1] Mikaitis M, Pineda García G,\n", + "Knight JC and Furber SB (2018)\n", + "Neuromodulated Synaptic Plasticity\n", + "on the SpiNNaker Neuromorphic\n", + "System. Front. Neurosci. 12:105.\n", + "doi: 10.3389/fnins.2018.00105\n", + "\n", + "[2] PyGeNN: A Python library for GPU-enhanced neural networks, James C. Knight, Anton Komissarov, Thomas Nowotny. Frontiers\n", + "\n", + "[3] Eugene M. Izhikevich. Solving the distal reward problem through linkage of STDP and dopamine signaling. Cerebral Cortex 17, no. 10 (2007): 2443-2452.\n", + "\n", + "[4] Nicolas Brunel. Dynamics of sparsely connected networks of excitatory and inhibitory spiking neurons. Journal of Computational Neuroscience 8(3):183-208 (2000)\n", + "\n", + "\n", + "Acknowledgements\n", + "----------------\n", + "\n", + "This software was developed in part or in whole in the Human Brain Project, funded from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under Specific Grant Agreements No. 720270, No. 785907 and No. 945539 (Human Brain Project SGA1, SGA2 and SGA3).\n", + "\n", + "The authors would like to thank James Knight, Garibaldi García and Mantas Mikaitis for their kind and helpful feedback.\n", + "\n", + "\n", + "License\n", + "-------\n", + "\n", + "This notebook (and associated files) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.\n", + "\n", + "This notebook (and associated files) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details." + ] + } + ], + "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.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/doc/tutorials/stdp_windows/stdp_windows.ipynb b/doc/tutorials/stdp_windows/stdp_windows.ipynb new file mode 100644 index 000000000..89463cb4b --- /dev/null +++ b/doc/tutorials/stdp_windows/stdp_windows.ipynb @@ -0,0 +1,902 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NESTML STDP windows tutorial\n", + "\n", + "In this tutorial, we will plot the \"window function\", relating the weight change of a synapse to the relative timing of a single pair of pre- and postsynaptic spikes. This type of synaptic plasticity is commonly known as spike-timing depdendent plasticity (STDP)." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib as mpl\n", + "mpl.rcParams['axes.formatter.useoffset'] = False\n", + "import matplotlib.pyplot as plt\n", + "import nest\n", + "import numpy as np\n", + "import os\n", + "import re\n", + "from pynestml.frontend.pynestml_frontend import generate_nest_target\n", + "\n", + "NEST_SIMULATOR_INSTALL_LOCATION = nest.ll_api.sli_func(\"statusdict/prefix ::\")" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1IAAAKeCAYAAACveyp8AAAABHNCSVQICAgIfAhkiAAAIABJREFUeF7snQnYflO5/3epU6c6rqjToJIUpyJUlCl+FZEpEcqcKVPGEJI/UgmZopKhn3kmkSn6GcqYIgmZxxIiGpxynv/+rPru7ne/+3neZ36f4buu67n2s9de43fd617rXute93pRLXeZnREwAkbACBgBI2AEjIARMAJGwAg0jcCLmw7pgEbACBgBI2AEjIARMAJGwAgYASOQELAgZUIwAkbACBgBI2AEjIARMAJGwAi0iIAFqRYBc3AjYASMgBEwAkbACBgBI2AEjIAFKdOAETACRsAIGAEjYASMgBEwAkagRQQsSLUImIMbASNgBIyAETACRsAIGAEjYAQsSJkGjIARMAJGwAgYASNgBIyAETACLSJgQapFwBzcCBgBI2AEjIARMAJGwAgYASNgQco0YASMgBEwAkbACBgBI2AEjIARaBEBC1ItAubgRsAIGAEjYASMgBEwAkbACBgBC1KmASNgBIyAETACRsAIGAEjYASMQIsIWJBqETAHNwJGwAgYASNgBIyAETACRsAIWJAyDRgBI2AEjIARMAJGwAgYASNgBFpEwIJUi4A5uBEwAkbACBgBI2AEjIARMAJGwIKUacAIGAEjYASMgBEwAkbACBgBI9AiAi9pMbyDG4Hs//7v/yag8OIX/1se51t8N1xGwAgYASNgBIyAETACRmAUEbAgNYqt2sM6RSEKgekf//hHIVjxXhayVBQLVz1sFCdtBIyAETACRsAIGAEj0HcEXlTLXd9zdYZDiUAru00KK8HKgtRQNrkLbQSMgBEwAkbACBgBI1AHAQtSdYCx90QEJBg9+OCD2V577ZU999xzSYVv0003zeaff/7s7rvvzmbOnJlts8022aKLLpq95CWTNzstTJmqjIARMAJGwAgYASNgBEYFAQtSo9KSPayHdpXuv//+bKONNsquueaaIrc555wzm3322bM//elP2VNPPZW9+tWvzjbccMPsgAMOyP7jP/4jhZPKnwWpHjaSkzYCRsAIGAEjYASMgBHoKwIWpPoK93Bmpt2oWbNmZR/96EfrnoNiF4ozUwhWv/71r7M3v/nNE85PDWftXWojYASMgBEwAkbACBgBIzAZgcn6V5PD2GfMEdBO0tJLL52deOKJ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wgoZd0KxeBWt74kXMwl81atelb361a9OOPE/9kcLUWNHPq5wQKBM/0ceeWR2xhlnpD6yww47JEEKVw5nEI1APQSs2lcPGfvXRaCKwXgFpy5cY/tBdBLppYp2xhYgV9wINInAMssskwQiHH0o8lvey36ssmMUCHfHHXekO/7U98yrmwTdwcYCgbgY4QXhsWjyrlfSO1Jdh9QJGgEjAAJSJzIaRsAIdIYAxiIwNoG75557klDEpE+q1Updqn0yMoE/4djBsgDVWRs49ugj4D4y+m3cixp6R6oXqDpNI2AErBphGjACXULgvPPOK+6OOumkk7K999479S+EKxly4cn5qEcffTS76KKLUs6veMUrsh133LEwBuQd4S41iJMxAkbACPwLAe9ImRSMgBEwAkbACAwwAhhpWX311dOlvNzXt++++6bdqGWXXbYwic5qOsLUEUcckWHgBaFpk002ybbYYosUlm9ecR/gRnbRjIARGEoELEgNZbO50EbACBgBIzDqCOjsExfrPvXUU9nFF1+cqoz/V7/61eyggw6aJBwhNOEQmhZYYIFJ56n0rWp3yuq4o05Rrp8RMALdRsCCVLcRdXpGwAgYASNgBLqAgAQbVPs++9nPZosvvnj29NNPpwvQcfWunXjHO96RdrDWXnvtuiq2Slu7VGVjFFWCVheq5CSMgBEwAiOFgAWpkWpOV8YIGAEjYARGAYGohnfqqadmf/rTn5LaHueeuCPq8ssvTyp8nIt64oknkvreaqutlq288srZ/PPPX1wz0MwuU8xLu2BlAWsUMHUdjIARMALdRsCCVLcRdXpGwAgYASNgBDpEQAINyey3335JQFpwwQVTqvPOO2/2qU99Kp2XQpC6+eabkwrfxz72scK6XxSOykWJwhLhZPZZaoHl8H43AkbACBiBagQsSFXjYl8jYASMgBEwAgOBACp8F154YfaGN7whW2655dLuEztT88wzTyrfSiutVJRTwlAj1by420S4u+66K8PEui7xJTHSaZTGQADjQhgBI2AEphkBC1LT3ADO3ggYASNgBIxAGYG4o7TXXntlnJO6//77s4985COFBb4q9TvtLlV9Iw/8JSA9/PDDGebUv/e972VYBlxqqaVS+ux8ycpfDF8uo9+NgBEwAuOOgAWpAaKAOGDVGwTrFTcOuoSR6kZUD/HqYj307G8EjIARGDwE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wAgYASMwQgQsSI0QMAc3AkbACBgBI2AEjIARMAJGwAhYkHIbMAJGwAgYASNgBIyAETACRsAIjBABC1IjBMzBjYARMAJGwAgYASNgBIyAETACFqTcBoyAETACRsAIGAEjYASMgBEwAiNEwILUCAFzcCNgBIyAETACRsAIGAEjYASMgAUptwEjYASMgBEwAkbACBgBI2AEjMAIEbAgNULAHNwIGAEjYASMgBEwAkbACBgBI2BBym3ACBgBI2AEjIARMAJGwAgYASMwQgQsSI0QMAc3AkbACBgBI2AEjIARMAJGwAhYkHIbMAJGwAgYASNgBIyAETACRsAIjBABC1IjBMzBjYARMAJGwAgYASNgBIyAETACFqTcBoyAETACRsAIGAEjYASMgBEwAiNEwILUCAFzcCNgBIyAETACRsAIGAEjYASMgAUptwEjYASMgBEwAkbACBgBI2AEjMAIEbAgNULAHNwIGAEjYASMgBEwAkbACBgBI2BBym3ACBgBI2AEjIARMAJGwAgYASMwQgQsSI0QMAc3AkbACBgBI2AEjIARMAJGwAhYkHIbMAJGwAgMgcD//M//pK8842+IKOPySWUbl8ydqRHoIgLqg13MwkkbASNgBEaFwL+OKpYjGQEjYAQGFIEoOP3Lv/xLwe///b//V/zrvzYPlxJc+I7Ts9ewqBwqH++xLHUCVl6XXpe5l/nl9RdNe1mGdvLKyzmZaNQKH/VFaJa361ZxJqJ/pH2/ts+JiKvLbAR6gcAbGqXrRUbOwwgYASPQbwjkk7P8nfL+4Q9/KOacc84kTL300kvF888/X/z9738vFl544XGvTizvq6++Wjz00EOpXPKvq48KPdS3ca/YEAXIy807biST7TyNIbIb108TpZydAClvs7Hu6oOdyGcipMFYY4FqIlDKZTQCRWFByq3ACBiBSYuAJuECQDs5t99+e/HjH/84eV933XXFZz7zmeLRRx8tnn766eKBBx4oXnnllWL77bdP35daaqliypQpxVve8pZK9Y/dhDjB7zTApM2PfB588MHi4osvLn77298Wl1xySXHyyScXa621VoFg9aY3vam4+eabi5/85CfFW9/61hTnbW97W7H55psXs8wyS1Ws8dpNGykuEdMc35yWpE29EHxPO+20hAdu3nnnLdZff/2RZt3x8LH8TJzPOOOM4ne/+13x5je/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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Preliminaries\n", + "\n", + "Experiments have shown that synaptic strength changes as a function of the precise spike timing of the presynaptic and postsynaptic neurons. If the pre neuron fires an action potential strictly before the post neuron, the synapse connecting them will be strengthened (“facilitated”). If the pre neuron fires after the post neuron, the synapse will be weakened (“depressed”). The depression and facilitation effects become stronger when the spikes occurred closer together in time. This is illustrated by empirical results (open circles), fitted by exponential curves (solid lines).\n", + "\n", + "\n", + "
\n", + "\n", + "
\n", + "\n", + "*Asymmetric STDP learning window. Spike-timing window of STDP for the induction of synaptic potentiation and depression characterized in hippocampal cultures. Data points from Bi and Poo (1998) [18], represent the relative change in the amplitude of EPSC after repetitive correlated activity of pre-post spike pairs. The LTP (+) and LTD (-) windows are fitted by the exponential function ∆g = A ± exp(−|∆t|/τ), with parameters A + = 0.86, A − = −0.25, τ + = 19 ms, and τ − = 34 ms. Adopted from Bi and Wang (2002).*\n", + "\n", + "We will define the theoretical model following [3]_.\n", + "\n", + "A pair of spikes in the input and the output cell, at times $t_i$ and $t_j$ respectively, induces a change $\\Delta w$ in the weight $w$:\n", + "\n", + "\\begin{equation}\n", + "\\Delta^\\pm w = \\pm \\lambda \\cdot f_\\pm(w) \\cdot K(|t_o - t_i|)\n", + "\\end{equation}\n", + "\n", + "The weight is increased by $\\Delta^+ w$ when $t_o>t_i$ and decreased by $\\Delta^- w$ when $t_i>t_o$. The temporal dependence of the update is defined by the filter kernel $K$ which is taken to be $K(t) = \\exp(-t/\\tau)$. The coefficient $\\lambda\\in\\mathbb{R}$ sets the magnitude of the update. The functions $f_\\pm(w)$ determine the relative magnitude of the changes in the positive and negative direction. These are here taken as\n", + "\n", + "\\begin{align}\n", + "f_+(w) &= (1 - w)^{\\mu_+}\\\\\n", + "f_-(w) &= \\alpha w^{\\mu_-}\n", + "\\end{align}\n", + "\n", + "with the parameter $\\alpha\\in\\mathbb{R}, \\alpha>0$ allowing to set an asymmetry between increasing and decreasing the synaptic efficacy, and $\\mu_\\pm\\in\\{0,1\\}$ allowing to choose between four different kinds of STDP (for references, see https://nest-simulator.readthedocs.io/en/nest-2.20.1/models/stdp.html?highlight=stdp#_CPPv4I0EN4nest14STDPConnectionE).\n", + "\n", + "To implement the kernel, we use two extra state variables to keep track of recent spiking activity. These could correspond to calcium concentration in biology. One presynaptic trace value and another postsynaptic trace value is used, for pre- and post spiking, respectively. These maintain a history of neuron spikes, being incremented by 1 whenever a spike is generated, and decaying back to zero exponentially; in other words, a convolution between the exponentially decaying kernel and the emitted spike train:\n", + "\n", + "\\begin{equation}\n", + "\\text{tr_pre} = K \\ast \\sum_i \\delta_{pre,i}\n", + "\\end{equation}\n", + "\n", + "and\n", + "\n", + "\\begin{equation}\n", + "\\text{tr_post} = K \\ast \\sum_i \\delta_{post,i}\n", + "\\end{equation}\n", + "\n", + "These are implemented in the NESTML model as follows:\n", + "\n", + "```\n", + " equations:\n", + " # all-to-all trace of presynaptic neuron\n", + " kernel pre_tr_kernel = exp(-t / tau_tr_pre)\n", + " inline pre_tr real = convolve(pre_tr_kernel, pre_spikes)\n", + "\n", + " # all-to-all trace of postsynaptic neuron\n", + " kernel post_tr_kernel = exp(-t / tau_tr_post)\n", + " inline post_tr real = convolve(post_tr_kernel, post_spikes)\n", + "end\n", + "```\n", + "\n", + "with time constants defined as parameters:\n", + "\n", + "```\n", + " parameters:\n", + " tau_tr_pre ms = 20 ms\n", + " tau_tr_post ms = 20 ms\n", + " end\n", + "```\n", + "\n", + "With the traces in place, the weight updates can then be expressed closely following the mathematical definitions.\n", + "\n", + "Begin by defining the weight and its initial value:\n", + "\n", + "```\n", + " state:\n", + " w real = 1.\n", + " end\n", + "```\n", + "\n", + "The update rule for facilitation:\n", + "\n", + "\\begin{equation}\n", + "\\Delta^+ w = \\lambda \\cdot (1 - w)^{\\mu+} \\cdot \\text{pre_trace}\n", + "\\end{equation}\n", + "\n", + "In NESTML, this rule is written in the `onReceive` event handler block. Statements in this block will be executed when the event occurs: in this case, receiving a presynaptic spike. In NESTML, additional scaling with an absolute maximum weight ``Wmax`` is added.\n", + "\n", + "```\n", + " onReceive(post_spikes):\n", + " # potentiate synapse\n", + " w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace ))\n", + " w = min(Wmax, w_)\n", + " end\n", + "```\n", + "\n", + "The update rule for depression :\n", + "\n", + "\\begin{equation}\n", + "\\Delta^- w = -\\alpha \\cdot \\lambda \\cdot w^{\\mu_-} \\cdot \\text{post_trace}\n", + "\\end{equation}\n", + "\n", + "```\n", + " onReceive(pre_spikes):\n", + " # depress synapse\n", + " w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace ))\n", + " w = max(Wmin, w_)\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, d)\n", + " end\n", + "```\n", + "\n", + "Finally, the remaining parameters are defined:\n", + "\n", + "```\n", + " parameters:\n", + " lambda real = .01\n", + " alpha real = 1.\n", + " mu_plus real = 1.\n", + " mu_minus real = 1.\n", + " Wmax real = 100.\n", + " Wmin real = 0.\n", + " end\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generating code with NESTML\n", + "\n", + "### Formulating the model in NESTML\n", + "\n", + "To generate fast code, NESTML needs to process the synapse model together with the neuron model that will be its postsynaptic partner in the network instantiantion.\n", + "\n", + "In this tutorial, we will use a very simple integrate-and-fire model, where arriving spikes cause an instantaneous increment of the membrane potential. Let's download the model from the NESTML repository so it becomes available locally:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('models/neurons/iaf_psc_delta.nestml', )" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import urllib.request \n", + "if not os.path.isdir(\"models\"):\n", + " os.makedirs(\"models\")\n", + "if not os.path.isdir(\"models/neurons\"):\n", + " os.makedirs(\"models/neurons\")\n", + "if not os.path.isdir(\"models/synapses\"):\n", + " os.makedirs(\"models/synapses\")\n", + "urllib.request.urlretrieve(\"https://raw.githubusercontent.com/nest/nestml/master/models/neurons/iaf_psc_delta.nestml\",\n", + " \"models/neurons/iaf_psc_delta.nestml\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now define a helper function to generate the C++ code for the models, build it as a NEST extension module, and load the module into the kernel. The resulting model names are composed of associated neuron and synapse partners, because of the co-generation, for example, \"stdp_synapse__with_iaf_psc_delta\" and \"iaf_psc_delta__with_stdp_synapse\".\n", + "\n", + "Because NEST does not support un- or reloading of modules at the time of writing, we implement a workaround that appends a unique number to the name of each generated model, for example, \"stdp_synapse0__with_iaf_psc_delta0\" and \"iaf_psc_delta0__with_stdp_synapse0\".\n", + "\n", + "The resulting neuron and synapse model names are returned by the function, so we do not have to think about these internals." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "n_modules_generated = 0\n", + "def generate_code_for(nestml_synapse_model: str):\n", + " \"\"\"Generate code for a given synapse model, passed as a string, in combination with\n", + " the iaf_psc_delta model.\n", + " \n", + " NEST cannot yet reload modules. Workaround using counter to generate unique names.\"\"\"\n", + " global n_modules_generated\n", + " \n", + " # append digit to the neuron model name and neuron model filename\n", + " with open(\"models/neurons/iaf_psc_delta.nestml\", \"r\") as nestml_model_file_orig:\n", + " nestml_neuron_model = nestml_model_file_orig.read()\n", + " nestml_neuron_model = re.sub(\"neuron\\ [^:\\s]*:\",\n", + " \"neuron iaf_psc_delta\" + str(n_modules_generated) + \":\", nestml_neuron_model)\n", + " with open(\"models/neurons/iaf_psc_delta\" + str(n_modules_generated) + \".nestml\", \"w\") as nestml_model_file_mod:\n", + " print(nestml_neuron_model, file=nestml_model_file_mod)\n", + "\n", + " # append digit to the synapse model name and synapse model filename\n", + " nestml_synapse_model_name = re.findall(\"synapse\\ [^:\\s]*:\", nestml_synapse_model)[0][8:-1]\n", + " nestml_synapse_model = re.sub(\"synapse\\ [^:\\s]*:\",\n", + " \"synapse \" + nestml_synapse_model_name + str(n_modules_generated) + \":\", nestml_synapse_model)\n", + " with open(\"models/synapses/\" + nestml_synapse_model_name + str(n_modules_generated) + \".nestml\", \"w\") as nestml_model_file:\n", + " print(nestml_synapse_model, file=nestml_model_file)\n", + "\n", + " # generate the code for neuron and synapse (co-generated)\n", + " module_name = \"nestml_\" + str(n_modules_generated) + \"_module\"\n", + " generate_nest_target(input_path=[\"models/neurons/iaf_psc_delta\" + str(n_modules_generated) + \".nestml\",\n", + " \"models/synapses/\" + nestml_synapse_model_name + str(n_modules_generated) + \".nestml\"],\n", + " target_path=\"/tmp/nestml_module\",\n", + " logging_level=\"ERROR\",\n", + " module_name=module_name,\n", + " suffix=\"_nestml\",\n", + " codegen_opts={\"nest_path\": NEST_SIMULATOR_INSTALL_LOCATION,\n", + " \"neuron_parent_class\": \"StructuralPlasticityNode\",\n", + " \"neuron_parent_class_include\": \"structural_plasticity_node.h\",\n", + " \"neuron_synapse_pairs\": [{\"neuron\": \"iaf_psc_delta\" + str(n_modules_generated),\n", + " \"synapse\": nestml_synapse_model_name + str(n_modules_generated),\n", + " \"post_ports\": [\"post_spikes\"]}]})\n", + " \n", + " # load module into NEST\n", + " nest.ResetKernel()\n", + " nest.Install(module_name)\n", + "\n", + " mangled_neuron_name = \"iaf_psc_delta\" + str(n_modules_generated) + \"_nestml__with_\" + nestml_synapse_model_name + str(n_modules_generated) + \"_nestml\"\n", + " mangled_synapse_name = nestml_synapse_model_name + str(n_modules_generated) + \"_nestml__with_iaf_psc_delta\" + str(n_modules_generated) + \"_nestml\"\n", + "\n", + " n_modules_generated += 1\n", + " \n", + " return mangled_neuron_name, mangled_synapse_name" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now go on to define the full synapse model in NESTML:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_stdp_model = \"\"\"\n", + "synapse stdp:\n", + "\n", + " state:\n", + " w real = 1.\n", + " end\n", + "\n", + " parameters:\n", + " d ms = 1 ms @nest::delay # !!! cannot have a variable called \"delay\"\n", + " lambda real = .01\n", + " tau_tr_pre ms = 20 ms\n", + " tau_tr_post ms = 20 ms\n", + " alpha real = 1\n", + " mu_plus real = 1\n", + " mu_minus real = 1\n", + " Wmax real = 100.\n", + " Wmin real = 0.\n", + " end\n", + "\n", + " equations:\n", + " kernel pre_trace_kernel = exp(-t / tau_tr_pre)\n", + " inline pre_trace real = convolve(pre_trace_kernel, pre_spikes)\n", + "\n", + " # all-to-all trace of postsynaptic neuron\n", + " kernel post_trace_kernel = exp(-t / tau_tr_post)\n", + " inline post_trace real = convolve(post_trace_kernel, post_spikes)\n", + " end\n", + "\n", + " input:\n", + " pre_spikes nS <- spike\n", + " post_spikes nS <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " onReceive(post_spikes):\n", + " # potentiate synapse\n", + " w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace ))\n", + " w = min(Wmax, w_)\n", + " end\n", + "\n", + " onReceive(pre_spikes):\n", + " # depress synapse\n", + " w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace ))\n", + " w = max(Wmin, w_)\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, d)\n", + " end\n", + "end\n", + "\"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Generate the code, build the user module and make the model available to instantiate in NEST:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "neuron_model_name, synapse_model_name = generate_code_for(nestml_stdp_model)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Running the simulation in NEST\n", + "\n", + "Let's define a function that will instantiate a simple network with one presynaptic cell and one postsynaptic cell connected by a single synapse, then run a simulation and plot the results." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def run_network(pre_spike_time, post_spike_time,\n", + " neuron_model_name,\n", + " synapse_model_name,\n", + " resolution=1., # [ms]\n", + " delay=1., # [ms]\n", + " lmbda=1E-6,\n", + " sim_time=None, # if None, computed from pre and post spike times\n", + " synapse_parameters=None, # optional dictionary passed to the synapse\n", + " fname_snip=\"\"):\n", + "\n", + " nest.set_verbosity(\"M_WARNING\")\n", + " #nest.set_verbosity(\"M_ALL\")\n", + "\n", + " nest.ResetKernel()\n", + " nest.SetKernelStatus({'resolution': resolution})\n", + "\n", + " wr = nest.Create('weight_recorder')\n", + " nest.CopyModel(synapse_model_name, \"stdp_nestml_rec\",\n", + " {\"weight_recorder\": wr[0],\n", + " \"w\": 1.,\n", + " \"delay\": delay,\n", + " \"d\": delay,\n", + " \"receptor_type\": 0,\n", + " \"mu_minus\": 0.,\n", + " \"mu_plus\": 0.})\n", + "\n", + " # create spike_generators with these times\n", + " pre_sg = nest.Create(\"spike_generator\",\n", + " params={\"spike_times\": [pre_spike_time, sim_time - 10.]})\n", + " post_sg = nest.Create(\"spike_generator\",\n", + " params={\"spike_times\": [post_spike_time],\n", + " 'allow_offgrid_times': True})\n", + "\n", + " # create parrot neurons and connect spike_generators\n", + " pre_neuron = nest.Create(\"parrot_neuron\")\n", + " post_neuron = nest.Create(neuron_model_name)\n", + "\n", + " spikedet_pre = nest.Create(\"spike_recorder\")\n", + " spikedet_post = nest.Create(\"spike_recorder\")\n", + " #mm = nest.Create(\"multimeter\", params={\"record_from\" : [\"V_m\"]})\n", + "\n", + " nest.Connect(pre_sg, pre_neuron, \"one_to_one\", syn_spec={\"delay\": 1.})\n", + " nest.Connect(post_sg, post_neuron, \"one_to_one\", syn_spec={\"delay\": 1., \"weight\": 9999.})\n", + " nest.Connect(pre_neuron, post_neuron, \"all_to_all\", syn_spec={'synapse_model': 'stdp_nestml_rec'})\n", + " #nest.Connect(mm, post_neuron)\n", + "\n", + " nest.Connect(pre_neuron, spikedet_pre)\n", + " nest.Connect(post_neuron, spikedet_post)\n", + "\n", + " # get STDP synapse and weight before protocol\n", + " syn = nest.GetConnections(source=pre_neuron, synapse_model=\"stdp_nestml_rec\")\n", + " if synapse_parameters is None:\n", + " synapse_parameters = {}\n", + " synapse_parameters.update({\"lambda\": lmbda})\n", + " nest.SetStatus(syn, synapse_parameters)\n", + "\n", + " initial_weight = nest.GetStatus(syn)[0][\"w\"]\n", + " np.testing.assert_allclose(initial_weight, 1)\n", + " nest.Simulate(sim_time)\n", + " updated_weight = nest.GetStatus(syn)[0][\"w\"]\n", + "\n", + " actual_t_pre_sp = nest.GetStatus(spikedet_pre)[0][\"events\"][\"times\"][0]\n", + " actual_t_post_sp = nest.GetStatus(spikedet_post)[0][\"events\"][\"times\"][0]\n", + "\n", + " dt = actual_t_post_sp - actual_t_pre_sp\n", + " dw = (updated_weight - initial_weight) / lmbda\n", + "\n", + " return dt, dw" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then, we can run the experiment. We set the pre spike time to a constant (100 ms) and loop over values for the post spike time (25 to 175 ms).\n", + "\n", + "Note that the dendritic delay in this example has been set to 10 ms, to make its effect on the STDP window more clear: it is not centered around zero, but shifted to the left by the dendritic delay. Hint: play with the parameters a bit here and see the effects it has on the returned window." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def stdp_window(neuron_model_name, synapse_model_name, synapse_parameters=None):\n", + " sim_time = 1000. # [ms]\n", + " pre_spike_time = 100. #sim_time / 2 # [ms]\n", + " delay = 10. # dendritic delay [ms]\n", + "\n", + " dt_vec = []\n", + " dw_vec = []\n", + " for post_spike_time in np.arange(25, 175).astype(float):\n", + " dt, dw = run_network(pre_spike_time, post_spike_time,\n", + " neuron_model_name,\n", + " synapse_model_name,\n", + " resolution=1., # [ms]\n", + " delay=delay, # [ms]\n", + " synapse_parameters=synapse_parameters,\n", + " sim_time=sim_time)\n", + " dt_vec.append(dt)\n", + " dw_vec.append(dw)\n", + " \n", + " return dt_vec, dw_vec, delay" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_stdp_window(dt_vec, dw_vec, delay):\n", + " fig, ax = plt.subplots(dpi=120)\n", + " ax.scatter(dt_vec, dw_vec)\n", + " ax.set_xlabel(r\"t_post - t_pre [ms]\")\n", + " ax.set_ylabel(r\"$\\Delta w$\")\n", + "\n", + " for _ax in [ax]:\n", + " _ax.grid(which=\"major\", axis=\"both\")\n", + " _ax.grid(which=\"minor\", axis=\"x\", linestyle=\":\", alpha=.4)\n", + " _ax.set_xlim(np.amin(dt_vec), np.amax(dt_vec))\n", + " #_ax.minorticks_on()\n", + " #_ax.set_xlim(0., sim_time)\n", + "\n", + " ylim = ax.get_ylim()\n", + " ax.plot((np.amin(dt_vec), np.amax(dt_vec)), (0, 0), linestyle=\"--\", color=\"black\", linewidth=2, alpha=.5)\n", + " ax.plot((-delay, -delay), ylim, linestyle=\"--\", color=\"black\", linewidth=2, alpha=.5)\n", + " ax.set_ylim(ylim)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "dt_vec, dw_vec, delay = stdp_window(neuron_model_name, synapse_model_name,\n", + " synapse_parameters={\"alpha\": .5})\n", + "\n", + "plot_stdp_window(dt_vec, dw_vec, delay)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Symmetric LTP or LTD-only\n", + "----------------------\n", + "\n", + "Depending on the frequency at which the spike pairing protocol is repeated, a symmetric potentiation-only window can occur for high repetition rates, whereas for low rates, a depression-only window is observed.\n", + "\n", + "Facilitation-only is easy to obtain without even changing the model:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "dt_vec, dw_vec, delay = stdp_window(neuron_model_name, synapse_model_name,\n", + " synapse_parameters={\"alpha\": -1.})\n", + "plot_stdp_window(dt_vec, dw_vec, delay)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Adapt the model to obtain the symmetric depression-only window." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Windowed STDP\n", + "------------\n", + "\n", + "In this variant of the original STDP rule, we allow only spikes more than a few milliseconds apart to cause the weight to change. If the pre-post absolute $|\\Delta t|$ is smaller than some threshold, the weight change should be zero." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_windowed_stdp_model = \"\"\"\n", + "synapse stdp_windowed:\n", + "\n", + " state:\n", + " w real = 1.\n", + " pre_nn_trace real = 0.\n", + " post_nn_trace real = 0.\n", + " end\n", + "\n", + " parameters:\n", + " d ms = 1 ms @nest::delay # !!! cannot have a variable called \"delay\"\n", + " lambda real = .01\n", + " tau_tr_pre ms = 20 ms\n", + " tau_tr_post ms = 20 ms\n", + " alpha real = 1\n", + " mu_plus real = 1\n", + " mu_minus real = 1\n", + " Wmax real = 100.\n", + " Wmin real = 0.\n", + " tau_recency_window_pre ms = 10 ms\n", + " tau_recency_window_post ms = 10 ms\n", + " end\n", + "\n", + " equations:\n", + " kernel pre_trace_kernel = exp(-t / tau_tr_pre)\n", + " inline pre_trace real = convolve(pre_trace_kernel, pre_spikes)\n", + "\n", + " # all-to-all trace of postsynaptic neuron\n", + " kernel post_trace_kernel = exp(-t / tau_tr_post)\n", + " inline post_trace real = convolve(post_trace_kernel, post_spikes)\n", + "\n", + " pre_nn_trace' = -pre_nn_trace / tau_recency_window_pre\n", + " post_nn_trace' = -post_nn_trace / tau_recency_window_post\n", + " end\n", + "\n", + " input:\n", + " pre_spikes nS <- spike\n", + " post_spikes nS <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " onReceive(post_spikes):\n", + " post_nn_trace = 1\n", + "\n", + " if pre_nn_trace < .7:\n", + " # potentiate synapse\n", + " w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace ))\n", + " w = min(Wmax, w_)\n", + " end\n", + " end\n", + "\n", + " onReceive(pre_spikes):\n", + " pre_nn_trace = 1\n", + "\n", + " if post_nn_trace < .7:\n", + " # depress synapse\n", + " w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace ))\n", + " w = max(Wmin, w_)\n", + " end\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, d)\n", + " end\n", + "end\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "neuron_model_name, synapse_model_name = generate_code_for(nestml_windowed_stdp_model)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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qOLkqfv6um5scCkiIp6SbhZ3zg045w52zp00QppVzrlzw+mqnXPjnHNnKLAUKQyV5WVcMmuqrxHjO3v7+XnTenr7BzKeLxGRYlXSwaWIlIbLG6cx+8j6UdPt6unnhqVr+dyvVynAFBFJkoJLESl6kamJrj57BvtUlQ+bLlK7uayllZua1mcncyIiRUbBpYiUhMryMuY1ThsxuIyIzHk5Uu1lX18fra2tg6++vsRGpYuIFKuSHtAjIqXl6Q3b2RocfaohP3Netre3s2jRosHt+fPnU18/etO7iEixU82liJSMROew1JyXIiKJU3ApIiUjU3NeiojIHgouRaRkROa8tFHSGVBXU+17zksREdlDwaWIlAy/c1464JJZh1JZrq9IEZFE6ZtTREpK9JyXsTWYke3ZR9Yzr3FaVvMlIlIsFFyKSEmJnvNyck31kGOTa6q5+uwZ3Dz3JNVaiogkSVMRiUjJqSwv48o505nXOI2nN2ync1cPE8Z664orqBQRSY2CSxEpWZXlZcPOYykiIsnRn+giIiIikjYKLkVEREQkbRRcioiIiEjaqM+liEgSamtrmT9//pBtERFRcCkikpSKigrq6+tznQ0RkbyjZnERERERSRsFlyIiIiKSNgouRURERCRt1OdSRCQJoVCIp556anD7lFNOIRAI5DBHIiL5QcGliEgSQqEQTU1Ng9tHHXWUgksREdQsLiIiIiJppOBSRERERNJGwaWIiIiIpI2CSxERERFJGwWXIiIiIpI2Ci5FREREJG0UXIqIiIhIXL39A6ze1JHQOZrnUkRERESG6O0f4OdN67lz5QbeeHVdQucquBQRERGRQb39A1x259Msf6kNS+J8NYuLiIiIyKCfN61n+UttALgkzi+q4NLMDjCz/2dmy81sh5k5M2scIf07zGyFme00sy1mttDMauKkqzaz75nZG2a2y8yeNLOzM/ksIpLfKioqqKurG3xVVKghSEQKX2//AHeu3JBUjWVEsX0bvg34MrAOeB6YNVxCMzseeARYA3wBOBj4IjAdOCcm+e3AecCPw9f+JPBnMzvTObcijfkXkQJRW1vLggULcp0NEZG0enrDdrYGe1K6RrEFl6uASc65djM7D7hnhLTfBbYDjc65LgAz2wD8wsze45x7OLyvAfgE8CXn3A/C++4EXgC+D7wjUw8jIiIikk2du1ILLKHI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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "dt_vec, dw_vec, delay = stdp_window(neuron_model_name, synapse_model_name)\n", + "plot_stdp_window(dt_vec, dw_vec, delay)" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Symmetric inhibitory STDP\n", + "--------------------\n", + "\n", + "\n", + "
\n", + "\n", + "
\n", + "\n", + "The symmetric STDP window in the figure can be observed experimentally and was used to achieve a self-organised balance between excitation and inhibition in recurrent networks [4]_." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "nestml_stdp_vogels_model = \"\"\"\n", + "synapse stdp_vogels:\n", + "\n", + " state:\n", + " w real = 1.\n", + " end\n", + "\n", + " parameters:\n", + " d ms = 1 ms @nest::delay # !!! cannot have a variable called \"delay\"\n", + " lambda real = .01\n", + " offset real = 1.\n", + " tau_tr_pre ms = 20 ms\n", + " tau_tr_post ms = 20 ms\n", + " alpha real = 1\n", + " mu_plus real = 1\n", + " mu_minus real = 1\n", + " Wmax real = 100.\n", + " Wmin real = 0.\n", + " end\n", + "\n", + " equations:\n", + " kernel pre_trace_kernel = exp(-t / tau_tr_pre)\n", + " inline pre_trace real = convolve(pre_trace_kernel, pre_spikes)\n", + "\n", + " # all-to-all trace of postsynaptic neuron\n", + " kernel post_trace_kernel = exp(-t / tau_tr_post)\n", + " inline post_trace real = convolve(post_trace_kernel, post_spikes)\n", + " end\n", + "\n", + " input:\n", + " pre_spikes nS <- spike\n", + " post_spikes nS <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " onReceive(post_spikes):\n", + " w += lambda * (pre_trace + post_trace)\n", + " end\n", + "\n", + " onReceive(pre_spikes):\n", + " w += lambda * (pre_trace + post_trace - offset)\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, d)\n", + " end\n", + "end\n", + "\"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save to a temporary file and make the model available to instantiate in NEST:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "neuron_model_name, synapse_model_name = generate_code_for(nestml_stdp_vogels_model)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "dt_vec, dw_vec, delay = stdp_window(neuron_model_name,\n", + " synapse_model_name,\n", + " synapse_parameters={\"offset\": .6})\n", + "plot_stdp_window(dt_vec, dw_vec, delay)" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Further directions\n", + "---------------------\n", + " \n", + "* **Bursting dependent rules**\n", + "\n", + " Neuronal bursting is when action potentials are fired at high frequency in groups, separated by periods of quiescence. Bursting can be considered a different communication signal from the normal firing of action potentials. Search for (or come up with) a burst-dependent learning rule, and implement it in NESTML.\n", + "\n", + "

 

\n", + " \n", + "* **Triplet relationships**\n", + "\n", + " So far, we have looked at the relative timing of two spikes, $\\Delta t$ on the horizontal axis.\n", + "\n", + " Come up with a triplet spike protocol, that involves not just the time difference between two but between three spikes. Make a 3D plot of $\\Delta w$ as a function of the timing parameters $\\Delta t_1$ and $\\Delta t_2$. What do you expect to see?\n", + "\n", + "

 

\n", + "\n", + "* **Multiphasic windows**\n", + " \n", + " Patch clamping is a common recording technique that uses a micropipette filled with a liquid that mimics the intracellular environment. When cesium ions (Cs+) are introduced into this solution, an extra potentiation window is seen for long pre-after-post delays. This thought to be caused by cesium blocking of potassium channels, which depolarises the postsynaptic neuron, and enhance and lengthen backpropagating action potentials in the apical dendrite [I]_.\n", + "\n", + " \n", + "
\n", + " \n", + "
\n", + "\n", + " In the figure, the data is fit with a difference-of-gaussians curve (continuous black line). It could be easier to approach this using the existing exponentially decaying trace values, but add an additional trace with higher-order dynamics (where the exponentially decaying function has order 1).\n", + " \n", + " [I] Malleability of Spike-Timing-Dependent Plasticity at the CA3–CA1 Synapse\n", + " Gayle M. Wittenberg, Samuel S.-H. Wang\n", + " Journal of Neuroscience 14 June 2006, 26 (24) 6610-6617" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "References\n", + "----------\n", + "\n", + "[1] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological models of synaptic plasticity based on spike timing, Biol. Cybern. 98, 459–478 https://doi.org/10.1007/s00422-008-0233-1\n", + "\n", + "[2] Front. Comput. Neurosci., 23 November 2010 Enabling functional neural circuit simulations with distributed computing of neuromodulated plasticity, Wiebke Potjans, Abigail Morrison and Markus Diesmann https://doi.org/10.3389/fncom.2010.00141 \n", + "\n", + "[3] Rubin, Lee and Sompolinsky. Equilibrium Properties of Temporally Asymmetric Hebbian Plasticity. Physical Review Letters, 8 Jan 2001, Vol 86, No 2 http://doi.org/10.1103/PhysRevLett.86.364\n", + "\n", + "[4] Vogels, Sprekeler, Zenke, Clopath and Gerstner (2011). Inhibitory Plasticity Balances Excitation and Inhibition in Sensory Pathways and Memory Networks. Science Vol 334 https://doi.org/10.1126/science.1211095 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Acknowledgements\n", + "----------------\n", + "\n", + "The authors thank Younes Bouhadjar for his suggestions on use cases and valuable feedback.\n", + "\n", + "This software was developed in part or in whole in the Human Brain Project, funded from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under Specific Grant Agreements No. 720270 and No. 785907 (Human Brain Project SGA1 and SGA2).\n", + "\n", + "License\n", + "-------\n", + "\n", + "This notebook (and associated files) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.\n", + "\n", + "This notebook (and associated files) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details." + ] + } + ], + "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.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/doc/tutorials/triplet_stdp_synapse/triplet_stdp_synapse.ipynb b/doc/tutorials/triplet_stdp_synapse/triplet_stdp_synapse.ipynb new file mode 100644 index 000000000..598707661 --- /dev/null +++ b/doc/tutorials/triplet_stdp_synapse/triplet_stdp_synapse.ipynb @@ -0,0 +1,2406 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "anonymous-address", + "metadata": {}, + "source": [ + "# Triplet STDP synapse tutorial" + ] + }, + { + "cell_type": "markdown", + "id": "cordless-convenience", + "metadata": {}, + "source": [ + "In this tutorial, we will learn to formulate triplet rule (which considers sets of three spikes, i.e., two presynaptic and one postsynaptic spikes or two postsynaptic and one presynaptic spikes) for Spike Timing-Dependent Plasticity (STDP) learning model using NESTML and simulate it with NEST simulator." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "orange-zambia", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import nest\n", + "import numpy as np\n", + "import os\n", + "import re\n", + "\n", + "from pynestml.frontend.pynestml_frontend import generate_nest_target\n", + "np.set_printoptions(suppress=True)\n", + "\n", + "NEST_INSTALL_PATH = nest.ll_api.sli_func(\"statusdict/prefix ::\")" + ] + }, + { + "cell_type": "markdown", + "id": "understanding-commissioner", + "metadata": {}, + "source": [ + "Early experiments in Bi and Poo (1998) [1] have shown that a sequence of $n$ pairs of \"pre then post\" spikes result in synaptic potentiation and $n$ pairs of \"post then pre\" result in synaptic depression. Later experiments have shown that these pairs of spikes do not necessarily describe the synaptic plasiticity behavior. Other variables like calcium concentration or postsynaptic membrane potential play an important role in potentiation or depression.\n", + "\n", + "Experiments conducted by Wang et al., [2] and Sjöström et al., [3] using triplet and quadruplets of spikes show that the classical spike-dependent synaptic plasticity alone cannot explain the results of the experiments. The triplet STDP model formulated by Pfister and Gerstner in [4] assume that a combination of pairs and triplets of spikes triggers the synaptic plasticity and thus reproduce the experimental results." + ] + }, + { + "cell_type": "markdown", + "id": "integrated-swimming", + "metadata": {}, + "source": [ + "## Triplet STDP model" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABQAAAAD/CAYAAACuGHucAAAgAElEQVR4AeydB7hdRdm2SUhCC72HIkiTLiKd0KUjgiBIgoDSm7QAgSglFJUiSFGREkCaIL0aei9SpEMiSJEmTfon3//Nf92jz/Ld6+zTklP22vtZ13XOzJq2Zu6Z/a6Zd02ZInXx+r//+78i5JdfflnYsfy///f/au7L/jWevjEBEzABEzABEzABEzABEzABEzABEzABEzABE+gzAlN09qT//d//LYJgj4rAwqOOEhC/smIwhrfdBEzABEzABEzABEzABEzABEzABEzABEzABEyg9wl0qgCMSryoDCRrun/77bcTf59++mnv59hPMAETMAETMAETMAETMAETMAETMAETMAETMAET6DKBThWASknKPt3L/Oyzz9Kiiy6app122nTooYemjz/+OHtFxaHC2jQBEzABEzABEzABEzABEzABEzABEzABEzABE+hbAl1WACpbKPb+9a9/5dsvvvgiXX755Wno0KFp8ODBaYoppkjPPPNMwp2rveXCSsumCZiACZiACZiACZiACZiACZiACZiACZiACZhA7xLotgIwKvWuv/76NOecc2bF38CBA7O5wQYbFLMAezfrTt0ETMAETMAETMAETMAETMAETMAETMAETMAETKAzAt1WACpBZgHuvffeWenH7D8UgJoFOGHChGKWoMLbNAETMAETMAETMAETMAETMAETMAETMAETMAET6HsCnSoAmfEXZ/19+eWX+XRfzG222SZNOeWUWQkoc8iQIelPf/pTcUBI3xfJTzQBEzABEzABEzABEzABEzABEzABEzABEzABExCBThWABPz8888VvjDZ+489//SHAlBKwGWXXTYrDZkliKKw3tXeoSL1wtrNBEzABEzABEzABEzABEzABEzABEzABEzABExg0gh0SQGopDkARAq9yy67LC/73W+//dKMM85YKAJRCC6zzDLpo48+UrRsovArK/3izMKawL4xARMwARMwARMwARMwARMwARMwARMwARMwARPoEQJdUgCiuEP5p+v5559Piy++eDr00EPTZ599lmaZZZasDET5xxJg9gIcO3ZsjoOSr6z4UzpWAIqETRMwARMwARMwARMwARMwARMwARMwARMwARPoHQKdKgA14y/O/mOPPxR9F110Uc7V8ssvnwYMGJBnAeo0YJSCZ5xxRvaPykOUfvG+d4rlVE3ABEzABEzABEzABEzABEzABEzABEzABEzABCDQqQKQQHGmHvYxY8akueaaK91+++2Z4sSJE9M000xTswyY2YAnnXSSKZuACZiACZiACZiACZiACZiACZiACZiACZiACfQjgS4pAP/nf/4ncaAH1+jRo/NhH7vvvnu+Zzbfu+++WywBRvE3aNCgPEPwW9/6VnrxxReLcNlSUijKzaYJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEDPE+iSAlCP5WCP+eefP8/0GzVqVLGUl2XCBxxwQHZH+YcSUH/nn39+EU7peAmwSNg0ARMwARMwARMwARMwARMwARMwARMwARMwgd4l0KkCUHsAsvT3nXfeSbPOOmvabLPN0gcffFDkDL/x48cXSj8p/1AGnnzyyTmcDgKx8q/AZosJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJ9DqBugrAuOcfOZDSbuTIkXmp79Zbb12zLyDKveeee66YHcgBIVICojB84YUX2hTkiy++aONmBxMwARMwARMwARMwARMwARMwARMwARMwARMwgZ4lUFcBGB+hmXuPP/54WmyxxdLUU0+dWNbLxexAlIVSEN54441poYUWyso/lIBSBJ566qmJfQR1ScGoeHK3aQImYAImYAImYAImYAImYAImYAImYAImYAIm0LMEOlUA6nH77rtvVuxddNFF2ak8g0/KPA7+GDBgQHEQyJRTTpm+8pWvpHJ4KQGVvk0TMAETMAETMAETMAETMAETMAETMAETMAETMIGeJ9AlBSCzAPfZZ58088wzp9dffz1xGAjXZ599lu0ff/xxng346aefpjXXXDMrAFECahnw0KFD03777ZfjoPiLswF7vkhO0QRMwARMwARMwARMwARMwARMwARMwARMwARMQAQ6VQCyzJcDPlD+MZtv4YUXzkuBl1xyybT44ovnv+WXXz4ttdRSCbcZZ5wx7xMo5R9xsK+11lp6Zjbj0uEaD9+YgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAn0GIFOFYCffPJJ2muvvbISj1l92tcPxd7AgQPzbD8p+6KJH/eYnAbM/oHPP/98m8NDeqwkTsgETMAETMAETMAETMAETMAETMAETMAETMAETKANgQ4VgMzSe+SRR/LMP5R5e+65Zxo7dmw65phj8t+RRx6Zjj766Gw/7rjj0s9+9rN07LHHpv333z9NNdVURTwpA7fYYoucAS8BblMPdjABEzABEzABEzABEzABEzABEzABEzABEzCBXiFQVwGI4o+lvxzcse222+aZfHvvvXfOgE4FjrlBoUccrn/961853rzzzpvjaVYgCsGtttqqZv8/xYlp2W4CJmACJmACJmACJmACJmACJmACJmACJmACJtBzBKZACSeFXznZd999N80xxxxZkafTf3XarxSBupdJGigBL7/88rxvoBSAgwcPzvsDXn311SmG1TPjrEApBvUMhbFpAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAibQPQI1MwCZ8cclZdxdd92VpplmmjT77LOnW265JftF5R2zBLmksMOuNAjHcmFm/vGHIpB9A3feeeci/RgvJ5RSnnkYnyF3myZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAt0nkBWAn3/+eREzzrrjdN8555wznwJcBPiPpZ6Srux28sknZ8Ufh4BMPfXUxYEh7CvIFZ+FMjHGRzkY78vP970JmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEDnBPISYIKhbDv99NPToYcemkaPHp0OP/zwNNtssyX28jv++OPTqFGj0sEHH5x+/etf16RaVh6OGzcuHXTQQWnMmDFpzTXXLBSAKAF1GMjIkSPTgQcemI466qgc9sUXX6xJk7xY+VeDxDcmYAImYAImYAImYAImYAImYAImYAImYAImMEkEiiXAzLgbOnRoVtixX5/27hswYEAxcw93ZgUStjxDj33/uIYPH57jatmv0pE5ZMiQIj3cUAz+6U9/qpt5KwHrYrGjCZiACZiACZiACZiACZiACZiACZiACZiACXSZQFYAoszj2mSTTdLSSy+dVlpppeJv7bXXTiussEJaeeWV09e//vW066671iSufQBxJJ299torh1t11VXTiiuumL75zW+mVVZZJa211lo5jeWWWy77r7/++ukb3/hGWmaZZdL9999fs49gXBpc8zDfmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJdItAMQOQWJpxh1KPwzyk3JNJGCkLsZcVdfJT+E8//bRIk4NFdLgIswUVRoeG1EsPN18mYAImYAImYAImYAImYAImYAImYAImYAImYAKTTiArAFHkSflXVurJnUdomS9Ku+iOXzkNKQMxZSeO7MSRXenGZ2D3ZQImYAImYAImYAImYAImYAImYAImYAImYAImMHkEamYATl5Sjm0CJmACJmACJtBMBPShjjKVP/xFP5W5/BFR7jZNwARMwARMwARMwARMwAT6l4AVgP3L3083ARMwARMwgYYmIEWftvF466230r777pv3+V1ttdXy/r7s98t+wRwEtuyyy6ZbbrmlocvkzJmACZiACZiACZiACZhAqxGwArDVatzlNQETMAETMIFuENCsPswxY8akWWaZJQ0YMCBNMcUUafDgwdnU/ZAhQ/L9FVdc0Y0nOKgJmIAJmIAJmIAJmIAJmEBvE7ACsLcJO30TMAETMAETqCABKf6U9fHjx2fl3sCBA7MZFYBTTjllGjRoUOE+btw4RbNpAiZgAiZgAiZgAiZgAibQAASsAGyASnAWTMAETMAETKDRCJSX/l511VVp/fXXT+ecc04699xz089+9rOs8GP2384775zOPvvsdMEFFySUf6+99lqjFcf5MQETMAETMAETMAETMIGWJmAFYEtXvwtvAiZgAiZgAu0T+PLLL7PnO++8k0aPHp3eeOONIvDLL79czPq77rrrksL+61//anNgSBHJFhMwARMwARMwARMwARMwgX4hYAVgv2D3Q03ABEzABEygGgQ+//zzhLLvuOOOyxnWacBPPfVUmmGGGdKcc86Z7r777qIwOiykcLDFBEzABEzABEzABEzABEyg3wlYAdjvVeAMmIAJmIAJmEBjEtAyYCn9dE9uX3jhhbwEeP/998+ZR1GoS+F1b9METMAETMAETMAETMAETKB/CVgB2L/8/XQTMAETMAETqCQBKQCPOuqoxIEhZaWflIUsCeZiibDcOipw+fCRjsLazwRMwARMwARMwARMwARMoGsErADsGieHMgETMAETMAETCASefvrpNO2006Z99923cEUJyExAKfqiMg83uWu/QEUkXlw6HOMpjE0TMAETMAETMAETMAETMIFJJ2AF4KSzc0wTMAETMAETaFkCmgE4ZsyYzKCsxJOyD8/PPvusXeVfVAaiBCzPJGxZwC64CZiACZiACZiACZiACfQgASsAexCmkzIBEzABEzCBViHw4osv5j0Ad9ppp2L2Hsq8N998M88CFIcvvvgivf/+++mBBx4owr377rvphhtuKE4ORkHoywRMwARMwARMwARMwARMoPcIWAHYe2ydsgmYgAmYgAk0LYG//OUvacYZZ0wDBgxI++23X57ld/TRR2e7ZvFpKS8HhUwxxRTpzDPPTO+88046+eST08EHH5yVhQAiHH9x1mDTgnPBTMAETMAETMAETMAETKAfCFgB2A/Q/UgTMAETMAETqDoBZgAOGTIkK/ZQ7m2zzTbZvscee7Qp2ksvvZSWWWaZtMgii6Rx48al3XbbrQhTT+knxWERyBYTMAETMAETMAETMAETMIHJImAF4GThc2QTMAETMAETaE0C7AE4bNiwrPSTInDuuedOP/nJT9rM5GNvv/feey+tvfbaacSIEWnixIkZGicERwVgtLcmVZfaBEzABEzABEzABEzABHqHgBWAvcPVqZqACZiACZhA0xO49tpr0yqrrJJWXXXVtPHGG6c33ngjffrpp0W5tRQYh1dffTWdd955edbgscceW4TBEsNFe00g35iACZiACZiACZiACZiACUwyASsAJxmdI5qACZiACZiACTBrL/5FInFGH0uDt91227T++uvnmYAcBMLMQF2ff/65rDWzAgtHW0zABEzABEzABEzABEzABCaZgBWAk4zOEU3ABEzABEzABLpC4K677ko///nPs8Lvvvvuy8uGN91007wsuHwCMMuCfZmACZiACZiACZiACZiACfQsASsAe5anUzMBEzABEzABEwgE2Ctw8cUXT1dddVVWAH788cdpzJgxaaqppko77LBDDslMwDgbMES31QRMwARMwARMwARMwARMoAcIWAHYAxCdhAmYgAmYgAmYQC0BneT7ySefpEceeSRpZh97/LFP4JNPPpkmTJhQE0lxZNZ4+sYETMAETMAETMAETMAETGCSCVgBOMnoHNEETMAETMAETKAzAtoHEKWe7DGODv1gD8B6/jGs7SZgAiZgAiZgAiZgAiZgApNGwArASePmWCZgAiZgAiZgAl0gIKUeir4vv/wyx4gHfqAY1OxAJSeloO5tmoAJmIAJmIAJmIAJmIAJTB4BKwAnj59jm4AJmIAJmIAJ1CEQlXhffPFFDhEP/JAysBy1rAws+/veBEzABEzABEzABEzABEyg+wSsAOw+M8cwARMwARMwARPoAgHN/sOMCr+o5IuKQiWpeLq3aQImYAImYAImYAImYAImMHkErACcPH6ObQImYAImYAJNQ0DKuHoKuLIST2FVePy1tBd72T8qAPHnj0vhopvSVByFlbtNEzABEzABEzABEzABEzCB7hGwArB7vBzaBEzABEzABJqaQJyd115BpbST/wMPPJD+8Ic/pCuvvDI99dRT2fm+++5L11xzTbr00kvTSy+9lN3KijwUfDrxV6bSrJeP//mf/8ne9fwUz6YJmIAJmIAJmIAJmIAJmEBbAlYAtmViFxMwARMwARNoCQIo3cqKNwoe3TULDxPF2z333JMOP/zwdMYZZxSMdttttzRw4MA0xRRTJOxcq6++er7H7eSTTy4O+nj11VfTmDFj0sEHH5w++eSTIo1okYIRhWHMS1mBGOPYbgImYAImYAImYAImYAIm0D4BKwDbZ2MfEzABEzABE2haAvWUaSj5ovvHH39cU/6HH344LbjggmnqqadOq622WuH3/PPPp9tuuy3deeed6Z133knM1HvsscfSvffem/9ee+21Iuztt9+ehg4dmqaddtq0ySabZHcUfigX9TzN8JPykUCykz/5F4naYgImYAImYAImYAImYAIm0CEBKwA7xGNPEzABEzABE2heAlKkYZZnAp577rlp4YUXTtttt116++23M4SPPvooPfPMM2nixIlZ0RfJKL5O/I1+UioSBkUeS4JffvnlnA7hJkyYkL797W/nZ/HM0aNH570BmSH41ltvZYVivfSim+0mYAImYAImYAImYAImYALtE7ACsH029jEBEzABEzCBliHw4Ycfpvfffz+Xl9l7Cy20UNp0000T+/txlRV7KPWk2BMkzdLTEl7MchiFVRjFQblIHg455JD0xhtv5GBHH310nm1400035ftyHpSWTRMwARMwARMwARMwARMwgY4JWAHYMR/7moAJmIAJmEDTEkChxsm9v/3tb9Maa6yRvvOd7+SyMutu/PjxRbk1uw8H7GWlnmYSFhHqWD777LPCFaWfFICkVY4vRd9dd92V9t9//zRs2LB08cUX5/hSGBaJ2WICJmACJmACJmACJmACJtApASsAO0XkACZgAiZgAibQvARYjrviiium3/zmN/kU308//TQXVgo6bqKCLrpHKijyyopB/MsKu3ivU30Jp7hR2Sg39hfULMAYNj7fdhMwARMwARMwARMwARMwgfYJWAHYPhv7mIAJmIAJmEDDEpCiLCrnpDAj0/Ln1F1m9z3++ON51h0KvEsuuST9/ve/z2UjPjP+dMU05NZfpsogk3xcdtllad11100jR47MewNGhaLyKSVluSzle4W3aQImYAImYAImYAImYALNTsAKwGavYZfPBEzABEygKQlI8SWlFiZ/KL+0hJaCn3feeWmKKaZIxx57bHrhhRfSWWedlRZYYIF0zTXXFDP7pDBTmo0ATHnS0mEpASnbVlttlQYMGJD22GOPIquxzIVjsIhTcLLVBEzABEzABEzABEzABFqGgBWALVPVLqgJmIAJmEAzEpBiTAozlRF3lGJzzjlnGjx4cJpyyinTTDPNlEaMGJFnACoe4aOd+3JaSrMvTSnsyEu0a8YjJwX/+te/zlliduONN95Yk70Yr8ajzrLksr/vTcAETMAETMAETMAETKDZCFgB2Gw16vKYgAmYgAm0DAEpxmKBUZBJofezn/0sK/6YAcjf0KFD07nnnlvsy1cvfkyrv+2akYgyj8NKdLFPocpImE022SSX8/LLLy9mNSpsNBu9vDGvtpuACZiACZiACZiACZhATxKwArAnaTotEzABEzABE+hHAijD4uy9+eabLw0cODD/DRkyJCsBv/3tb+cccgCHFGwxyzF+dO9ru5R1Mnl+Ob+6/8tf/pLmn3/+tOqqqxZhKF+MS3zK1ijl62uefp4JmIAJmIAJmIAJmEBrE7ACsLXr36U3ARMwAROoOAGUXJoNp6J8/PHHafvtt0/TTz99VvphLrfccunWW29Nb7/9ds0egcSRIg17IyrIoiKPsjLLMeaT+wkTJqSVV145n2QcTxemTDF+tIuXTRMwARMwARMwARMwARNodgJWADZ7Dbt8JmACJmACTUkgKsBiAV977bW03377ZcXfoEGD0pZbbpkuuuiiGCTb46EZUSkW7W0i9aGDlJIyeXRZ0Rmzgx9MPvroo+z8zDPPpHiASHu8Yhq2m4AJmIAJmIAJmIAJmECzErACsFlr1uUyARMwARNoegIo66Swk/22227Lyj/2/Bs7dmzBQMozhSs8GtiiPJNF2aXIU7l1H4uB35prrpkuvPDCxH6BunCvF17+Nk3ABEzABEzABEzABEygWQlYAdisNetymUAdAhr4yqwTxE4mYAIVISAFGNnVbL633norrbXWWmmHHXZIN910U6E0U5HKSjS5N6N53XXXpXnmmSedc845RfGQfZFb4WGLCZiA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hhtuSHvuuWd2w33jjTdOo0aNym4oDFk2xx97gqAgVIehEhCcyV4jYAVgr6F1wj1AQP2/mBQDn9133z3vgYqsY8kTF8ufWBXCzMDNN988z2w95JBD0h577JFmmmmmtNBCC2V5yUfk9957r6ZPGdO33QR6moAVgD1NtDXSi/00+oJS3rz44otptdVWy/09KfVQspx33nlZOTho0KA8W3qnnXZK++yzTz41GLn4jW98I68aYWWcxtRRwSiqeo7ubTbeHoDlOtEYISr+1H5U19Rrf9StFYDl2ur83grA0tKN2HDPOeectMMOOyRORFp00UXT3nvvnb944P7KK68UA1w6iygHL7jggvxFmFmBLCN54IEHOq8Bh2h6AlYANn0VV7aAkncy9YKnQNgZBK+00kp5WfAiiyySTjnllKwcREHI9H/Fo4OIG3+zzDJLmnvuufMsmcqCccZ7jIAVgD2G0gn1AgENYEhagxjs9Ot22WWX/CF4yy23zAfELbHEEul3v/td/mMQRFzJTA4K4cT0gw8+OA+av/vd7+bZL/JX1uPz5GbTBCaXgBWAk0uwteNHuaSlnMyEpv/HB92jjz46r3bjAwgfOK688so2wC6//PI8Ft5kk03SRhttlE444YQamUqEsjxsk0gLOzTaDECqgnYR34uqntheon90V9i+MK0A7D5lKwA72LCeBrXMMsukBRZYIB1xxBE1gis28mhnIIwicPrpp09zzTVX3igz/jioIk2JLrt3v/ocowoE6ikAY5upQhmcx+YkQDtUh6xem7ztttvyYJaZfbfeemuGEL/+4SA5JrnGBxNOkZtvvvnyoFmdyTLBes8rh/F99QlYAVj9Omz2EkiGIZM0W0XyCeUfM1uYCf3mm28W8hImiic+xOGPzfS32GKLxEA4XlF2luPGcLabQHcJlBWAar/dTcfhW49AbCvRDgkOAPne976XZwPykUN73qvfWE+OsWQYBSCzp4888sgCaDntwsOWTAAFIH1t7StrLF0nUFYAuq11zs4KwP8oACXMaDSys88LyzrY749LDUqzXqIbnUbFw/3aa69N7IvAjJl6V0yjnr/dmodAPQVg85TOJak6ATpwkkeSYZJ1J510UpaBN998cy6m/LkhjDp/MsWCgS6bBDNwfvDBB/OgmmdE+apnKI7N5iRgBWBz1mszlEpyj7LU2++I039nmGGG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" + } + }, + "cell_type": "markdown", + "id": "inside-south", + "metadata": {}, + "source": [ + "The synaptic transmission is formulated by a set of four differential equations as defined below.\n", + "\n", + "\\begin{equation}\n", + "\\frac{dr_1}{dt} = -\\frac{r_1(t)}{\\tau_+} \\quad\n", + "\\text{if } t = t^{pre}, \\text{ then } r_1 \\rightarrow r_1+1\n", + "\\end{equation}\n", + "\n", + "\\begin{equation}\n", + "\\frac{dr_2}{dt} = -\\frac{r_2(t)}{\\tau_x} \\quad\n", + "\\text{if } t = t^{pre}, \\text{ then } r_2 \\rightarrow r_2+1\n", + "\\end{equation}\n", + "\n", + "\\begin{equation}\n", + "\\frac{do_1}{dt} = -\\frac{o_1(t)}{\\tau_-} \\quad\n", + "\\text{if } t = t^{post}, \\text{ then } o_1 \\rightarrow o_1+1\n", + "\\end{equation}\n", + "\n", + "\\begin{equation}\n", + "\\frac{do_2}{dt} = -\\frac{o_2(t)}{\\tau_y} \\quad\n", + "\\text{if } t = t^{post}, \\text{ then } o_2 \\rightarrow o_2+1\n", + "\\end{equation}\n", + "\n", + "Here, $r_1$ and $r_2$ are the trace variables that detect the presynaptic events when a spike occurs at the presynaptic neuron at time $t^{pre}$. These variables increase when a presynaptic spike occurs and decrease back to 0 otherwise with time constants $\\tau_+$ and $\\tau_x$ respectively. Similarly, the variables $o_1$ and $o_2$ denote the trace variables that detect the postsynaptic events at a spike time $t^{post}$. In the absence of a postsynaptic spike, the vairables decrease their value with a time constant $\\tau_-$ and $\\tau_y$ respectively. Presynaptic variables, for example, can be the amount of glutamate bound and the postsynaptic receptors can determine the influx of calcium concentration through voltage-gated $Ca^{2+}$ channels.\n", + "\n", + "The weight change in the model is formulated as a function of the four trace variables defined above. The weight of the synapse decreases after the presynaptic spikes arrives at $t^{pre}$ by an amount proportional to the postsynaptic variable $o_1$ but also depends on the second presynaptic variable $r_2$.\n", + "\n", + "\\begin{equation}\n", + "w(t) \\rightarrow w(t) - o_1(t)[A_2^- + A_3^- r_2(t - \\epsilon)] \\quad \\text{if } t = t^{pre}\n", + "\\end{equation}\n", + "\n", + "Similarly, a postsynaptic spike at time $t^{post}$ increases the weight of the synapse and is dependent on the presynaptic variable $r_1$ and the postsynaptic variable $o_2$.\n", + "\n", + "\\begin{equation}\n", + "w(t) \\rightarrow w(t) + r_1(t)[A_2^+ + A_3^+ o_2(t - \\epsilon)] \\quad \\text{if } t = t^{post}\n", + "\\end{equation}\n", + "\n", + "Here, $A_2^+$ and $A_2^-$ denote the amplitude of the weight change whenever there is a pre-post pair or a post-pre pair. Similarly, $A_3^+$ and $A_3^-$ denote the amplitude of the triplet term for potentiation and depression, respectively.\n", + "\n", + "![image.png](attachment:image.png)" + ] + }, + { + "cell_type": "markdown", + "id": "collective-stuff", + "metadata": {}, + "source": [ + "## Generating code with NESTML\n", + "\n", + "### Triplet STDP model in NESTML" + ] + }, + { + "cell_type": "markdown", + "id": "basic-given", + "metadata": {}, + "source": [ + "In this tutorial, we will use a very simple integrate-and-fire model, where arriving spikes cause an instantaneous increment of the membrane potential. Let's download the model from the NESTML repository so it becomes available locally:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "environmental-daily", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('models/neurons/iaf_psc_delta.nestml', )" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import urllib.request \n", + "if not os.path.isdir(\"models\"):\n", + " os.makedirs(\"models\")\n", + "if not os.path.isdir(\"models/neurons\"):\n", + " os.makedirs(\"models/neurons\")\n", + "if not os.path.isdir(\"models/synapses\"):\n", + " os.makedirs(\"models/synapses\")\n", + "urllib.request.urlretrieve(\"https://raw.githubusercontent.com/nest/nestml/master/models/neurons/iaf_psc_delta.nestml\",\n", + " \"models/neurons/iaf_psc_delta.nestml\")" + ] + }, + { + "attachments": { + "image-2.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnsAAAFyCAYAAACN0xzCAAAgAElEQVR4AeydB5jVxPrGF1S813stf0SwXMWKl14VUBQFrNeCvSv2XrErTbChUhSpIl2qUhRQsWNDRFQQEGnSYZftu6clef/PO8l3dvZwFlCWhd3zZZ9skkkymflNMvOeb1oadFECSkAJKAEloASUgBKosATSKmzMNGJKQAkoASWgBJSAElACULGnL4ESUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVqSkAJKAEloASUgBJQsafvgBJQAkpACSgBJaAEKjABFXsVOHE1akpACSgBJaAElIASULGn74ASUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVqSkAJKAEloASUgBJQsafvgBJQAkpACSgBJaAEKjABFXsVOHE1akpACSgBJaAElIASULGn74ASUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVqSkAJKAEloASUgBJQsafvgBJQAkpACSgBJaAEKjABFXsVOHE1akpACSgBJaAElIASULGn74ASUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVqSkAJKAEloASUgBJQsafvgBJQAkpACSgBJaAEKjABFXsVOHE1akpACSgBJaAElIASULGn74ASUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVqSkAJKAEloASUgBJQsafvgBJQAkpACSgBJaAEKjABFXsVOHE1akpACSgBJaAElIASULGn74ASUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVqSkAJKAEloASUgBJQsafvgBJQAkpACSgBJaAEKjABFXsVOHE1akpACSgBJaAElIASULGn74ASUAJKQAkoASWgBCowARV7FThxNWpKQAkoASWgBJSAElCxp++AElACSkAJKAEloAQqMAEVexU4cTVq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SkAJKAEloASUQGoSULGXmumusVYCSkAJKAEloARShICKvRRJaI2mElACSkAJKAElkJoEVOylZrprrJWAElACSkAJKIEUIaBiL0USWqOpBJSAElACSkAJpCYBFXupme4aayWgBJSAElACSiBFCKjYS5GE1mgqASWgBJSAElACqUlAxV5qpkiKi04AACAASURBVLvGWgkoASWgBJSAEkgRAir2UiShNZpKQAkoASWgBJRAahJQsZea6a6xVgJKQAkoASWgBFKEgIq9FElojaYSUAJKQAkoASWQmgRU7KVmumuslYASUAJKQAkogRQhoGIvRRJao6kElIASUAJKQAmkJgEVe6mZ7hprJaAElIASUAJKIEUIqNhLkYTWaCoBJaAElIASUAKpSUDFXmqmu8ZaCSgBJaAElIASSBECKvZSJKE1mkpACSgBJaAElEBqElCxl5rprrFWAkpACSgBJaAEUoSAir0USWiNphJQAkpACSgBJZCaBFTspWa6a6yVgBJQAkpACSiBFCGgYi9FElqjqQSUgBJQAkpACaQmARV7qZnuGmsloASUgBJQAkogRQio2EuRhNZoKgEloASUgBJQAqlJQMVeaqa7xloJKAEloASUgBJIEQIq9lIkoTWaSkAJKAEloASUQGoSULGXmumusVYCSkAJKAEloARShICKvRRJaI2mElACSkAJKAElkJoEVOylZrprrJWAElACSkAJKIEUIaBiL0USWqOpBJSAElACSkAJpCYBFXupme4aayWgBJSAElACSiBFCKjYS5GE1mgqASWgBJSAElACqUlAxV5qprvGWgkoASWgBJSAEkgRAir2UiShNZpKQAkoASWgBJRAahJQsZea6a6xVgJKQAkoASWgBFKEgIq9FElojaYSUAJKQAkoASWQmgRU7KVmumuslYASUAJKQAkogRQhoGIvRRJao6kElIASUAJKQAmkJgEVe6mZ7hprJaAElIASUAJKIEUIqNhLkYTWaCoBJaAElIASUAKpSUDFXmqmu8ZaCSgBJaAElIASSBECKvZSJKE1mkpACSgBJaAElEBqElCxl5rprrFWAkpACSgBJaAEUoSAir0USWiNphJQAkpACSgBJZCaBFTspWa6a6yVgBJQAkpACSiBFCGgYi9FElqjqQSUgBJQAkpACaQmARV7qZnuGmsloASUgBJQAkogRQio2EuR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" + } + }, + "cell_type": "markdown", + "id": "ruled-myrtle", + "metadata": {}, + "source": [ + "We will be formulating two types of interactions between the spikes, namely All-to-All interaction and Nearest-spike interaction.\n", + "\n", + "$\\textit{All-to-All Interation}$ - Each postsynaptic spike interacts with all previous postsynaptic spikes and vice versa. All the internal variables $r_1, r_2, o_1,$ and $o_2$ accumulate over several postsynaptic spike timimgs.\n", + "\n", + "
\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "thorough-halifax", + "metadata": {}, + "outputs": [], + "source": [ + "nestml_triplet_stdp_model = '''\n", + "synapse stdp_triplet:\n", + "\n", + " state:\n", + " w nS = 1 nS\n", + "\n", + " tr_r1 real = 0.\n", + " tr_r2 real = 0.\n", + " tr_o1 real = 0.\n", + " tr_o2 real = 0.\n", + " end\n", + "\n", + " parameters:\n", + " the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called \"delay\"\n", + "\n", + " tau_plus ms = 16.8 ms # time constant for tr_r1\n", + " tau_x ms = 101 ms # time constant for tr_r2\n", + " tau_minus ms = 33.7 ms # time constant for tr_o1\n", + " tau_y ms = 125 ms # time constant for tr_o2\n", + "\n", + " A2_plus real = 7.5e-10\n", + " A3_plus real = 9.3e-3\n", + " A2_minus real = 7e-3\n", + " A3_minus real = 2.3e-4\n", + "\n", + " Wmax nS = 100 nS\n", + " Wmin nS = 0 nS\n", + " end\n", + "\n", + " equations:\n", + " tr_r1' = -tr_r1 / tau_plus\n", + " tr_r2' = -tr_r2 / tau_x\n", + " tr_o1' = -tr_o1 / tau_minus\n", + " tr_o2' = -tr_o2 / tau_y\n", + " end\n", + "\n", + " input:\n", + " pre_spikes nS <- spike\n", + " post_spikes nS <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " onReceive(post_spikes):\n", + " # increment post trace values\n", + " tr_o1 += 1\n", + " tr_o2 += 1\n", + "\n", + " # potentiate synapse\n", + " w_ nS = w + tr_r1 * ( A2_plus + A3_plus * tr_o2 )\n", + " w = min(Wmax, w_)\n", + " end\n", + "\n", + " onReceive(pre_spikes):\n", + " # increment pre trace values\n", + " tr_r1 += 1\n", + " tr_r2 += 1\n", + "\n", + " # depress synapse\n", + " w_ nS = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 )\n", + " w = max(Wmin, w_)\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, the_delay)\n", + " end\n", + " \n", + "end\n", + "\n", + "'''" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "parental-litigation", + "metadata": {}, + "outputs": [], + "source": [ + "n_modules_generated = 0\n", + "def generate_code_for(nestml_synapse_model: str):\n", + " \"\"\"Generate code for a given synapse model, passed as a string, in combination with\n", + " the iaf_psc_delta model.\n", + " \n", + " NEST cannot yet reload modules. Workaround using counter to generate unique names.\"\"\"\n", + " global n_modules_generated\n", + " \n", + " # append digit to the neuron model name and neuron model filename\n", + " with open(\"models/neurons/iaf_psc_delta.nestml\", \"r\") as nestml_model_file_orig:\n", + " nestml_neuron_model = nestml_model_file_orig.read()\n", + " nestml_neuron_model = re.sub(\"neuron\\ [^:\\s]*:\",\n", + " \"neuron iaf_psc_delta\" + str(n_modules_generated) + \":\", nestml_neuron_model)\n", + " with open(\"models/neurons/iaf_psc_delta\" + str(n_modules_generated) + \".nestml\", \"w\") as nestml_model_file_mod:\n", + " print(nestml_neuron_model, file=nestml_model_file_mod)\n", + "\n", + " # append digit to the synapse model name and synapse model filename\n", + " nestml_synapse_model_name = re.findall(\"synapse\\ [^:\\s]*:\", nestml_synapse_model)[0][8:-1]\n", + " nestml_synapse_model = re.sub(\"synapse\\ [^:\\s]*:\",\n", + " \"synapse \" + nestml_synapse_model_name + str(n_modules_generated) + \":\", nestml_synapse_model)\n", + " with open(\"models/synapses/\" + nestml_synapse_model_name + str(n_modules_generated) + \".nestml\", \"w\") as nestml_model_file:\n", + " print(nestml_synapse_model, file=nestml_model_file)\n", + "\n", + " # generate the code for neuron and synapse (co-generated)\n", + " module_name = \"nestml_\" + str(n_modules_generated) + \"_module\"\n", + " generate_nest_target(input_path=[\"models/neurons/iaf_psc_delta\" + str(n_modules_generated) + \".nestml\",\n", + " \"models/synapses/\" + nestml_synapse_model_name + str(n_modules_generated) + \".nestml\"],\n", + " target_path=\"/tmp/nestml_module\",\n", + " logging_level=\"ERROR\",\n", + " module_name=module_name,\n", + " suffix=\"_nestml\",\n", + " codegen_opts={\"nest_path\": NEST_INSTALL_PATH,\n", + " \"neuron_parent_class\": \"StructuralPlasticityNode\",\n", + " \"neuron_parent_class_include\": \"structural_plasticity_node.h\",\n", + " \"neuron_synapse_pairs\": [{\"neuron\": \"iaf_psc_delta\" + str(n_modules_generated),\n", + " \"synapse\": nestml_synapse_model_name + str(n_modules_generated),\n", + " \"post_ports\": [\"post_spikes\"]}]})\n", + " \n", + " # load module into NEST\n", + " nest.ResetKernel()\n", + " nest.Install(module_name)\n", + "\n", + " mangled_neuron_name = \"iaf_psc_delta\" + str(n_modules_generated) + \"_nestml__with_\" + nestml_synapse_model_name + str(n_modules_generated) + \"_nestml\"\n", + " mangled_synapse_name = nestml_synapse_model_name + str(n_modules_generated) + \"_nestml__with_iaf_psc_delta\" + str(n_modules_generated) + \"_nestml\"\n", + "\n", + " n_modules_generated += 1\n", + " \n", + " return mangled_neuron_name, mangled_synapse_name, nestml_synapse_model_name" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "colonial-serve", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1,GLOBAL, INFO]: List of files that will be processed:\n", + "[2,GLOBAL, INFO]: /home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/neurons/iaf_psc_delta0.nestml\n", + "[3,GLOBAL, INFO]: /home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/synapses/stdp_triplet0.nestml\n", + "[4,GLOBAL, INFO]: Start processing '/home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/neurons/iaf_psc_delta0.nestml'!\n", + "[5,iaf_psc_delta0_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[6,iaf_psc_delta0_nestml, WARNING, [67:4;67:22]]: Variable 'G' has the same name as a physical unit!\n", + "[7,iaf_psc_delta0_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n", + "[8,iaf_psc_delta0_nestml, WARNING, [69:70;69:70]]: Non-matching unit types at pA +/- pA buffer! Implicitly replaced by pA +/- 1.0 * pA buffer.\n", + "[9,iaf_psc_delta0_nestml, WARNING, [69:13;69:65]]: Non-matching unit types at mV / ms +/- pA / pF! Implicitly replaced by mV / ms +/- 1.0 * pA / pF.\n", + "[10,iaf_psc_delta0_nestml, INFO, [63:4;63:17]]: Ode of 'V_abs' updated!\n", + "[11,GLOBAL, INFO]: Start processing '/home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/synapses/stdp_triplet0.nestml'!\n", + "[12,stdp_triplet0_nestml, INFO, [2:0;67:0]]: Start building symbol table!\n", + "[13,stdp_triplet0_nestml, INFO, [64:18;64:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[14,stdp_triplet0_nestml, INFO, [46:13;46:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[15,stdp_triplet0_nestml, INFO, [47:13;47:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[16,stdp_triplet0_nestml, WARNING, [50:12;50:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[17,stdp_triplet0_nestml, INFO, [56:13;56:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[18,stdp_triplet0_nestml, INFO, [57:13;57:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[19,stdp_triplet0_nestml, WARNING, [60:12;60:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[20,GLOBAL, INFO]: All variables defined in state block: w, tr_r1, tr_r2, tr_o1, tr_o2\n", + "[21,GLOBAL, INFO]: All variables due to convolutions: []\n", + "[22,GLOBAL, INFO]: Assigned-to variables in onReceive(pre_spikes): tr_r1, tr_r2, w\n", + "[23,GLOBAL, INFO]: Variables used in convolve with other than 'spike post' port: []\n", + "[24,GLOBAL, INFO]: --> State variables that will be moved from synapse to neuron: {'tr_o2', 'tr_o1'}\n", + "[25,GLOBAL, INFO]: recursive dependent variables search yielded the following new variables: {'tr_o2', 'tr_o1', 'tau_minus', 'tau_y'}\n", + "[26,GLOBAL, INFO]: Moving state var definition of tr_o2 from synapse to neuron\n", + "[27,GLOBAL, INFO]: Moving state var definition of tr_o1 from synapse to neuron\n", + "[28,GLOBAL, INFO]: Moving state var defining equation(s) tr_o2\n", + "[29,GLOBAL, INFO]: Moving state var defining equation(s) tr_o1\n", + "[30,GLOBAL, INFO]: Moving state variables for equation(s) tr_o2\n", + "[31,GLOBAL, INFO]: Moving state variables for equation(s) tr_o1\n", + "[32,GLOBAL, INFO]: Moving onPost updates for tr_o2\n", + "[33,GLOBAL, INFO]: Moving state var updates for tr_o2 from synapse to neuron\n", + "[34,GLOBAL, INFO]: Moving onPost updates for tr_o1\n", + "[35,GLOBAL, INFO]: Moving state var updates for tr_o1 from synapse to neuron\n", + "[36,GLOBAL, INFO]: Dependent variables: tau_y, tr_o2, tau_minus, tr_o1\n", + "[37,GLOBAL, INFO]: Copying declarations from neuron equations block to synapse equations block...\n", + "[38,GLOBAL, INFO]: \t• Copying variable tau_y\n", + "[39,GLOBAL, INFO]: \t• Copying variable tr_o2\n", + "[40,GLOBAL, INFO]: \t• Copying variable tau_minus\n", + "[41,GLOBAL, INFO]: \t• Copying variable tr_o1\n", + "[42,GLOBAL, INFO]: In synapse: replacing variables with suffixed external variable references\n", + "[43,GLOBAL, INFO]: \t• Replacing variable tr_o2\n", + "[44,GLOBAL, INFO]: ASTSimpleExpression replacement made (var = tr_o2__for_stdp_triplet0_nestml) in expression: A3_plus * tr_o2\n", + "[45,GLOBAL, INFO]: \t• Replacing variable tr_o1\n", + "[46,GLOBAL, INFO]: ASTSimpleExpression replacement made (var = tr_o1__for_stdp_triplet0_nestml) in expression: tr_o1 * (A2_minus + A3_minus * tr_r2)\n", + "[47,GLOBAL, INFO]: In synapse: replacing ``continuous`` type input ports that are connected to postsynaptic neuron with suffixed external variable references\n", + "[48,GLOBAL, INFO]: Add suffix to moved variable names in neuron...\n", + "[49,GLOBAL, INFO]: \t• Variable tau_y\n", + "[50,GLOBAL, INFO]: \t• Variable tr_o2\n", + "[51,GLOBAL, INFO]: \t• Variable tau_minus\n", + "[52,GLOBAL, INFO]: \t• Variable tr_o1\n", + "[53,GLOBAL, INFO]: Moving parameters...\n", + "[54,GLOBAL, INFO]: Moving parameter with name tr_o2 from synapse to neuron\n", + "[55,GLOBAL, INFO]: Moving parameter with name tr_o1 from synapse to neuron\n", + "[56,GLOBAL, INFO]: Moving parameter with name tau_minus from synapse to neuron\n", + "[57,GLOBAL, INFO]: Moving parameter with name tau_y from synapse to neuron\n", + "[58,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[59,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, WARNING, [67:4;67:22]]: Variable 'G' has the same name as a physical unit!\n", + "[60,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n", + "[61,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, WARNING, [69:70;69:70]]: Non-matching unit types at pA +/- pA buffer! Implicitly replaced by pA +/- 1.0 * pA buffer.\n", + "[62,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, WARNING, [69:13;69:65]]: Non-matching unit types at mV / ms +/- pA / pF! Implicitly replaced by mV / ms +/- 1.0 * pA / pF.\n", + "[63,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [63:4;63:17]]: Ode of 'V_abs' updated!\n", + "[64,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [10:4;10:17]]: Ode of 'tr_o2__for_stdp_triplet0_nestml' updated!\n", + "[65,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [9:4;9:17]]: Ode of 'tr_o1__for_stdp_triplet0_nestml' updated!\n", + "[66,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: Start building symbol table!\n", + "[67,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [64:18;64:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_syn\": \"2\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[68,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, WARNING, [50:12;50:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[69,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [56:13;56:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[70,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [57:13;57:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[71,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, WARNING, [60:12;60:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[72,GLOBAL, INFO]: Successfully constructed neuron-synapse pair models\n", + "[73,GLOBAL, INFO]: Analysing/transforming neuron 'iaf_psc_delta0_nestml'\n", + "[74,iaf_psc_delta0_nestml, INFO, [58:0;131:0]]: Starts processing of the model 'iaf_psc_delta0_nestml'\n", + "[75,iaf_psc_delta0_nestml, INFO, [58:0;131:0]]: The neuron 'iaf_psc_delta0_nestml' will be analysed!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Dependency analysis...\n", + "INFO:Generating numerical solver for the following symbols: V_abs\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\"\n", + " }\n", + " }\n", + "]\n", + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_syn\": \"2\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Dependency analysis...\n", + "INFO:Generating numerical solver for the following symbols: V_abs\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\"\n", + " }\n", + " }\n", + "]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[76,iaf_psc_delta0_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[77,iaf_psc_delta0_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o2__for_stdp_triplet0_nestml' = -tr_o2__for_stdp_triplet0_nestml / tau_y__for_stdp_triplet0_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o2__for_stdp_triplet0_nestml\": \"0.000000E+00\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o1__for_stdp_triplet0_nestml' = -tr_o1__for_stdp_triplet0_nestml / tau_minus__for_stdp_triplet0_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o1__for_stdp_triplet0_nestml\": \"0.000000E+00\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_minus__for_stdp_triplet0_nestml\": \"3.370000E+01\",\n", + " \"tau_syn\": \"2\",\n", + " \"tau_y__for_stdp_triplet0_nestml\": \"125\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet0_nestml with defining expression = \"-tr_o2__for_stdp_triplet0_nestml / tau_y__for_stdp_triplet0_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet0_nestml with defining expression = \"-tr_o1__for_stdp_triplet0_nestml / tau_minus__for_stdp_triplet0_nestml\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet0_nestml with defining expression = \"-tr_o2__for_stdp_triplet0_nestml / tau_y__for_stdp_triplet0_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet0_nestml with defining expression = \"-tr_o1__for_stdp_triplet0_nestml / tau_minus__for_stdp_triplet0_nestml\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Shape tr_o2__for_stdp_triplet0_nestml: reconstituting expression -tr_o2__for_stdp_triplet0_nestml/tau_y__for_stdp_triplet0_nestml\n", + "INFO:Shape tr_o1__for_stdp_triplet0_nestml: reconstituting expression -tr_o1__for_stdp_triplet0_nestml/tau_minus__for_stdp_triplet0_nestml\n", + "INFO:Dependency analysis...\n", + "INFO:Generating propagators for the following symbols: tr_o2__for_stdp_triplet0_nestml, tr_o1__for_stdp_triplet0_nestml\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[78,GLOBAL, INFO]: Analysing/transforming neuron 'iaf_psc_delta0_nestml__with_stdp_triplet0_nestml'\n", + "[79,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [58:0;131:0]]: Starts processing of the model 'iaf_psc_delta0_nestml__with_stdp_triplet0_nestml'\n", + "[80,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [58:0;131:0]]: The neuron 'iaf_psc_delta0_nestml__with_stdp_triplet0_nestml' will be analysed!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:Generating numerical solver for the following symbols: V_abs\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"tr_o1__for_stdp_triplet0_nestml\": \"0.0\",\n", + " \"tr_o2__for_stdp_triplet0_nestml\": \"0.0\"\n", + " },\n", + " \"parameters\": {\n", + " \"tau_minus__for_stdp_triplet0_nestml\": \"33.7000000000000\",\n", + " \"tau_y__for_stdp_triplet0_nestml\": \"125.000000000000\"\n", + " },\n", + " \"propagators\": {\n", + " \"__P__tr_o1__for_stdp_triplet0_nestml__tr_o1__for_stdp_triplet0_nestml\": \"exp(-__h/tau_minus__for_stdp_triplet0_nestml)\",\n", + " \"__P__tr_o2__for_stdp_triplet0_nestml__tr_o2__for_stdp_triplet0_nestml\": \"exp(-__h/tau_y__for_stdp_triplet0_nestml)\"\n", + " },\n", + " \"solver\": \"analytical\",\n", + " \"state_variables\": [\n", + " \"tr_o2__for_stdp_triplet0_nestml\",\n", + " \"tr_o1__for_stdp_triplet0_nestml\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"tr_o1__for_stdp_triplet0_nestml\": \"__P__tr_o1__for_stdp_triplet0_nestml__tr_o1__for_stdp_triplet0_nestml*tr_o1__for_stdp_triplet0_nestml\",\n", + " \"tr_o2__for_stdp_triplet0_nestml\": \"__P__tr_o2__for_stdp_triplet0_nestml__tr_o2__for_stdp_triplet0_nestml*tr_o2__for_stdp_triplet0_nestml\"\n", + " }\n", + " },\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\"\n", + " }\n", + " }\n", + "]\n", + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o2__for_stdp_triplet0_nestml' = -tr_o2__for_stdp_triplet0_nestml / tau_y__for_stdp_triplet0_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o2__for_stdp_triplet0_nestml\": \"0.000000E+00\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o1__for_stdp_triplet0_nestml' = -tr_o1__for_stdp_triplet0_nestml / tau_minus__for_stdp_triplet0_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o1__for_stdp_triplet0_nestml\": \"0.000000E+00\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_minus__for_stdp_triplet0_nestml\": \"3.370000E+01\",\n", + " \"tau_syn\": \"2\",\n", + " \"tau_y__for_stdp_triplet0_nestml\": \"125\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet0_nestml with defining expression = \"-tr_o2__for_stdp_triplet0_nestml / tau_y__for_stdp_triplet0_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet0_nestml with defining expression = \"-tr_o1__for_stdp_triplet0_nestml / tau_minus__for_stdp_triplet0_nestml\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet0_nestml with defining expression = \"-tr_o2__for_stdp_triplet0_nestml / tau_y__for_stdp_triplet0_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet0_nestml with defining expression = \"-tr_o1__for_stdp_triplet0_nestml / tau_minus__for_stdp_triplet0_nestml\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Shape tr_o2__for_stdp_triplet0_nestml: reconstituting expression -tr_o2__for_stdp_triplet0_nestml/tau_y__for_stdp_triplet0_nestml\n", + "INFO:Shape tr_o1__for_stdp_triplet0_nestml: reconstituting expression -tr_o1__for_stdp_triplet0_nestml/tau_minus__for_stdp_triplet0_nestml\n", + "INFO:Dependency analysis...\n", + "INFO:Generating numerical solver for the following symbols: V_abs, tr_o2__for_stdp_triplet0_nestml, tr_o1__for_stdp_triplet0_nestml\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\",\n", + " \"tr_o1__for_stdp_triplet0_nestml\": \"0.0\",\n", + " \"tr_o2__for_stdp_triplet0_nestml\": \"0.0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\",\n", + " \"tau_minus__for_stdp_triplet0_nestml\": \"33.7000000000000\",\n", + " \"tau_y__for_stdp_triplet0_nestml\": \"125.000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\",\n", + " \"tr_o2__for_stdp_triplet0_nestml\",\n", + " \"tr_o1__for_stdp_triplet0_nestml\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\",\n", + " \"tr_o1__for_stdp_triplet0_nestml\": \"-tr_o1__for_stdp_triplet0_nestml/tau_minus__for_stdp_triplet0_nestml\",\n", + " \"tr_o2__for_stdp_triplet0_nestml\": \"-tr_o2__for_stdp_triplet0_nestml/tau_y__for_stdp_triplet0_nestml\"\n", + " }\n", + " }\n", + "]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[81,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[82,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"tr_r1' = -tr_r1 / tau_plus\",\n", + " \"initial_values\": {\n", + " \"tr_r1\": \"0.000000E+00\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_r2' = -tr_r2 / tau_x\",\n", + " \"initial_values\": {\n", + " \"tr_r2\": \"0.000000E+00\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"A2_minus\": \"7.000000E-03\",\n", + " \"A2_plus\": \"7.500000E-10\",\n", + " \"A3_minus\": \"2.300000E-04\",\n", + " \"A3_plus\": \"9.300000E-03\",\n", + " \"Wmax\": \"100\",\n", + " \"Wmin\": \"0\",\n", + " \"tau_plus\": \"1.680000E+01\",\n", + " \"tau_x\": \"101\",\n", + " \"the_delay\": \"1\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape tr_r1 with defining expression = \"-tr_r1 / tau_plus\"\n", + "INFO:\n", + "Processing shape tr_r2 with defining expression = \"-tr_r2 / tau_x\"\n", + "INFO:\n", + "Processing shape tr_r1 with defining expression = \"-tr_r1 / tau_plus\"\n", + "INFO:\n", + "Processing shape tr_r2 with defining expression = \"-tr_r2 / tau_x\"\n", + "INFO:Shape tr_r1: reconstituting expression -tr_r1/tau_plus\n", + "INFO:Shape tr_r2: reconstituting expression -tr_r2/tau_x\n", + "INFO:Dependency analysis...\n", + "INFO:Generating propagators for the following symbols: tr_r1, tr_r2\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Analysing/transforming synapse stdp_triplet0_nestml__with_iaf_psc_delta0_nestml.\n", + "[83,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: Starts processing of the model 'stdp_triplet0_nestml__with_iaf_psc_delta0_nestml'\n", + "[84,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: The neuron 'stdp_triplet0_nestml__with_iaf_psc_delta0_nestml' will be analysed!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"tr_r1\": \"0.0\",\n", + " \"tr_r2\": \"0.0\"\n", + " },\n", + " \"parameters\": {\n", + " \"tau_plus\": \"16.8000000000000\",\n", + " \"tau_x\": \"101.000000000000\"\n", + " },\n", + " \"propagators\": {\n", + " \"__P__tr_r1__tr_r1\": \"exp(-__h/tau_plus)\",\n", + " \"__P__tr_r2__tr_r2\": \"exp(-__h/tau_x)\"\n", + " },\n", + " \"solver\": \"analytical\",\n", + " \"state_variables\": [\n", + " \"tr_r1\",\n", + " \"tr_r2\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"tr_r1\": \"__P__tr_r1__tr_r1*tr_r1\",\n", + " \"tr_r2\": \"__P__tr_r2__tr_r2*tr_r2\"\n", + " }\n", + " }\n", + "]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[85,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: Start building symbol table!\n", + "[86,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [64:18;64:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[87,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [56:13;56:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[88,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [57:13;57:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[89,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: Start building symbol table!\n", + "[90,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [64:18;64:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[91,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [56:13;56:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[92,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [57:13;57:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[93,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: Start building symbol table!\n", + "[94,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [64:18;64:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[95,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [56:13;56:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[96,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [57:13;57:13]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[97,iaf_psc_delta0_nestml, INFO, [58:0;131:0]]: Successfully generated code for the model: 'iaf_psc_delta0_nestml' in: '/tmp/nestml_module' !\n", + "[98,iaf_psc_delta0_nestml__with_stdp_triplet0_nestml, INFO, [58:0;131:0]]: Successfully generated code for the model: 'iaf_psc_delta0_nestml__with_stdp_triplet0_nestml' in: '/tmp/nestml_module' !\n", + "Generating code for the synapse stdp_triplet0_nestml__with_iaf_psc_delta0_nestml.\n", + "[99,stdp_triplet0_nestml__with_iaf_psc_delta0_nestml, INFO, [2:0;67:0]]: Successfully generated code for the model: 'stdp_triplet0_nestml__with_iaf_psc_delta0_nestml' in: '/tmp/nestml_module' !\n", + "[100,GLOBAL, INFO]: Successfully generated NEST module code in '/tmp/nestml_module' !\n" + ] + } + ], + "source": [ + "# Generate code for All-to-All spike interaction\n", + "neuron_model_name, synapse_model_name, nestml_synapse_model_name = \\\n", + "generate_code_for(nestml_triplet_stdp_model)" + ] + }, + { + "attachments": { + "image-3.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmcAAAFsCAYAAACJnR5PAAAgAElEQVR4AeydB5xVxfXH0RiT+I/R2LvEWFFRsRtFTWKNGjW2JPYGWKLG2HvvHQULRbGAYu+9i2A3VixYKNK37+vn//nOfb/H7HUXUMAsb8+Ft3PvzJkzZ37Tzj1TbifzyxFwBBwBR8ARcAQcAUeg3SDQqd1I4oI4Ao6AI+AIOAKOgCPgCJgrZ14JHAFHwBFwBBwBR8ARaEcIuHLWjgrDRXEEHAFHwBFwBBwBR8CVM68DjoAj4Ag4Ao6AI+AItCMEXDlrR4XhojgCjoAj4Ag4Ao6AI+DKmdcBR8ARcAQcAUfAEXAE2hECrpy1o8JwURwBR8ARcAQcAUfAEXDlzOuAI+AIOAKOgCPgCDgC7QgBV87aUWG4KI6AI+AIOAKOgCPgCLhy5nXAEXAEHAFHwBFwBByBdoSAK2ftqDBcFEfAEXAEHAFHwBFwBFw58zrgCDgCjoAj4Ag4Ao5AO0LAlbN2VBguiiPgCDgCjoAj4Ag4Aq6ceR1wBBwBR8ARcAQcAUegHSHgylk7KgwXxRFwBBwBR8ARcAQcAVfOvA44Ao6AI+AIOAKOgCPQjhBw5awdFYaL4gg4Ao6AI+AIOAKOgCtnXgccAUfAEXAEHAFHwBFoRwi4ctaOCsNFcQQcAUfAEXAEHAFHwJUzrwOOgCPgCDgCjoAj4Ai0IwRcOWtHheGiOAKOgCPgCDgCjoAj4MqZ1wFHwBFwBBwBR8ARcATaEQKunLWjwnBRHAFHwBFwBBwBR8ARcOXM64Aj4Ag4Ao6AI+AIOALtCAFXztpRYbgojoAj4Ag4Ao6AI+AIuHLmdcARcAQcAUfAEXAEHIF2hIArZ+2oMFwUR8ARcAQcAUfAEXAEXDnzOuAIOAKOgCPgCDgCjkA7QsCVs3ZUGC6KI+AIOAKOgCPgCDgCrpx5HXAEHAFHwBFwBBwBR6AdIeDKWTsqDBfFEXAEHAFHwBFwBBwBV868DjgCjoAj4Ag4Ao6AI9COEHDlrB0VhoviCDgCjoAj4Ag4Ao6AK2deBxwBR8ARcAQcAUfAEWhHCLhy1o4Kw0VxBBwBR8ARcAQcAUfAlTOvA46AI+AIOAKOgCPgCLQjBFw5a0eF4aI4Ao6AI+AIOAKOgCMwR5SzYrEYkC0UChWE8eMnv3w+XwnjhrBSqVTx4z6Xy1We0zdKI44DTfo5Hc+fHYGOikBrbUPtCExaa2/pOKKXm8ZS7VuuwmM+bcUVrbszj0A2m60Qg7FwllsJ/JE3rdUJsVIYZU1//tprr9kTTzxhL7zwQujP0318fX29ffjhh5UxQHx+Kld1Mq5/MU6x//Rkmlm66fHwMEdgRgjMknKWbnxqrK0lqoZBHCr3sGHD7JprrrF+/fpZ37597eqrrw6/Sy+91Phdf/31wX/ixIktGjqNKZPJ2O23327PPPNMi6SURgtPf3AEHIEKArSf999/v9Le+vTpE9rhZZddZv3797frrrvOnn766TDIq32rzYoJ7Rc+7733Xmij1157rd1www3Wu3fvSru96aabwkBNHNpr+ooHxXSYP88cAmkM1f82NDTMHIOZpCIdylxKieoF0V988UW7+eab7dRTT7VOnTqF389//nM777zzjDrw9ttvV5R+lLYDDzwwpJqWfSZF+UFkGg/kKrLqo2T45JNPgqxXXXWVXX755UZ9RvbPPvtMUdx1BH5yBGZJOVNjjd/eyAGNgV/av7Gx0T7//HM75JBD7He/+12lMdOo55tvvsrzz372s8r99ttvb1OmTAnAqFM466yzQjh8SEONLEYv3SDjML93BDoCAnEbUBuhzTL4aCDFnWeeeVo877PPPgEexUljJX8GM/GhzfKbd955gx88t95660pU2r4uDY56dvfHIaByAE/1jbMTW/FMS6d0X331VVtiiSVCea+yyir2wAMP2IMPPhheuNW/r7zyyvbWW28FFtAfdNBBFWUtzXdOPNMGBg4cGMYc6quuOG933XVXpR4zDqFcUq8fe+yx/5mVT3K623ERmCXlTLBpEJCyJn+5Y8aMsX//+9+2/vrr2+9///tKQ1hqqaVs+eWXt2OPPTa8hfOm8tVXX9mnn35qF154oS299NK22GKL2ZprrhlosKKddtpp9qtf/SrwOPjgg0MSbaWr9N11BDo6AgyoGpCYXvrvf/8b2tr9999vv/3tb0N7UrtaYIEFbMiQIQGyeLDXoKz2VlNTE6wLf/vb32zJJZcMPBZaaCHr2rVrsIx/++23rb44dfSymJ35V98LT8qHslE5zY50VGdIJ07r+eeft4UXXjj0z88++6xNmjSpRbr05V988YWde+651rlz56C0rbfeenbUUUcFsWJes0POtnhQ13feeefKmINlWJcs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" + } + }, + "cell_type": "markdown", + "id": "settled-keeping", + "metadata": {}, + "source": [ + "$\\textit{Nearest spike Interation}$ - Each postsynaptic spike interacts with only the last spike. Hence no accumulation of the trace variables occurs. The variables saturate at 1. This is achieved by updating the variables to the value of 1 instead of updating by at step of 1. In this way, the synapse forgets all other previous spikes and keeps only the memory of the last one.\n", + "\n", + "
\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "addressed-roads", + "metadata": {}, + "outputs": [], + "source": [ + "nestml_triplet_stdp_nn_model = '''\n", + "synapse stdp_triplet_nn:\n", + "\n", + " state:\n", + " w nS = 1 nS\n", + "\n", + " tr_r1 real = 0.\n", + " tr_r2 real = 0.\n", + " tr_o1 real = 0.\n", + " tr_o2 real = 0.\n", + " end\n", + "\n", + " parameters:\n", + " the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called \"delay\"\n", + "\n", + " tau_plus ms = 16.8 ms # time constant for tr_r1\n", + " tau_x ms = 101 ms # time constant for tr_r2\n", + " tau_minus ms = 33.7 ms # time constant for tr_o1\n", + " tau_y ms = 125 ms # time constant for tr_o2\n", + "\n", + " A2_plus real = 7.5e-10\n", + " A3_plus real = 9.3e-3\n", + " A2_minus real = 7e-3\n", + " A3_minus real = 2.3e-4\n", + "\n", + " Wmax nS = 100 nS\n", + " Wmin nS = 0 nS\n", + " end\n", + "\n", + " equations:\n", + " tr_r1' = -tr_r1 / tau_plus\n", + " tr_r2' = -tr_r2 / tau_x\n", + " tr_o1' = -tr_o1 / tau_minus\n", + " tr_o2' = -tr_o2 / tau_y\n", + " end\n", + "\n", + " input:\n", + " pre_spikes nS <- spike\n", + " post_spikes nS <- spike\n", + " end\n", + "\n", + " output: spike\n", + "\n", + " onReceive(post_spikes):\n", + " # increment post trace values\n", + " tr_o1 = 1\n", + " tr_o2 = 1\n", + "\n", + " # potentiate synapse\n", + " #w_ nS = Wmax * ( w / Wmax + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) )\n", + " w_ nS = w + tr_r1 * ( A2_plus + A3_plus * tr_o2 )\n", + " w = min(Wmax, w_)\n", + " end\n", + "\n", + " onReceive(pre_spikes):\n", + " # increment pre trace values\n", + " tr_r1 = 1\n", + " tr_r2 = 1\n", + "\n", + " # depress synapse\n", + " #w_ nS = Wmax * ( w / Wmax - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) )\n", + " w_ nS = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 )\n", + " w = max(Wmin, w_)\n", + "\n", + " # deliver spike to postsynaptic partner\n", + " deliver_spike(w, the_delay)\n", + " end\n", + " \n", + "end\n", + "\n", + "'''" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "civic-xerox", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1,GLOBAL, INFO]: List of files that will be processed:\n", + "[2,GLOBAL, INFO]: /home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/neurons/iaf_psc_delta1.nestml\n", + "[3,GLOBAL, INFO]: /home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/synapses/stdp_triplet_nn1.nestml\n", + "[4,GLOBAL, INFO]: Start processing '/home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/neurons/iaf_psc_delta1.nestml'!\n", + "[5,iaf_psc_delta1_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[6,iaf_psc_delta1_nestml, WARNING, [67:4;67:22]]: Variable 'G' has the same name as a physical unit!\n", + "[7,iaf_psc_delta1_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n", + "[8,iaf_psc_delta1_nestml, WARNING, [69:70;69:70]]: Non-matching unit types at pA +/- pA buffer! Implicitly replaced by pA +/- 1.0 * pA buffer.\n", + "[9,iaf_psc_delta1_nestml, WARNING, [69:13;69:65]]: Non-matching unit types at mV / ms +/- pA / pF! Implicitly replaced by mV / ms +/- 1.0 * pA / pF.\n", + "[10,iaf_psc_delta1_nestml, INFO, [63:4;63:17]]: Ode of 'V_abs' updated!\n", + "[11,GLOBAL, INFO]: Start processing '/home/charl/julich/nestml-fork-jit-third-factor/nestml/doc/tutorials/stdp_windows/models/synapses/stdp_triplet_nn1.nestml'!\n", + "[12,stdp_triplet_nn1_nestml, INFO, [2:0;69:0]]: Start building symbol table!\n", + "[13,stdp_triplet_nn1_nestml, INFO, [66:18;66:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[14,stdp_triplet_nn1_nestml, INFO, [46:12;46:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[15,stdp_triplet_nn1_nestml, INFO, [47:12;47:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[16,stdp_triplet_nn1_nestml, WARNING, [51:12;51:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[17,stdp_triplet_nn1_nestml, INFO, [57:12;57:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[18,stdp_triplet_nn1_nestml, INFO, [58:12;58:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[19,stdp_triplet_nn1_nestml, WARNING, [62:12;62:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[20,GLOBAL, INFO]: All variables defined in state block: w, tr_r1, tr_r2, tr_o1, tr_o2\n", + "[21,GLOBAL, INFO]: All variables due to convolutions: []\n", + "[22,GLOBAL, INFO]: Assigned-to variables in onReceive(pre_spikes): tr_r1, tr_r2, w\n", + "[23,GLOBAL, INFO]: Variables used in convolve with other than 'spike post' port: []\n", + "[24,GLOBAL, INFO]: --> State variables that will be moved from synapse to neuron: {'tr_o2', 'tr_o1'}\n", + "[25,GLOBAL, INFO]: recursive dependent variables search yielded the following new variables: {'tr_o2', 'tr_o1', 'tau_minus', 'tau_y'}\n", + "[26,GLOBAL, INFO]: Moving state var definition of tr_o2 from synapse to neuron\n", + "[27,GLOBAL, INFO]: Moving state var definition of tr_o1 from synapse to neuron\n", + "[28,GLOBAL, INFO]: Moving state var defining equation(s) tr_o2\n", + "[29,GLOBAL, INFO]: Moving state var defining equation(s) tr_o1\n", + "[30,GLOBAL, INFO]: Moving state variables for equation(s) tr_o2\n", + "[31,GLOBAL, INFO]: Moving state variables for equation(s) tr_o1\n", + "[32,GLOBAL, INFO]: Moving onPost updates for tr_o2\n", + "[33,GLOBAL, INFO]: Moving state var updates for tr_o2 from synapse to neuron\n", + "[34,GLOBAL, INFO]: Moving onPost updates for tr_o1\n", + "[35,GLOBAL, INFO]: Moving state var updates for tr_o1 from synapse to neuron\n", + "[36,GLOBAL, INFO]: Dependent variables: tau_y, tr_o2, tr_o1, tau_minus\n", + "[37,GLOBAL, INFO]: Copying declarations from neuron equations block to synapse equations block...\n", + "[38,GLOBAL, INFO]: \t• Copying variable tau_y\n", + "[39,GLOBAL, INFO]: \t• Copying variable tr_o2\n", + "[40,GLOBAL, INFO]: \t• Copying variable tr_o1\n", + "[41,GLOBAL, INFO]: \t• Copying variable tau_minus\n", + "[42,GLOBAL, INFO]: In synapse: replacing variables with suffixed external variable references\n", + "[43,GLOBAL, INFO]: \t• Replacing variable tr_o2\n", + "[44,GLOBAL, INFO]: ASTSimpleExpression replacement made (var = tr_o2__for_stdp_triplet_nn1_nestml) in expression: A3_plus * tr_o2\n", + "[45,GLOBAL, INFO]: \t• Replacing variable tr_o1\n", + "[46,GLOBAL, INFO]: ASTSimpleExpression replacement made (var = tr_o1__for_stdp_triplet_nn1_nestml) in expression: tr_o1 * (A2_minus + A3_minus * tr_r2)\n", + "[47,GLOBAL, INFO]: In synapse: replacing ``continuous`` type input ports that are connected to postsynaptic neuron with suffixed external variable references\n", + "[48,GLOBAL, INFO]: Add suffix to moved variable names in neuron...\n", + "[49,GLOBAL, INFO]: \t• Variable tau_y\n", + "[50,GLOBAL, INFO]: \t• Variable tr_o2\n", + "[51,GLOBAL, INFO]: \t• Variable tr_o1\n", + "[52,GLOBAL, INFO]: \t• Variable tau_minus\n", + "[53,GLOBAL, INFO]: Moving parameters...\n", + "[54,GLOBAL, INFO]: Moving parameter with name tr_o2 from synapse to neuron\n", + "[55,GLOBAL, INFO]: Moving parameter with name tr_o1 from synapse to neuron\n", + "[56,GLOBAL, INFO]: Moving parameter with name tau_minus from synapse to neuron\n", + "[57,GLOBAL, INFO]: Moving parameter with name tau_y from synapse to neuron\n", + "[58,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[59,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, WARNING, [67:4;67:22]]: Variable 'G' has the same name as a physical unit!\n", + "[60,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n", + "[61,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, WARNING, [69:70;69:70]]: Non-matching unit types at pA +/- pA buffer! Implicitly replaced by pA +/- 1.0 * pA buffer.\n", + "[62,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, WARNING, [69:13;69:65]]: Non-matching unit types at mV / ms +/- pA / pF! Implicitly replaced by mV / ms +/- 1.0 * pA / pF.\n", + "[63,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [63:4;63:17]]: Ode of 'V_abs' updated!\n", + "[64,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [10:4;10:17]]: Ode of 'tr_o2__for_stdp_triplet_nn1_nestml' updated!\n", + "[65,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [9:4;9:17]]: Ode of 'tr_o1__for_stdp_triplet_nn1_nestml' updated!\n", + "[66,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: Start building symbol table!\n", + "[67,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [66:18;66:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_syn\": \"2\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[68,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, WARNING, [51:12;51:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[69,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [57:12;57:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[70,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [58:12;58:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[71,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, WARNING, [62:12;62:12]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[72,GLOBAL, INFO]: Successfully constructed neuron-synapse pair models\n", + "[73,GLOBAL, INFO]: Analysing/transforming neuron 'iaf_psc_delta1_nestml'\n", + "[74,iaf_psc_delta1_nestml, INFO, [58:0;131:0]]: Starts processing of the model 'iaf_psc_delta1_nestml'\n", + "[75,iaf_psc_delta1_nestml, INFO, [58:0;131:0]]: The neuron 'iaf_psc_delta1_nestml' will be analysed!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Dependency analysis...\n", + "INFO:Generating numerical solver for the following symbols: V_abs\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\"\n", + " }\n", + " }\n", + "]\n", + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_syn\": \"2\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Dependency analysis...\n", + "INFO:Generating numerical solver for the following symbols: V_abs\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\"\n", + " }\n", + " }\n", + "]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[76,iaf_psc_delta1_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[77,iaf_psc_delta1_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o2__for_stdp_triplet_nn1_nestml' = -tr_o2__for_stdp_triplet_nn1_nestml / tau_y__for_stdp_triplet_nn1_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\": \"0.000000E+00\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o1__for_stdp_triplet_nn1_nestml' = -tr_o1__for_stdp_triplet_nn1_nestml / tau_minus__for_stdp_triplet_nn1_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\": \"0.000000E+00\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_minus__for_stdp_triplet_nn1_nestml\": \"3.370000E+01\",\n", + " \"tau_syn\": \"2\",\n", + " \"tau_y__for_stdp_triplet_nn1_nestml\": \"125\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o2__for_stdp_triplet_nn1_nestml / tau_y__for_stdp_triplet_nn1_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o1__for_stdp_triplet_nn1_nestml / tau_minus__for_stdp_triplet_nn1_nestml\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o2__for_stdp_triplet_nn1_nestml / tau_y__for_stdp_triplet_nn1_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o1__for_stdp_triplet_nn1_nestml / tau_minus__for_stdp_triplet_nn1_nestml\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Shape tr_o2__for_stdp_triplet_nn1_nestml: reconstituting expression -tr_o2__for_stdp_triplet_nn1_nestml/tau_y__for_stdp_triplet_nn1_nestml\n", + "INFO:Shape tr_o1__for_stdp_triplet_nn1_nestml: reconstituting expression -tr_o1__for_stdp_triplet_nn1_nestml/tau_minus__for_stdp_triplet_nn1_nestml\n", + "INFO:Dependency analysis...\n", + "INFO:Generating propagators for the following symbols: tr_o2__for_stdp_triplet_nn1_nestml, tr_o1__for_stdp_triplet_nn1_nestml\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[78,GLOBAL, INFO]: Analysing/transforming neuron 'iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml'\n", + "[79,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [58:0;131:0]]: Starts processing of the model 'iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml'\n", + "[80,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [58:0;131:0]]: The neuron 'iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml' will be analysed!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:Generating numerical solver for the following symbols: V_abs\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\": \"0.0\",\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\": \"0.0\"\n", + " },\n", + " \"parameters\": {\n", + " \"tau_minus__for_stdp_triplet_nn1_nestml\": \"33.7000000000000\",\n", + " \"tau_y__for_stdp_triplet_nn1_nestml\": \"125.000000000000\"\n", + " },\n", + " \"propagators\": {\n", + " \"__P__tr_o1__for_stdp_triplet_nn1_nestml__tr_o1__for_stdp_triplet_nn1_nestml\": \"exp(-__h/tau_minus__for_stdp_triplet_nn1_nestml)\",\n", + " \"__P__tr_o2__for_stdp_triplet_nn1_nestml__tr_o2__for_stdp_triplet_nn1_nestml\": \"exp(-__h/tau_y__for_stdp_triplet_nn1_nestml)\"\n", + " },\n", + " \"solver\": \"analytical\",\n", + " \"state_variables\": [\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\",\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\": \"__P__tr_o1__for_stdp_triplet_nn1_nestml__tr_o1__for_stdp_triplet_nn1_nestml*tr_o1__for_stdp_triplet_nn1_nestml\",\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\": \"__P__tr_o2__for_stdp_triplet_nn1_nestml__tr_o2__for_stdp_triplet_nn1_nestml*tr_o2__for_stdp_triplet_nn1_nestml\"\n", + " }\n", + " },\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\"\n", + " }\n", + " }\n", + "]\n", + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"V_abs' = -V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\",\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o2__for_stdp_triplet_nn1_nestml' = -tr_o2__for_stdp_triplet_nn1_nestml / tau_y__for_stdp_triplet_nn1_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\": \"0.000000E+00\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_o1__for_stdp_triplet_nn1_nestml' = -tr_o1__for_stdp_triplet_nn1_nestml / tau_minus__for_stdp_triplet_nn1_nestml\",\n", + " \"initial_values\": {\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\": \"0.000000E+00\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250\",\n", + " \"E_L\": \"-70\",\n", + " \"I_e\": \"0\",\n", + " \"Theta\": \"-55 - E_L\",\n", + " \"V_min\": \"-inf * 1\",\n", + " \"V_reset\": \"-70 - E_L\",\n", + " \"t_ref\": \"2\",\n", + " \"tau_m\": \"10\",\n", + " \"tau_minus__for_stdp_triplet_nn1_nestml\": \"3.370000E+01\",\n", + " \"tau_syn\": \"2\",\n", + " \"tau_y__for_stdp_triplet_nn1_nestml\": \"125\",\n", + " \"with_refr_input\": \"false\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o2__for_stdp_triplet_nn1_nestml / tau_y__for_stdp_triplet_nn1_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o1__for_stdp_triplet_nn1_nestml / tau_minus__for_stdp_triplet_nn1_nestml\"\n", + "INFO:\n", + "Processing shape V_abs with defining expression = \"-V_abs / tau_m + (1.0 / 1.0 / 1.0) * 0 + (I_e + I_stim) / C_m\"\n", + "INFO:\n", + "Processing shape tr_o2__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o2__for_stdp_triplet_nn1_nestml / tau_y__for_stdp_triplet_nn1_nestml\"\n", + "INFO:\n", + "Processing shape tr_o1__for_stdp_triplet_nn1_nestml with defining expression = \"-tr_o1__for_stdp_triplet_nn1_nestml / tau_minus__for_stdp_triplet_nn1_nestml\"\n", + "INFO:Shape V_abs: reconstituting expression -V_abs/tau_m + (I_e + I_stim)/C_m\n", + "INFO:Shape tr_o2__for_stdp_triplet_nn1_nestml: reconstituting expression -tr_o2__for_stdp_triplet_nn1_nestml/tau_y__for_stdp_triplet_nn1_nestml\n", + "INFO:Shape tr_o1__for_stdp_triplet_nn1_nestml: reconstituting expression -tr_o1__for_stdp_triplet_nn1_nestml/tau_minus__for_stdp_triplet_nn1_nestml\n", + "INFO:Dependency analysis...\n", + "INFO:Generating numerical solver for the following symbols: V_abs, tr_o2__for_stdp_triplet_nn1_nestml, tr_o1__for_stdp_triplet_nn1_nestml\n", + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"V_abs\": \"0\",\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\": \"0.0\",\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\": \"0.0\"\n", + " },\n", + " \"parameters\": {\n", + " \"C_m\": \"250.000000000000\",\n", + " \"I_e\": \"0\",\n", + " \"tau_m\": \"10.0000000000000\",\n", + " \"tau_minus__for_stdp_triplet_nn1_nestml\": \"33.7000000000000\",\n", + " \"tau_y__for_stdp_triplet_nn1_nestml\": \"125.000000000000\"\n", + " },\n", + " \"solver\": \"numeric\",\n", + " \"state_variables\": [\n", + " \"V_abs\",\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\",\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"V_abs\": \"-V_abs/tau_m + (I_e + I_stim)/C_m\",\n", + " \"tr_o1__for_stdp_triplet_nn1_nestml\": \"-tr_o1__for_stdp_triplet_nn1_nestml/tau_minus__for_stdp_triplet_nn1_nestml\",\n", + " \"tr_o2__for_stdp_triplet_nn1_nestml\": \"-tr_o2__for_stdp_triplet_nn1_nestml/tau_y__for_stdp_triplet_nn1_nestml\"\n", + " }\n", + " }\n", + "]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[81,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [58:0;131:0]]: Start building symbol table!\n", + "[82,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, WARNING, [88:4;88:22]]: Variable 'h' has the same name as a physical unit!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:ode-toolbox: analysing input:\n", + "INFO:{\n", + " \"dynamics\": [\n", + " {\n", + " \"expression\": \"tr_r1' = -tr_r1 / tau_plus\",\n", + " \"initial_values\": {\n", + " \"tr_r1\": \"0.000000E+00\"\n", + " }\n", + " },\n", + " {\n", + " \"expression\": \"tr_r2' = -tr_r2 / tau_x\",\n", + " \"initial_values\": {\n", + " \"tr_r2\": \"0.000000E+00\"\n", + " }\n", + " }\n", + " ],\n", + " \"options\": {\n", + " \"output_timestep_symbol\": \"__h\"\n", + " },\n", + " \"parameters\": {\n", + " \"A2_minus\": \"7.000000E-03\",\n", + " \"A2_plus\": \"7.500000E-10\",\n", + " \"A3_minus\": \"2.300000E-04\",\n", + " \"A3_plus\": \"9.300000E-03\",\n", + " \"Wmax\": \"100\",\n", + " \"Wmin\": \"0\",\n", + " \"tau_plus\": \"1.680000E+01\",\n", + " \"tau_x\": \"101\",\n", + " \"the_delay\": \"1\"\n", + " }\n", + "}\n", + "INFO:Processing global options...\n", + "INFO:Processing input shapes...\n", + "INFO:\n", + "Processing shape tr_r1 with defining expression = \"-tr_r1 / tau_plus\"\n", + "INFO:\n", + "Processing shape tr_r2 with defining expression = \"-tr_r2 / tau_x\"\n", + "INFO:\n", + "Processing shape tr_r1 with defining expression = \"-tr_r1 / tau_plus\"\n", + "INFO:\n", + "Processing shape tr_r2 with defining expression = \"-tr_r2 / tau_x\"\n", + "INFO:Shape tr_r1: reconstituting expression -tr_r1/tau_plus\n", + "INFO:Shape tr_r2: reconstituting expression -tr_r2/tau_x\n", + "INFO:Dependency analysis...\n", + "INFO:Generating propagators for the following symbols: tr_r1, tr_r2\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Analysing/transforming synapse stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml.\n", + "[83,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: Starts processing of the model 'stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml'\n", + "[84,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: The neuron 'stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml' will be analysed!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:In ode-toolbox: returning outdict = \n", + "INFO:[\n", + " {\n", + " \"initial_values\": {\n", + " \"tr_r1\": \"0.0\",\n", + " \"tr_r2\": \"0.0\"\n", + " },\n", + " \"parameters\": {\n", + " \"tau_plus\": \"16.8000000000000\",\n", + " \"tau_x\": \"101.000000000000\"\n", + " },\n", + " \"propagators\": {\n", + " \"__P__tr_r1__tr_r1\": \"exp(-__h/tau_plus)\",\n", + " \"__P__tr_r2__tr_r2\": \"exp(-__h/tau_x)\"\n", + " },\n", + " \"solver\": \"analytical\",\n", + " \"state_variables\": [\n", + " \"tr_r1\",\n", + " \"tr_r2\"\n", + " ],\n", + " \"update_expressions\": {\n", + " \"tr_r1\": \"__P__tr_r1__tr_r1*tr_r1\",\n", + " \"tr_r2\": \"__P__tr_r2__tr_r2*tr_r2\"\n", + " }\n", + " }\n", + "]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[85,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: Start building symbol table!\n", + "[86,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [66:18;66:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[87,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [57:12;57:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[88,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [58:12;58:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[89,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: Start building symbol table!\n", + "[90,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [66:18;66:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[91,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [57:12;57:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[92,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [58:12;58:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[93,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: Start building symbol table!\n", + "[94,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [66:18;66:18]]: Implicit casting from (compatible) type 'nS' to 'real'.\n", + "[95,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [57:12;57:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[96,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [58:12;58:12]]: Implicit casting from (compatible) type 'integer' to 'real'.\n", + "[97,iaf_psc_delta1_nestml, INFO, [58:0;131:0]]: Successfully generated code for the model: 'iaf_psc_delta1_nestml' in: '/tmp/nestml_module' !\n", + "[98,iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml, INFO, [58:0;131:0]]: Successfully generated code for the model: 'iaf_psc_delta1_nestml__with_stdp_triplet_nn1_nestml' in: '/tmp/nestml_module' !\n", + "Generating code for the synapse stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml.\n", + "[99,stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml, INFO, [2:0;69:0]]: Successfully generated code for the model: 'stdp_triplet_nn1_nestml__with_iaf_psc_delta1_nestml' in: '/tmp/nestml_module' !\n", + "[100,GLOBAL, INFO]: Successfully generated NEST module code in '/tmp/nestml_module' !\n" + ] + } + ], + "source": [ + "# Generate code for nearest spike interaction model\n", + "neuron_model_name_nn, synapse_model_name_nn, nestml_synapse_model_name_nn = \\\n", + "generate_code_for(nestml_triplet_stdp_nn_model)" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAJqCAYAAADXOGGHAAAgAElEQVR4AeydBbhdxdWGkUBwhzRoKAkSICEEAkmQFlrci7sXKUWSQIBS+HGX4lagUCgUGqQ4FAsECe4SHAIEl3o7//Ou8h1WNsfukXvPPXvN85wzs0fWzHwze+bba2bPniKFCQQCgUAgg8B///vf9J///Md8H3/88TT11FOn+eefP40dO9b8/v3vf0+WgvgY0vzzn/+cLKzUhdIonOt//etfugw7EAgEAoGaEZii5pSRMBAIBNoegU8++STtscceaYoppkhTTjllGjBgQLrvvvus3iI4kBK5CRApqgYc0kKG9KsmTcQJBAKBQKASAkFuKiEU4YFAjhEYN25cWmaZZVL//v2N4Ew77bRp3333NUT+8Y9/TEZqaoXp1ltvTYssskhaY4010ptvvmliQoNTK5qRLhAIBEAgyE30g0AgECiKwLPPPptWX331dM4556SXX37ZCAganNlmm838SITGRctL2NVqbaTpeeutt9LQoUONOKEV+vTTT01etXKKFjw8A4FAIPcIBLnJfRcIAAKB4ghcccUVRmjef/99i/Dggw+mGWaYIfXo0SMNHz7ciA0kxZObajUuSvPee++ZxqZnz57p/PPPt3y+/PLLgsziJQvfQCAQCATKIxDkpjw+ERoI5AoBkY7PPvssXXDBBen2228v1P+1115LvXv3Ni3LwIEDE2QHA8GRJqajGheWveacc87Uq1evdNNNNxXkFTINRyAQCAQCNSAQ5KYG0CJJINBuCEBK/v73v1u1/va3v6Vf//rXaZ111rFrvf309ddfpwMOOMDIDctTQ4YMSe+8845pWbQkpbi6Fk7+WgQK++yzzzZ5W265ZSJfyqFwpQ07EAgEAoGOIhDkpqOIRfxAoA0Q8GQDQiLNC1V75plnbB/M4YcfbjX95ptvzCYNYeuvv36aY4450owzzpjOOOMMC4OYyEBQpMHxpIkNyGh7Lr/88nTDDTek66+/Pu28885GbjbccMP0wAMPJJbC0OAQFxNER6iGHQgEAh1BIMhNR9CKuIFAmyAAafBaFpGbd999N6211lppv/32s5pKm6NwPCdMmJBWXXVVIyVobz7++GOLy34bkRzia/+NCMqkSZMSGpqppprKlqLYmDz99NOnmWaayX5cs/eGjcUvvPCCyRRJ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AkyuImvDuC++uFuAkJBAIMDCLrrAIosv+sMu7r4QYNnFneABggV3C0GCu6zg7gnEiDuThPM/7+n5OpVL93jPdPecmudO3VteX9W99fWpU1X97fleveyVyy+1u484xE7svq7ttcpK1q8n0zU1NnUSJOoXGz90mD15/Y22z1qd7JA1VrdjO65pR6+xuu255FJ28e772tTh43wlECPl+HGj7d5rrraDOnS0KzfaxK7r2tnu2mg9691lLevZeS27/k/bW803A23amLG+fJr9YcYPH2H9b7ndDuqyrl2wQXe7fJ3OdnGnVeySjde1/hei5wJp4IBG9nOZYjXffW8Drr3VRp13tY068zIbfWUfm/j6R36C89ThY325spf/59ot+JFijB5vU4ZCWDjhebjrsLjeCidNiyg64cut/vaDE8dN9Hx/mYxkB1KTS4++RdDc0F8biXaY4dIUj8IlL5kiO/tQODnKzv0AgODgguEHQY50QIRrCbmCu11LcH0VWi4W/wmZu6S6nfOrTTaXttcnDf3rMGn4uA8EAoHyRyDITYnaKEdulrTZIDdbbep7faJL4HP/037xvUSGDfjBzjr8MDui65p23nod7bKuHeyyddaw07qsYa/0vMTF9VMnjvcpkZopU23IgIF21iGHWo+NutvF63exS9dZwy7psqZduM669sX1N+dO753AzqVTbdywQfbE9T3t8HXXtPPW7WzXd1vXbuy6rl3caW27ab99bdroUb5EduqkcU5wfh49wh6+qqf9be2OduGG69uV63W1izp1sH90Ws2u3X8vmzryJ98EjV/l6E9MHjXKHrvuWtu/4xp28UYb2WXd17ee229rtxx3hI3+5P3cr/kJE3zd9NBvB9gVp5xmh67Tzc7qvp5dsX5n69m1g5231sp20eYb2cg3X8lJc9hO35fX1tjnb7xmJ/7+93behhtazw27Wc9une38zqtar522scmffGLTxk82l1D8Yjb0h4F22kF/tUO7drSLN17feq67tl3atZOdsc7a9vylF9kvkyZYzfixvocMI92QgYPs/ONPtP07dbR/dF/Hzt+wi52x9mp26jqd7M2rr/J0nST+8otNHDbM+l19rR3RrZv13m1n67Xtlnb7rjvbDTvvYg8df6rVfDvYt8+HCE0aP9b++2Q/u2Xfv9qjO+1ur+y6i722/Z/sua22sKf+tL29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" + } + }, + "cell_type": "markdown", + "id": "expensive-snapshot", + "metadata": {}, + "source": [ + "## Results \n", + "\n", + "### Spike pairing protocol\n", + "\n", + "If we set the values of $A_3^+$ and $A_3^-$ to 0 in the above equations, the model becomes a classical STDP model. The authors in [4] tested this model to check if they could reproduce the experimental results of [2] and [3]. They tested this with a pairing protocol which is a classic STDP protocol where the pairs of presynaptic and postsynaptic spikes shifted by $\\Delta{t}$ are repeated at regular intervals of $(1/\\rho)$. They showed that spike pairs repeated at high frequencies did not have considerable effect on the synaptic weights as shown by the experimental data.\n", + "\n", + "\n", + "
\n", + "\n", + "
\n" + ] + }, + { + "cell_type": "markdown", + "id": "secure-north", + "metadata": {}, + "source": [ + "### Triplet STDP model with spike pairs\n", + "\n", + "Let us simulate the pairing protocol in the above formulated model to see if we can reproduce the frequency dependence of spikes on the synaptic weights." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "conscious-trailer", + "metadata": {}, + "outputs": [], + "source": [ + "# Create pre and post spike arrays\n", + "def create_spike_pairs(freq=1., delta_t=0., size=10):\n", + " \"\"\"\n", + " Creates the spike pairs given the frequency and the time difference between the pre and post spikes.\n", + " :param: freq: frequency of the spike pairs\n", + " :param: delta_t: time difference or delay between the spikes\n", + " :param: size: number of spike pairs to be generated.\n", + " :return: pre and post spike arrays\n", + " \"\"\"\n", + " pre_spike_times = 1 + abs(delta_t) + freq * np.arange(size).astype(float)\n", + " post_spike_times = 1 + abs(delta_t) + delta_t + freq * np.arange(size).astype(float)\n", + " \n", + " return pre_spike_times, post_spike_times" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "similar-command", + "metadata": {}, + "outputs": [], + "source": [ + "def run_triplet_stdp_network(neuron_model_name, synapse_model_name, neuron_opts,\n", + " nest_syn_opts, pre_spike_times, post_spike_times, \n", + " resolution=1., delay=1., sim_time=None):\n", + " \"\"\"\n", + " Runs the triplet stdp synapse model\n", + " \"\"\"\n", + " nest.set_verbosity(\"M_ALL\")\n", + " nest.ResetKernel()\n", + " nest.SetKernelStatus({'resolution': resolution})\n", + " \n", + " # Set defaults for neuron\n", + " nest.SetDefaults(neuron_model_name, neuron_opts)\n", + "\n", + " # Create neurons\n", + " neurons = nest.Create(neuron_model_name, 2)\n", + "\n", + " pre_sg = nest.Create('spike_generator', params={'spike_times': pre_spike_times})\n", + " post_sg = nest.Create('spike_generator', params={'spike_times': post_spike_times})\n", + "\n", + " spikes = nest.Create('spike_recorder')\n", + " weight_recorder = nest.Create('weight_recorder')\n", + "\n", + " # Set defaults for synapse\n", + " nest.CopyModel('static_synapse',\n", + " 'excitatory_noise',\n", + " {'weight': 9999.,\n", + " 'delay' : syn_opts[\"delay\"]})\n", + "\n", + " _syn_opts = nest_syn_opts.copy()\n", + " _syn_opts.pop('delay')\n", + "\n", + " nest.CopyModel(synapse_model_name,\n", + " synapse_model_name + \"_rec\",\n", + " {'weight_recorder' : weight_recorder[0]})\n", + " nest.SetDefaults(synapse_model_name + \"_rec\", _syn_opts)\n", + "\n", + " # Connect nodes\n", + " nest.Connect(neurons[0], neurons[1], syn_spec={'synapse_model': synapse_model_name + \"_rec\"})\n", + " nest.Connect(pre_sg, neurons[0], syn_spec='excitatory_noise')\n", + " nest.Connect(post_sg, neurons[1], syn_spec='excitatory_noise')\n", + " nest.Connect(neurons, spikes)\n", + " \n", + " # Run simulation\n", + " syn = nest.GetConnections(source=neurons[0], synapse_model=synapse_model_name + \"_rec\")\n", + " initial_weight = nest.GetStatus(syn)[0]['w']\n", + " \n", + " nest.Simulate(sim_time)\n", + " \n", + " updated_weight = nest.GetStatus(syn)[0]['w']\n", + " dw = updated_weight - initial_weight\n", + " print('Initial weight: {}, Updated weight: {}'.format(initial_weight, updated_weight))\n", + "\n", + " connections = nest.GetConnections(neurons, neurons)\n", + " gid_pre = nest.GetStatus(connections,'source')[0]\n", + " gid_post = nest.GetStatus(connections,'target')[0]\n", + "\n", + " # From the spike recorder\n", + " events = nest.GetStatus(spikes, 'events')[0]\n", + " times_spikes = np.array(events['times'])\n", + " senders_spikes = events['senders']\n", + " # print('times_spikes: ', times_spikes)\n", + " # print('senders_spikes: ', senders_spikes)\n", + "\n", + " # From the weight recorder\n", + " events = nest.GetStatus(weight_recorder, 'events')[0]\n", + " times_weights = events['times']\n", + " weights = events['weights']\n", + " # print('times_weights: ', times_weights)\n", + " # print('weights: ', weights)\n", + " \n", + " return dw" + ] + }, + { + "cell_type": "markdown", + "id": "cosmetic-rachel", + "metadata": {}, + "source": [ + "### Simulation" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "passing-character", + "metadata": {}, + "outputs": [], + "source": [ + "# Simulate the network\n", + "def run_frequency_simulation(neuron_model_name, synapse_model_name,\n", + " neuron_opts, nest_syn_opts,\n", + " freqs, delta_t, n_spikes):\n", + " \"\"\"\n", + " Runs the spike pair simulation for given frequencies and given time difference between spikes.\n", + " \"\"\"\n", + " dw_dict = dict.fromkeys(delta_t)\n", + " for _t in delta_t:\n", + " dw_vec = []\n", + " for _freq in freqs:\n", + " spike_interval = (1/_freq)*1000 # in ms\n", + "\n", + " pre_spike_times, post_spike_times = create_spike_pairs(freq=spike_interval,\n", + " delta_t=_t,\n", + " size=n_spikes)\n", + "\n", + " sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 10. + 3 * syn_opts[\"delay\"]\n", + "\n", + " dw = run_triplet_stdp_network(neuron_model_name, synapse_model_name, \n", + " neuron_opts, nest_syn_opts,\n", + " pre_spike_times=pre_spike_times,\n", + " post_spike_times=post_spike_times,\n", + " sim_time=sim_time)\n", + " dw_vec.append(dw)\n", + "\n", + " dw_dict[_t] = dw_vec\n", + " \n", + " return dw_dict" + ] + }, + { + "cell_type": "markdown", + "id": "respective-police", + "metadata": {}, + "source": [ + "### All-to-all spike interaction" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "active-pipeline", + "metadata": {}, + "outputs": [], + "source": [ + "freqs = [1., 5., 10., 20., 40., 50.] # frequency of spikes in Hz\n", + "delta_t = [10, -10] # delay between t_post and t_pre in ms\n", + "n_spikes = 60" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "psychological-reflection", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial weight: 1.0, Updated weight: 1.0032840201153659\n", + "Initial weight: 1.0, Updated weight: 1.0487030313494627\n", + "Initial weight: 1.0, Updated weight: 1.1212921010110624\n", + "Initial weight: 1.0, Updated weight: 1.208550316936044\n", + "Initial weight: 1.0, Updated weight: 1.4218868273243082\n", + "Initial weight: 1.0, Updated weight: 1.5846034621613552\n", + "Initial weight: 1.0, Updated weight: 0.6678711978627694\n", + "Initial weight: 1.0, Updated weight: 0.6653426131462727\n", + "Initial weight: 1.0, Updated weight: 0.6450780469148971\n", + "Initial weight: 1.0, Updated weight: 0.6180411107607721\n", + "Initial weight: 1.0, Updated weight: 1.068737821702289\n", + "Initial weight: 1.0, Updated weight: 1.5937453662768748\n" + ] + } + ], + "source": [ + "syn_opts = {\n", + " 'delay': 1.,\n", + " 'tau_minus': 33.7,\n", + " 'tau_plus': 16.8,\n", + " 'tau_x': 101.,\n", + " 'tau_y': 125.,\n", + " 'A2_plus': 5e-10,\n", + " 'A3_plus': 6.2e-3,\n", + " 'A2_minus': 7e-3,\n", + " 'A3_minus': 2.3e-4,\n", + " 'Wmax': 50.,\n", + " 'Wmin' : 0.,\n", + " 'w': 1.\n", + "}\n", + "\n", + "synapse_suffix = neuron_model_name[neuron_model_name.find(nestml_synapse_model_name):]\n", + "neuron_opts = {'tau_minus__for_' + synapse_suffix: syn_opts['tau_minus'],\n", + " 'tau_y__for_' + synapse_suffix: syn_opts['tau_y']}\n", + "\n", + "nest_syn_opts = syn_opts.copy()\n", + "nest_syn_opts.pop('tau_minus')\n", + "nest_syn_opts.pop('tau_y')\n", + "\n", + "dw_dict = run_frequency_simulation(neuron_model_name, synapse_model_name, \n", + " neuron_opts, nest_syn_opts,\n", + " freqs, delta_t, n_spikes)" + ] + }, + { + "cell_type": "markdown", + "id": "piano-limit", + "metadata": {}, + "source": [ + "### Nearest spike interaction" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "inclusive-galaxy", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial weight: 1.0, Updated weight: 1.027536987681302\n", + "Initial weight: 1.0, Updated weight: 1.0361996900270407\n", + "Initial weight: 1.0, Updated weight: 1.1178373501754864\n", + "Initial weight: 1.0, Updated weight: 1.3052281386777107\n", + "Initial weight: 1.0, Updated weight: 1.5046769960859652\n", + "Initial weight: 1.0, Updated weight: 1.5580870819162018\n", + "Initial weight: 1.0, Updated weight: 0.554406040254968\n", + "Initial weight: 1.0, Updated weight: 0.5544062835543123\n", + "Initial weight: 1.0, Updated weight: 0.5555461935366892\n", + "Initial weight: 1.0, Updated weight: 0.632456315445355\n", + "Initial weight: 1.0, Updated weight: 1.2001792723059206\n", + "Initial weight: 1.0, Updated weight: 1.5398255566140917\n" + ] + } + ], + "source": [ + "syn_opts_nn = {\n", + " 'delay': 1.,\n", + " 'tau_minus': 33.7,\n", + " 'tau_plus': 16.8,\n", + " 'tau_x': 714.,\n", + " 'tau_y': 40.,\n", + " 'A2_plus': 8.8e-11,\n", + " 'A3_plus': 5.3e-2,\n", + " 'A2_minus': 6.6e-3,\n", + " 'A3_minus': 3.1e-3,\n", + " 'Wmax': 50.,\n", + " 'Wmin' : 0.,\n", + " 'w': 1.\n", + "}\n", + "\n", + "synapse_suffix_nn = neuron_model_name_nn[neuron_model_name_nn.find(nestml_synapse_model_name_nn):]\n", + "neuron_opts_nn = {'tau_minus__for_' + synapse_suffix_nn: syn_opts_nn['tau_minus'],\n", + " 'tau_y__for_' + synapse_suffix_nn: syn_opts_nn['tau_y']}\n", + "\n", + "nest_syn_opts_nn = syn_opts_nn.copy()\n", + "nest_syn_opts_nn.pop('tau_minus')\n", + "nest_syn_opts_nn.pop('tau_y')\n", + "\n", + "dw_dict_nn = run_frequency_simulation(neuron_model_name_nn, synapse_model_name_nn,\n", + " neuron_opts_nn, nest_syn_opts_nn,\n", + " freqs, delta_t, n_spikes)" + ] + }, + { + "cell_type": "markdown", + "id": "successful-capitol", + "metadata": {}, + "source": [ + "### Plot: Weight change as a function of frequency" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "biological-drunk", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEKCAYAAAAB0GKPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABISUlEQVR4nO2deZxN5R/H3w/GDLLvGUJIlrENRWRfQhQS0aq0KUoopIjol7RIok2ppsUuWxShJEt22cmQbezbmOX5/fG9d2Yww52Ze+feO/f7fr3Oa+4959xznjNz53zO812NtRZFURRFuR5ZvD0ARVEUxT9QwVAURVFcQgVDURRFcQkVDEVRFMUlVDAURVEUl8jm7QF4ikKFCtnSpUt7exiKoih+xZo1a45Zawsnty3TCkbp0qVZvXq1t4ehKIriVxhj9qW0TU1SiqIoikuoYCiKoiguoYKhKIqiuESm9WEkR0xMDJGRkVy8eNHbQ1GuICQkhNDQUIKCgrw9FEVRUsAnBMMY0wp4H8gKfGqtHZXMPp2B1wELrLfWPpDa80RGRpI7d25Kly6NMSado1bchbWWqKgoIiMjKVOmjLeHoyhKCnhdMIwxWYFxQHMgElhljJllrd2SZJ/ywCvAHdbaE8aYImk518WLF1UsfBBjDAULFuTo0aPeHoqiKNfAF3wYdYCd1trd1tpLwHdA+yv2eQIYZ609AWCtPZLWk6lY+Cb6d1EU38cXBKMEsD/J+0jHuqRUACoYY343xvzpMGFdhTGmpzFmtTFmtT6tKooSiERHe+7YviAYrpANKA80AroCnxhj8l25k7V2orU23FobXrhwsomKXscYQ9++fRPejx49mtdffz3Dx3Hy5Ek++ugjtxzr448/5quvvgKgUaNGmjCpKF7iyBG4+Wb47jvPHN8XBOMAUDLJ+1DHuqREArOstTHW2j3AdkRA/I7g4GCmTZvGsWPH3Hrc2NjYVO3vTsF46qmneOihh9xyLEVR0s5TT8F//8HUqZ45vi8IxiqgvDGmjDEmO9AFmHXFPjOQ2QXGmEKIiWp3Bo7RbWTLlo2ePXvy7rvvXrXt6NGjdOzYkdq1a1O7dm1+//13AP766y/q1q1LjRo1qFevHtu2bQNg0qRJtGvXjiZNmtC0aVPOnTvHY489Rp06dahRowYzZ84EYPPmzdSpU4fq1asTFhbGjh07ePnll9m1axfVq1enX79+l43j3LlztGnThmrVqlGlShW+//57QMqt9O/fn6pVq1KnTh127twJwOuvv87o0aMvO0Z8fDyPPPIIgwcPJi4ujn79+lG7dm3CwsKYMGGCe3+pihLg7NsHbdvC9Onyvlgx8EQzVa9HSVlrY40xvYAFSFjt59bazcaYYcBqa+0sx7YWxpgtQBzQz1obla4T9+kD69al6xBXUb06vPfedXd79tlnCQsLo3///pet7927Ny+88AL169fn33//pWXLlmzdupWKFSuybNkysmXLxqJFixg4cCBTHY8Qa9euZcOGDRQoUICBAwfSpEkTPv/8c06ePEmdOnVo1qwZH3/8Mb1796Zbt25cunSJuLg4Ro0axaZNm1iXzO9g/vz53HjjjcyZMweAU6dOJWzLmzcvGzdu5KuvvqJPnz789NNPV30+NjaWbt26UaVKFQYNGsTEiRPJmzcvq1atIjo6mjvuuIMWLVpoCK2ipJO9e+HNN+HzzyEuDvLkgdWrobyH7C9eFwwAa+1cYO4V64YkeW2BFx2L35MnTx4eeughPvjgA3LkyJGwftGiRWzZkhBNzOnTpzl79iynTp3i4YcfZseOHRhjiImJSdinefPmFChQAICff/6ZWbNmJTztX7x4kX///Ze6desyYsQIIiMj6dChA+Wv822qWrUqffv2ZcCAAbRt25YGDRokbOvatWvCzxdeeCHZzz/55JN07tyZQYMGJYxrw4YNTJkyBRAB2rFjhwqGoqSRPXtEKCZNgixZ4N574eefYcoUz4kF+IhgeAUXZgKepE+fPtSsWZNHH300YV18fDx//vknISEhl+3bq1cvGjduzPTp09m7dy+NGjVK2JYrV66E19Zapk6dyi233HLZ52+99VZuu+025syZQ+vWrZkwYQJly5ZNcWwVKlRg7dq1zJ07l8GDB9O0aVOGDBH9Thr+mlIobL169Vi8eDF9+/YlJCQEay1jx46lZcuW1//FKIqSInv2wIgR8OWXIhRPPgkvvwyhoXDqFOTN69nz+4IPIyApUKAAnTt35rPPPktY16JFC8aOHZvw3mkuOnXqFCVKSKTxpEmTUjxmy5YtGTt2LNZhvPz7778B2L17N2XLluX555+nffv2bNiwgdy5c3PmzJlkj3Pw4EFy5sxJ9+7d6devH2vXrk3Y5vRnfP/999StWzfZz/fo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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "fig, axes = plt.subplots()\n", + "ls1 = axes.plot(freqs, dw_dict_nn[delta_t[0]], color='r')\n", + "ls2 = axes.plot(freqs, dw_dict_nn[delta_t[1]], linestyle='--', color='r')\n", + "axes.plot(freqs, dw_dict[delta_t[0]], color='b')\n", + "axes.plot(freqs, dw_dict[delta_t[1]], linestyle='--', color='b')\n", + "\n", + "axes.set_xlabel(r'${\\rho}(Hz)$')\n", + "axes.set_ylabel(r'${\\Delta}w$')\n", + "\n", + "lines = axes.get_lines()\n", + "legend = plt.legend([lines[i] for i in [0,2]], ['Nearest spike', 'All-to-all'])\n", + "legend2 = plt.legend([ls1[0], ls2[0]], [r'${\\Delta}t = 10ms$', r'${\\Delta}t = -10ms$'], loc = 4)\n", + "axes.add_artist(legend)" + ] + }, + { + "cell_type": "markdown", + "id": "interior-parliament", + "metadata": {}, + "source": [ + "### Triplet protocol\n", + "\n", + "In the first triplet protocol, each triplet consists of two presynaptic spikes and one postsynaptic spike separated by $\\Delta{t_1} = t^{post} - t_1^{pre}$ and $\\Delta{t_2} = t^{post} - t_2^{pre}$ where $t_1^{pre}$ and $t_2^{pre}$ are the presynaptic spikes of the triplet. \n", + "\n", + "The second triplet protocol is similar to the first with the difference that it contains two postsynaptic spikes and one presynaptic spike. In this case, $\\Delta{t_1} = t_1^{post} - t^{pre}$ and $\\Delta{t_2} = t_2^{post} - t^{pre}$." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "adequate-diesel", + "metadata": {}, + "outputs": [], + "source": [ + "def create_triplet_spikes(_delays, n, trip_delay=1):\n", + " _dt1 = abs(_delays[0])\n", + " _dt2 = abs(_delays[1])\n", + " _interval = _dt1 + _dt2\n", + " \n", + " # pre_spikes\n", + " start = 1\n", + " stop = 0\n", + " pre_spike_times = []\n", + " for i in range(n):\n", + " start = stop + 1 if i == 0 else stop + trip_delay\n", + " stop = start + _interval\n", + " pre_spike_times = np.hstack([pre_spike_times, [start, stop]])\n", + " \n", + " # post_spikes\n", + " start = 1 + _dt1\n", + " step = _interval + trip_delay\n", + " stop = start + n * step\n", + " post_spike_times = np.arange(start, stop, step).astype(float)\n", + " \n", + " return pre_spike_times, post_spike_times" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "certified-bubble", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "pre_spike_times, post_spike_times = create_triplet_spikes((5, -5), 2, 10)\n", + "l = []\n", + "l.append(post_spike_times)\n", + "l.append(pre_spike_times)\n", + "colors1 = ['C{}'.format(i) for i in range(2)]\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 3))\n", + "ax1.eventplot(l, colors=colors1)\n", + "ax1.legend(['post', 'pre'])\n", + "\n", + "l = []\n", + "l.append(pre_spike_times)\n", + "l.append(post_spike_times)\n", + "ax2.eventplot(l, colors=colors1)\n", + "ax2.legend(['post', 'pre'])\n", + "plt.tight_layout()" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABFAAAAKbCAYAAADSeH5xAAAgAElEQVR4AeydBdgd1dW2izUQoMFdQ3AP7gRLS5Hi7hIoFC3a4u7uElyKtbgUilsCBAlBQnDXBPj0/779X/dqn/PtTM7rx99nX9ecmdmz9Z59Zq1Zs+UXyc4ETMAETMAETMAETMAETMAETMAETMAETKAsgX/733Hpk/95K/2i7FV7moAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJJBtQ3AhMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETMAETMAETMAGFLcBEzABEzABEzABEzABEzABEzABEzABE+iAgA0oHQDyZRMwARMwARMwARMwARMwARMwARMwAROwAcVtwARMwARMwARMwARMwARMwARMwARMwAQ6IGADSgeAfNkETMAETMAETMAETMAETMAETMAETMAEbEBxGzABEzABEzABEzABEzABEzABEzABEzCBDgjYgNIBIF82ARMwARMwARMwARMwARMwARMwARMwARtQ3AZMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETMAETMAETMAGFLcBEzABEzABEzABEzABEzABEzABEzABE+iAgA0oHQDyZRMwARMwARMwARMwARMwARMwARMwAROwAcVtwARMwARMwARMwARMwARMwARMwARMwAQ6IGADSgeAfNkETMAETMAETMAETMAETMAETMAETMAEbEBxGzABEzABEzABEzABEzABEzABEzABEzCBDgjYgNIBIF82ARMwARMwARMwARMwARMwARMwARMwARtQ3AZMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETMAETMAETMAGFLcBEzABEzABEzABEzABEzABEzABEzABE+iAgA0oHQDyZRMwARMwARMwARMwARMwARMwARMwAROwAcVtwARMwARMwARMwARMwARMwARMwARMwAQ6IGADSgeAfNkETMAETMAETMAETMAETMAETMAETMAEbEBxGzABEzABEzABEzABEzABEzABEzABEzCBDgjYgNIBIF82ARMwARMwARMwARMwARMwARMwARMwARtQ3AZMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETMAETMAETMAGFLcBEzABEzABEzABEzABEzABEzABEzABE+iAgA0oHQDyZRMwARMwARMwARMwARMwARMwARMwAROwAcVtwARMwARMwARMwARMwARMwARMwARMwAQ6IGADSgeAfNkETMAETMAETMAETMAETMAETMAETMAEbEBxGzABEzABEzABEzABEzABEzABEzABEzCBDgjYgNIBIF82ARMwARMwARMwARMwARMwARMwARMwARtQ3AZMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETMAETMAETMAGFLcBEzABEzABEzABEzABEzABEzABEzABE+iAgA0oHQDyZRMwARMwARMwARMwARMwARMwARMwAROwAcVtwARMwARMwARMwARMwARMwARMwARMwAQ6IGADSgeAfNkETMAETMAETMAETMAETMAETMAETMAEbEBxGzABEzABEzABEzABEzABEzABEzABEzCBDgjYgNIBIF82ARMwARMwARMwARMwARMwARMwARMwARtQ3AZMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETMAETMAETMAGFLcBEzABEzABEzABEzABEzABEzABEzABE+iAgA0oHQDyZRMwARMwARMwARMwARMwARMwARMwAROwAcVtwARMwARMwARMwARMwARMwARMwARMwAQ6IGADSgeAfNkETMAETMAETMAETMAETMAETMAETMAEbEBxGzABEzABEzABEzABEzABEzABEzABEzCBDgjYgNIBIF82ARMwARMwARMwARMwARMwARMwARMwARtQ3AZMwARMwARMwARMwARMwARMwARMwARMoAMCNqB0AMiXTcAETMAETMAETMAETMAETOD//b//FxDY/+///m9pw/O///u/45xjhfuv//qvkl9n6Sltwufxya/Wjjz/53/+Z7y6qZ74507+uV/xWFzwz+uj42KahMsZFNPzuQnUg4ANKPWg7jxNwARMwARMwARMwARMwASajkBu4MBogLvlllvS6NGjx6uLjAUYBWQgGC9AmZM83L/927+VDDGdMU6USa7bXv/5n/8ZZS4aNL7//vuo69/+9rf0H//xH2Hc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nYerHrBNVTkXtiEIqO188803afPNN0+/+93volxM7iclV8K6IQrsQpiACZiACbQMAfQYfQy66aab0myzzRa6Dh+LxowZE/WUnFKlmRPCckk0qr8X65deeimdfPLJiSFXuOJ9qX5JelcO8IU9K/DMMsss6eKLLy71EFaPoN5FxLWtFwEbUOpF3vn2mAAz02NAmWiiidIaa6wRD1S94PY4cSfQ6wkgpJkcjg2H4EaxxZBiZwImYAImYALVIiB5M3bs2MQcKOg6G2ywQfrkk08iS31M4qURvUdOH5F07n31COgesRIPPVHsakMA7jjmP/z222/jWH61KYFzMYGUbEBxK2haAligt99++1Aspp122nTnnXdGXX7++eemrZML3ngEEMwoqGxSTqW8Nl5pXSITMAETMIFmJqAXc+rw7rvvpqWWWir0nEUXXTQ988wzE1RNBhT2fpGcAE9VPXIDlvSDqmboxEv6GCjU9jlmOE9+blQmUE0CNqBUk67TrjqBe++9N+ZCYUnjtdZaK/JT18qqZ+4MWpYAilDe00SKKcqp21fL3nZXzARMwATqTkAv5QzLwZ100kmpX79+YUQ55phjQgYhiwhXdPjbiFKkUtlzdIAiZzHXtcrm6NSKBIr8pZf541aRlM+rRcAGlGqRdbo1IcDkXXRrpXvrwIEDo3srD1Y9TGtSCGfSkgQQxO+991565513on6cSzj7K0dL3nJXygRMwAQahoDkDPNs0PsEPQdDyjXXXFMqo17ciy+UpQA+qAoBcafXA0N48g8uVcnQiZYIaLjU888/n3766adSz+BSAB+YQA0I2IBSA8jOoroEGLqDYjH11FOnQw89NDIr92WmuqVw6q1CQIrRp59+GhPIbrHFFlE1FCU7EzABEzABE6g2AV7I+RAko/0DDzyQFltssdB1GNIzYsSIKILkFScyuFS7bE7//1g/9thj6fTTTy9NIms21SVAe6ed//DDD2mGGWZIl112WanHla5VtwRO3QT+ScAGFLeEpiSQPyiffPLJxBwoGFFQMPJJP5uyci50QxBAeWUZY03aJ0UV4S2ltiEK6kKYgAmYgAm0JIFc3uy6666h5yy++OJp5MiRUV8MLZZHtb/16Afq6cy8ewy3ko5Q+9L0rhzVA4UewnCn/Yu97knvIuLa1oOADSj1oO48u0yAh6MekIqsc4TX3nvvHYpF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6EgxIMrynL///e+hs3z44chex+TJk8OP/ieffDJsPcv2s2iuYEz2iSeeCGWgJSCDosSjSfDQQw+FnVWwZ6GteamHjlhGZCFxOk6gZKyqJmM/Pv1mG7LpUTb4339piS1/b4ktn7HEls9mQ47/mD3+gyW2fMoSWz4dnW/1nCW2eiHyW79oCfxWz2c91/7XElv9Kes5Jk7+T1EZX/2dJTY+386+YK41JM3QiA2TTxiLZfs/7jOdtoZkYzDHlso0WjrVaFi810yAnpM+p/g5gxuDIo54cCMu7jRQKY1si8TTNHesQZP88TKUljiekQZZtYu4jjjq0T2QT89ex2pHPB114ImTsMJx/LwjbehLablHnBMofemp9a626luJt0rfM9+xvvd4On3fzFZqtyyWKohAiX/3pI2fx+shPv69x6/5sSPQ1xDQd9EagXJFHoHCuC8X6XCYNbKEN5O0J++9207eaUe7deIoe37yKHtl8kh7fVKRvT6p0F6fXGivTCqwlyeNCOFfJxXYq5MKg+c48iPs1RBfEPLMnVxoePK/lo3/66RCy/evTiqyv04qstdKx9gDo4baqplXWnLpMsvwA5n2xtrc2JgMmrTRXTB+03az0047PRAo6w9Z10477ce55bzcK32J+hWM1mNXjzEMR7zGNY6FKaHihRd9h8b+eF7yqXylRTZRXLwslZkfp3jyqQ3kV7yOFVKP0klew4YfxvPnz58fmkF7yY+P51Mb80PS4JgEYhdDdipkEweWKp988snB8D6EChNJ7IyIU/vCSd4/lYecpGNCZGsZ5P/Nb34TSBomN9nUAQcG+eUK9zhucazix3nN+NKp2uIEypeg8QhHoF8g0K8JlPgTgpGmc15nnXUCkcLSEI6vvPLKkEzCMCGsNWSL7JDAhMOMw2Br+1nO454lQjh+vL/wwgvBRkp8Zx0GhBNOOMHY9liOurSNcZxAwYDq1KlTQzINXsqjkHhUZesbzF586RP7n5v/abf9tt5uuanebv51vd30q3q78cas/2W93cj5r+rtevwv6+26G+vt+hvr7bobomPO5a+9od6u5fyX2fTK96umNNdcX2+zrqu3m26pt9/cUmGvzU1GWwiKW8gwo9IYZqSYj2JWqr6xPmijQJ40NkSzvfEBLH7MfebfO+cMYHFHno4Mavl543XomDL1A4hjtUvHuhYvK/84Xoau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" + } + }, + "cell_type": "markdown", + "id": "treated-jerusalem", + "metadata": {}, + "source": [ + "### STDP model with triplets\n", + "\n", + "The standard STDP model fails to reproduce the triplet experiments shown in [2] and [3]. The experments show a clear asymmetry between the pre-post-pre and post-pre-post protocols, but the standard STDP rule fails to reproduce it.\n", + "\n", + "\n", + "
\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "adult-observation", + "metadata": {}, + "source": [ + "### Triplet model with triplet protocol\n", + "\n", + "Let us try to formulate the two triplet protocols using the triplet model and check if we can reproduce the asymmetry in the change in weights." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "liquid-offset", + "metadata": {}, + "outputs": [], + "source": [ + "# Simulation\n", + "def run_triplet_protocol_simulation(neuron_model_name, synapse_model_name,\n", + " neuron_opts, nest_syn_opts,\n", + " spike_delays, n_triplets = 1, triplet_delay = 1000,\n", + " pre_post_pre=True):\n", + " dw_vec= []\n", + "\n", + " # For pre-post-pre triplets\n", + " for _delays in spike_delays:\n", + " pre_spike_times, post_spike_times = create_triplet_spikes(_delays, n_triplets, triplet_delay)\n", + " if not pre_post_pre: # swap the spike arrays\n", + " post_spike_times, pre_spike_times = pre_spike_times, post_spike_times\n", + "\n", + " sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 10. + 3 * syn_opts[\"delay\"]\n", + "\n", + " print('Simulating for (delta_t1, delta_t2) = ({}, {})'.format(_delays[0], _delays[1]))\n", + " dw = run_triplet_stdp_network(neuron_model_name, synapse_model_name,\n", + " neuron_opts, nest_syn_opts,\n", + " pre_spike_times=pre_spike_times,\n", + " post_spike_times=post_spike_times,\n", + " sim_time=sim_time)\n", + " dw_vec.append(dw)\n", + " \n", + " return dw_vec" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "moderate-surfing", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "27.0" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# All to all - Parameters are taken from [4]\n", + "syn_opts = {\n", + " 'delay': 1.,\n", + " 'tau_minus': 33.7,\n", + " 'tau_plus': 16.8,\n", + " 'tau_x': 946.,\n", + " 'tau_y': 27.,\n", + " 'A2_plus': 6.1e-3,\n", + " 'A3_plus': 6.7e-3,\n", + " 'A2_minus': 1.6e-3,\n", + " 'A3_minus': 1.4e-3,\n", + " 'Wmax': 50.,\n", + " 'Wmin' : 0.,\n", + " 'w': 1.\n", + "}\n", + "\n", + "synapse_suffix = neuron_model_name[neuron_model_name.find(nestml_synapse_model_name):]\n", + "neuron_opts_nn = {'tau_minus__for_' + synapse_suffix: syn_opts['tau_minus'],\n", + " 'tau_y__for_' + synapse_suffix: syn_opts['tau_y']}\n", + "\n", + "nest_syn_opts = syn_opts.copy()\n", + "nest_syn_opts.pop('tau_minus')\n", + "nest_syn_opts.pop('tau_y')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "revolutionary-coffee", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "47.0" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Nearest spike - Parameters are taken from [4]\n", + "syn_opts_nn = {\n", + " 'delay': 1.,\n", + " 'tau_minus': 33.7,\n", + " 'tau_plus': 16.8,\n", + " 'tau_x': 575.,\n", + " 'tau_y': 47.,\n", + " 'A2_plus': 4.6e-3,\n", + " 'A3_plus': 9.1e-3,\n", + " 'A2_minus': 3e-3,\n", + " 'A3_minus': 7.5e-9,\n", + " 'Wmax': 50.,\n", + " 'Wmin' : 0.,\n", + " 'w': 1.\n", + "}\n", + "\n", + "synapse_suffix_nn = neuron_model_name_nn[neuron_model_name_nn.find(nestml_synapse_model_name_nn):]\n", + "neuron_opts_nn = {'tau_minus__for_' + synapse_suffix_nn: syn_opts_nn['tau_minus'],\n", + " 'tau_y__for_' + synapse_suffix_nn: syn_opts_nn['tau_y']}\n", + "\n", + "nest_syn_opts_nn = syn_opts_nn.copy()\n", + "nest_syn_opts_nn.pop('tau_minus')\n", + "nest_syn_opts_nn.pop('tau_y')" + ] + }, + { + "cell_type": "markdown", + "id": "extra-minnesota", + "metadata": {}, + "source": [ + "### pre-post-pre triplet" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "close-seating", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simulating for (delta_t1, delta_t2) = (5, -5)\n", + "Initial weight: 1.0, Updated weight: 1.0050613336422116\n", + "Simulating for (delta_t1, delta_t2) = (10, -10)\n", + "Initial weight: 1.0, Updated weight: 1.0033041134126772\n", + "Simulating for (delta_t1, delta_t2) = (15, -5)\n", + "Initial weight: 1.0, Updated weight: 1.0010569740202522\n", + "Simulating for (delta_t1, delta_t2) = (5, -15)\n", + "Initial weight: 1.0, Updated weight: 1.0060708925921593\n", + "Simulating for (delta_t1, delta_t2) = (5, -5)\n", + "Initial weight: 1.0, Updated weight: 1.0069212695313912\n", + "Simulating for (delta_t1, delta_t2) = (10, -10)\n", + "Initial weight: 1.0, Updated weight: 1.0048211690063567\n", + "Simulating for (delta_t1, delta_t2) = (15, -5)\n", + "Initial weight: 1.0, Updated weight: 1.0026215076729108\n", + "Simulating for (delta_t1, delta_t2) = (5, -15)\n", + "Initial weight: 1.0, Updated weight: 1.0076053401541742\n" + ] + } + ], + "source": [ + "pre_post_pre_delays = [(5, -5), (10, -10), (15, -5), (5, -15)]\n", + "\n", + "# All-to-All interation\n", + "dw_vec = run_triplet_protocol_simulation(neuron_model_name, synapse_model_name,\n", + " neuron_opts, nest_syn_opts,\n", + " pre_post_pre_delays,\n", + " n_triplets=1,\n", + " triplet_delay=1000)\n", + "\n", + "# Nearest spike interaction\n", + "dw_vec_nn = run_triplet_protocol_simulation(neuron_model_name_nn, synapse_model_name_nn,\n", + " neuron_opts_nn, nest_syn_opts_nn,\n", + " pre_post_pre_delays,\n", + " n_triplets=1,\n", + " triplet_delay=1000)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "alpine-consultancy", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plot\n", + "bar_width = 0.25\n", + "fig, axes = plt.subplots()\n", + "br1 = np.arange(len(pre_post_pre_delays))\n", + "br2 = [x + bar_width for x in br1]\n", + "axes.bar(br1, dw_vec, width=bar_width, color='b')\n", + "axes.bar(br2, dw_vec_nn, width=bar_width, color='r')\n", + "axes.set_xticks([r + bar_width for r in range(len(br1))])\n", + "axes.set_xticklabels(pre_post_pre_delays)\n", + "axes.set_xlabel(r'${(\\Delta{t_1}, \\Delta{t_2})} \\: [ms]$')\n", + "axes.set_ylabel(r'${\\Delta}w$')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "alert-provision", + "metadata": {}, + "source": [ + "### post-pre-post triplet" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "proved-broadcasting", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simulating for (delta_t1, delta_t2) = (-5, 5)\n", + "Initial weight: 1.0, Updated weight: 1.0452168105331474\n", + "Simulating for (delta_t1, delta_t2) = (-10, 10)\n", + "Initial weight: 1.0, Updated weight: 1.0275785817728278\n", + "Simulating for (delta_t1, delta_t2) = (-5, 15)\n", + "Initial weight: 1.0, Updated weight: 1.008936270857372\n", + "Simulating for (delta_t1, delta_t2) = (-15, 5)\n", + "Initial weight: 1.0, Updated weight: 1.050539844879153\n", + "Simulating for (delta_t1, delta_t2) = (-5, 5)\n", + "Initial weight: 1.0, Updated weight: 1.048644757755009\n", + "Simulating for (delta_t1, delta_t2) = (-10, 10)\n", + "Initial weight: 1.0, Updated weight: 1.026345906763637\n", + "Simulating for (delta_t1, delta_t2) = (-5, 15)\n", + "Initial weight: 1.0, Updated weight: 1.0099778920748412\n", + "Simulating for (delta_t1, delta_t2) = (-15, 5)\n", + "Initial weight: 1.0, Updated weight: 1.0466078732990223\n" + ] + } + ], + "source": [ + "post_pre_post_delays = [(-5, 5), (-10, 10), (-5, 15), (-15, 5)]\n", + "\n", + "# All-to-All interaction\n", + "dw_vec = run_triplet_protocol_simulation(neuron_model_name, synapse_model_name,\n", + " neuron_opts, nest_syn_opts,\n", + " post_pre_post_delays,\n", + " n_triplets=10,\n", + " triplet_delay=1000,\n", + " pre_post_pre=False)\n", + "\n", + "# Nearest spike interaction\n", + "dw_vec_nn = run_triplet_protocol_simulation(neuron_model_name_nn, synapse_model_name_nn,\n", + " neuron_opts_nn, nest_syn_opts_nn,\n", + " post_pre_post_delays,\n", + " n_triplets=10,\n", + " triplet_delay=1000,\n", + " pre_post_pre=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "plastic-stewart", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEKCAYAAAAMzhLIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAU2UlEQVR4nO3df5Bd5X3f8fcnUhCkqcFFm5kWiAUVNJWDg5s1ntYmk5TGhhk7wok8luw2Sk1KPanGM009E5zUqUMndfE0JtMxmZhUZAgTD8TEpUpsR/mBf4xdTFgRjC1sOWuBizCdih/GwTGWZb79455Fl8vVsz/Yc3e1er9m7uie8zz3Oc8+e7Sfe8859zmpKiRJOp7vWekOSJJWN4NCktRkUEiSmgwKSVKTQSFJajIoJElN61e6A8tt48aNtWnTppXuhiSdUPbt2/doVU2NK1tzQbFp0yZmZmZWuhuSdEJJ8tXjlXnoSZLUZFBIkpoMCklSk0EhSWoyKCRJTQaFJKnJoJAkNU0kKJJcluRAktkkV48p35Dk1q78riSbuvWbknwryb3d47cn0V9J0jG9f+EuyTrgeuAngUPA3Un2VNX9Q9WuBJ6oqs1JtgPXAm/qyr5SVRf13U9JGpX00+6Jdr+4SXyiuBiYraqDVXUEuAXYOlJnK3BT9/w24NKkr1+RJGkxJhEUZwEPDS0f6taNrVNVR4EngTO7snOT/FWSTya5ZNwGklyVZCbJzOHDh5e395J0klvtJ7MfAX6wql4O/CLwwSQvGq1UVTdU1XRVTU9NjZ3TSpK0RJMIioeBc4aWz+7Wja2TZD1wOvBYVX27qh4DqKp9wFeAC3rvsSTpWZMIiruB85Ocm+QUYDuwZ6TOHmBn93wbcEdVVZKp7mQ4Sc4DzgcOTqDPkqRO71c9VdXRJLuAvcA64Maq2p/kGmCmqvYAu4Gbk8wCjzMIE4AfA65J8h3gGeBtVfV4332WJB2TOtGu05rH9PR0eT8KScvhZLo8Nsm+qpoeV7bmbly0Kp1Me5ukNWe1X/UkSVphBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpoMCklSk9+jkKRJO8G+W+UnCklSk0EhSWoyKCRJTQaFJKnJoJAkNXnV04g+LkZwjldJJzI/UUiSmgwKSVKTQSFJajIoJElNBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpoMCklSk0EhSWoyKCRJTQaFJKnJoJAkNRkUkqQmg0KS1GRQSJKaJhIUSS5LciDJbJKrx5RvSHJrV35Xkk0j5T+Y5Kkk75hEfyVJx/QeFEnWAdcDlwNbgB1JtoxUuxJ4oqo2A9cB146Uvw/4WN99lSQ93yQ+UVwMzFbVwao6AtwCbB2psxW4qXt+G3BpMrh7dZIrgAeA/RPoqyRpxCSC4izgoaHlQ926sXWq6ijwJHBmku8Hfgn4tdYGklyVZCbJzOHDh5et45Kk1X8y+93AdVX1VKtSVd1QVdNVNT01NTWZnknSSWL9BLbxMHDO0PLZ3bpxdQ4lWQ+cDjwGvBLYluS9wBnAM0merqr3995rSRIwmaC4Gzg/ybkMAmE78OaROnuAncCdwDbgjqoq4JK5CkneDTxlSEjSZPUeFFV1NMkuYC+wDrixqvYnuQaYqao9wG7g5iSzwOMMwkSStApk8MZ97Zienq6ZmZklv35wrdXyKnpoFGCN/e6k1aaPvwewOv8mJNlXVdPjylb7yWxJ0gozKCRJTQaFJKnJoJAkNRkUkqQmg0KS1GRQSJKaDApJUpNBIUlqMigkSU0GhSSpyaCQJDUZFJKkJoNCktRkUEiSmgwKSVKTQSFJajIoJElNBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpoMCklSk0EhSWoyKCRJTQaFJKnJoJAkNRkUkqQmg0KS1GRQSJKaDApJUtNEgiLJZUkOJJlNcvWY8g1Jbu3K70qyqVt/cZJ7u8fnkrxhEv2VJB3Te1AkWQdcD1wObAF2JNkyUu1K4Imq2gxcB1zbrf8CMF1VFwGXAR9Isr7vPkuSjpnEJ4qLgdmqOlhVR4BbgK0jdbYCN3XPbwMuTZKq+tuqOtqtPxWoCfRXkjRkEkFxFvDQ0PKhbt3YOl0wPAmcCZDklUn2A58H3jYUHM9KclWSmSQzhw8f7uFHkKST16o/mV1Vd1XVS4FXAO9McuqYOjdU1XRVTU9NTU2+k5K0hk0iKB4GzhlaPrtbN7ZOdw7idOCx4QpV9UXgKeCHe+upJOl5JhEUdwPnJzk3ySnAdmDPSJ09wM7u+Tbgjqqq7jXrAZK8BPgh4MEJ9FmS1On9CqKqOppkF7AXWAfcWFX7k1wDzFTVHmA3cHOSWeBxBmEC8Grg6iTfAZ4BfqGqHu27z5KkY1K1ti4kmp6erpmZmSW/PlnGznSKHhoFWGO/O2m16ePvAazOvwlJ9lXV9LiyVX8yW5K0sgwKSVLTgoNi3GWpkqS1bzGfKP4yyW8k2dxbbyRJq85iguIi4BPAdUk+kuR1SV+nerQWJcv/kNS/xQTFGcB+4NeADwPvBQ720CdJ0iqymO9RPArcCXwG+BvgBuAbfXRKkrR6LOYTxTTwZeBC4H7gv1fVjb30SpK0aiw4KKrqnqr618C/BDYDn0ryy731TJK0Kiz40FOSTwJ/B/i+btUzDOZl+i899EtamN6+Ouu33qU5izlH8bPA14FvdBP2XcKxOZkkSWvUYg49fRU4D7g2yVeB/8bgMJQkaQ2b9xNFkguAHcCbGVzt9CHgx6vqgSQP9Nw/SdIKW8ihpy8xuKfEtqr6/EiZB3IlaY1byKGnnwYeAP40yc1JXp/ke3vulyRplZg3KKrq9qrazuCS2I8BVwGHkvwu8KKe+ydJWmGLOZn9zar6YFW9nsEtSe8E7uutZ5KkVWFJ96Ooqieq6oaq+ufL3SFJ0urijYskSU0GhSSpyaCQJDUZFJKkJoNCktRkUEiSmgwKSVKTQSFJajIoJElNBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpomEhRJLktyIMlskqvHlG9IcmtXfleSTd36n0yyL8nnu3+d1lySJqz3oEiyDrgeuBzYAuxIsmWk2pXAE1W1GbgOuLZb/yjw+qq6ENgJ3Nx3fyVJzzWJTxQXA7NVdbCqjgC3AFtH6mwFbuqe3wZcmiRV9VdV9bVu/X7gtCQbJtBnSVJnEkFxFvDQ0PKhbt3YOlV1FHgSOHOkzs8A91TVt0c3kOSqJDNJZg4fPrxsHZcknSAns5O8lMHhqH87rry7Let0VU1PTU1NtnOStMZNIigeBs4ZWj67Wze2TpL1wOnAY93y2cD/BH62qr7Se28lSc8xiaC4Gzg/yblJTgG2A3tG6uxhcLIaYBtwR1VVkjOAjwBXV9VnJtBXSdKI3oOiO+ewC9gLfBH4g6ran+SaJD/VVdsNnJlkFvhFYO4S2l3AZuBXk9zbPX6g7z5Lko5JVa10H5bV9PR0zczMLPn1yTJ2plP00CjACfa7c2x1ouljn4XVud8m2VdV0+PKToiT2ZKklWNQSJKaDApJUpNBIUlqMigkSU0GhSSpyaCQJDUZFJKkJoNCktRkUEiSmgwKSVKTQSFJajIoJElNBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpoMCklSk0EhSWoyKCRJTQaFJKnJoJAkNRkUkqQmg0KS1GRQSJKaDApJUpNBIUlqMigkSU0GhSSpyaCQJDUZFJKkpokERZLLkhxIMpvk6jHlG5Lc2pXflWRTt/7MJB9P8lSS90+ir5Kk5+o9KJKsA64HLge2ADuSbBmpdiXwRFVtBq4Dru3WPw28C3hH3/2UJI03iU8UFwOzVXWwqo4AtwBbR+psBW7qnt8GXJokVfXNqvo0g8CQJK2ASQTFWcBDQ8uHunVj61TVUeBJ4MyFbiDJVUlmkswcPnz4BXZXEgBJPw+dcNbEyeyquqGqpqtqempqaqW7I0lryiSC4mHgnKHls7t1Y+skWQ+cDjw2gb5JkuYxiaC4Gzg/yblJTgG2A3tG6uwBdnbPtwF3VFVNoG+SpHms73sDVXU0yS5gL7AOuLGq9ie5Bpipqj3AbuDmJLPA4wzCBIAkDwIvAk5JcgXwmqq6v+9+SyeKvg77+05Nc3oPCoCq+ijw0ZF1vzr0/Gngjcd57aZeOydJaloTJ7MlSf0xKCRJTQaFJKnJoJAkNRkUkqQmg0KS1GRQSJKaDApJUpNBIUlqMigkSU0GhSSpyaCQJDUZFJKkJoNCktRkUEiSmgwKSVKTQSFJajIoJElNBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpoMCklSk0EhSWoyKCRJTQaFJKnJoJAkNRkUkqQmg0KS1GRQSJKaDApJUtNEgiLJZUkOJJlNcvWY8g1Jbu3K70qyaajsnd36A0leO4n+SpKO6T0okqwDrgcuB7YAO5JsGal2JfBEVW0GrgOu7V67BdgOvBS4DPitrj1J0oRM4hPFxcBsVR2sqiPALcDWkTpbgZu657cBlyZJt/6Wqvp2VT0AzHbtSZImZP0EtnEW8NDQ8iHglcerU1VHkzwJnNmt/+zIa88a3UCSq4CrusWnkhxYnq4vjyyu+kbg0YU1vMiW1yDHtj+ObX9W6di+5HgFkwiK3lXVDcANK92P5ZBkpqqmV7ofa5Fj2x/Htj+rYWwncejpYeCcoeWzu3Vj6yRZD5wOPLbA10qSejSJoLgbOD/JuUlOYXByes9InT3Azu75NuCOqqpu/fbuqqhzgfOBv5xAnyVJnd4PPXXnHHYBe4F1wI1VtT/JNcBMVe0BdgM3J5kFHmcQJnT1/gC4HzgK/Luq+m7ffV5ha+IQ2irl2PbHse3Pio9tBm/cJUkaz29mS5KaDApJUpNB0ZMkpyX55Lhvkif5uSSHk9zbPX5+Ae19opvGZO41P9Ct35XkrX38DCttnjH8sST3JDmaZNtI2c4kf909do6+dkxbb0yyP8kzSaZHyp43hUySU5J8qrtC74TXw77660keSvLUQtpKMpXkT5bvJ1o9XsA+/N2hcRq9+Gfcdnod2zWxo69SbwU+3Dj5fmtV7Vpkm2+pqpmRdTcCn+n+XWtaY/h/gJ8D3jG8MsnfA/4TMA0UsC/Jnqp6orGdLwA/DXxgpK3hKWT+AfDnSS6oqiNJ/gJ4E/D7S/nBVpnl3lf/CHg/8NcLaauqDid5JMmrquozi9jOiWDR+3DnW1V10SK31dvY+omiP28B/lffG6mqvwUeTLIWpzY57hhW1YNVdR/wzEjRa4E/q6rHu3D4MwbzhB1XVX2xqsZ9m781hcztXf/WgmXdV6vqs1X1yCJfdjtrZzyHLWUfXm638wLH1qDoQfd9kfOq6sFGtZ9Jcl+S25Kc06g37He7j5Xv6ubCmjMDXLLU/q5GCxzDccZNGfO8aV+Woa0vAK9YYrurRo/76mLbch9+rlOTzCT5bJIrFvia3sbWoOjHRuDrjfI/AjZV1csYvOO9qVF3zluq6kIGv/BLgH81VPb/GBwaWUvmG8MV1R1KOJLk7650X16gPvbVpbTlPvxcL+mm7Xgz8JtJ/uE89XsdW4OiH98CTp1b6E7u3ZvkXoCqeqyqvt0V/w/gR+drsKoe7v79G+CDPHcW3VO7ba4lzTFsWM5pX+ZrawPw9BLbXi2WfV89nnnach8eMvT//SDwCeDl89TvdWwNih50x8bXJTm1W/6Vqrpo7uRUkr8/VP2ngC/OLST50mh7SdYn2dg9/17gdQwOfcy5YGT5hDffGDbsBV6T5MVJXgy8pltHkt9b5Lmc404hk+RM4NGq+s6ifrBVZrn31ZZWW7gPP6vbdzd0zzcCr2IwOwVJ3pPkDWNe0+vYGhT9+VPg1ccpe3t3OebngLczuPJhbqcYN0/wBmBvkvuAexm8q/2dofJXMfi4udYcdwyTvCLJIeCNwAeS7AeoqseB/8xgjrG7gWu6dQAvA742pq03dG39U+AjSfZ2be0H5qaQ+ROeO4XMTwAfWZafcuUt575Kkvd24/l9SQ4leXerrc5aGs9hi96HgX8MzHTj9HHgv1bV/V3ZhcD/HdNcv2NbVT56eAD/BLh5ka95HfD2Rb7m5YvdzonyWMoYNtp6EfChZezbh4ELVnqMVmqcl7KvztPep4AXr/RYrIaxnae9vSsxtn6PoidVdU+SjydZVwucyLCq/ngJm9oIvGsJr1v1ljKGjba+weCd2wvWXc1ye1V9eTnaW2kT3FfHSjIFvK/a33U5IS3nPty199rF1F+usXVSQElSk+coJElNBoUkqcmgkCQ1GRSSpCaDQieNjEz5nOSKJJXkh0bqnZ3kTUvcxpLazHGmLk+yKcm3FvJt3nn6dVr3reAjc1/elBbKoNDJZHTK5x0MJkzbMVLvUgbXvy/FktqsqiPA3NTlo75Si59yerT9uWmrn/eFQ2k+BoVOJs9O+Zzk+4EfB36eoT/qSV4NvA/Y1r0DP2+hjS9Dm7ezgOmgk3woyfuTfDrJV5O8OsnNSb6cZHdXZ2eSfd1sop9e6M8gjeMX7nRSyPOnfN4K/HlVfS7JU0l+tKr2VdWnk9wNvKOqFjs/zgttc6FTl18I3FlVu5L8MrCbQUAdBg4lOR34JeCiGtxk6YxF/hzSc/iJQieL0SmfdzCYx4nu3+FDRf8I+BJAkvOS7E5y2wK2sdA2r0jyO0luTfKauQq1gKnLuwnmzgB+c+5lwO6qeqSqjgLfBY4CpwG/kWS6qr4+pilpwQwKnSyenfI5g9ulvpLBRH8w+KP+pgxsBJ7s/uhSVQer6sr5Gl9km7dX1b8B3sbzz0nMN3X5S4F7qmrurmg/AtzV9eFs4GtV9U3ghxncIveGJL8wX/+lFoNCJ4V67pTP24CPVjd/fw3m/H+EwQ2hNrGAE75J/iLJ8J3zltLmfwSuH2pzIVOXXwh8bmj5ZcB93fMfAe5Lcn5VfbOqbgH+mKF7IkhLYVDoZDI35fMO4PVJHpx7MJjaeQeDw0Mbk3whyT8b10iS7wE2A48PrV5wm92njGuBj1XVPUNtLGQ66AsZTDU/dxjqtKEJ3+ZC41eSHEhyD3Au8FvzjozU4MlsnUyuB/59Vf3EPPWevblR9y7/14GXJ3lnVb0H2AL8YVU9e9ewRbb5duBfAKcn2VxVv90VvRm4utVIVf2HoedPMwiCueX3zNMHaUmcPVYnlSRvBW5ajimfl1N3Vdb2qvq9kfXnAP8beOyFfJciyWnAncAUcGEdu5mTNC+DQpLU5DkKSVKTQSFJajIoJElNBoUkqcmgkCQ1GRSSpCaDQpLUZFBIkpr+P1o2Lgk+GlI5AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plot\n", + "bar_width = 0.25\n", + "fig, axes = plt.subplots()\n", + "br1 = np.arange(len(pre_post_pre_delays))\n", + "br2 = [x + bar_width for x in br1]\n", + "axes.bar(br1, dw_vec, width=bar_width, color='b')\n", + "axes.bar(br2, dw_vec_nn, width=bar_width, color='r')\n", + "axes.set_xticks([r + bar_width for r in range(len(br1))])\n", + "axes.set_xticklabels(post_pre_post_delays)\n", + "axes.set_xlabel(r'${(\\Delta{t_1}, \\Delta{t_2})} \\: [ms]$')\n", + "axes.set_ylabel(r'${\\Delta}w$')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "initial-interval", + "metadata": {}, + "source": [ + "### Quadruplet protocol\n", + "\n", + "This protocol is with a set of four spikes and defined as follows: a post-pre pair with a delay of $\\Delta{t_1} = t_1^{post} - t_1^{pre}< 0$ is followed after a time $T$ with a pre-post pair with a delat of $\\Delta{t_2} = t_2^{post} - t_2^{pre} > 0$. When $T$ is negative, a pre-post pair with a delay of $\\Delta{t_2} = t_2^{post} - t_2^{pre} > 0$ is followed by a post-pre pair with delay $\\Delta{t_1} = t_1^{post} - t_1^{pre}< 0$.\n", + "\n", + "Try to formulate this protocol using the defined model and reproduce the following weight change window graph." + ] + }, + { + "attachments": { + "image-3.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiwAAAJjCAYAAAAveUpQAAAgAElEQVR4AeydBZhdxfnGixV3C4XgToIFL+4BglvRQgspDgUKJEACBJfihRb+aHH3Fivu7q7BiZKQrNzv//y+zXszObnrd3fPvfvNPmfnnDmj78yd7z3f2G8sTCAQCAQCgUAgEAgEAjlFYGxhlH1d/779Jqf5i2wFAoFAIBAIBAKBQCBgQViiEQQCgUAgEAgEAoFA7hEIwpL7KooMBgKBQCAQCAQCgUAQlmgDgUAgEAgEAoFAIJB7BIKw5L6KIoOBQCAQCAQCgUAgEIQl2kAgEAgEAoFAIBAI5B6BICy5r6LIYCAQCAQCgUAgEAgEYYk2EAgEAoFAIBAIBAK5RyAIS+6rKDIYCAQCgUAgEAgEAkFYog0EAoFAIBAIBAKBQO4RCMKS+yqKDAYCgUAgEAgEAoFAEJZoA4FAIBAIBAKBQCCQewSCsOS+iiKDgUAgEAgEAoFAIBCEJdpAIBAIBAKBQCAQCOQegSAsua+iyGAgEAgEAoFAIBAIBGGJNhAIBAKBQCAQCAQCuUcgCEvuqygyGAgEAoFAIBAIBAJBWKINBAKBQCAQCAQCgUDuEQjCkvsqigwGAoFAIBAIBAKBQBCWaAOBQCAQCAQCgUAgkHsEgrDkvooig4FAIBAIBAKBQCAQhCXaQCAQCAQCgUAgEAjkHoEgLLmvoshgIBAIBAKBQCAQCARhiTYQCAQCgUAgEAgEArlHIAhL7qsoMhgIBAKBQCAQCAQCQViiDQQCgUAgEAgEAoFA7hEIwpL7KooMBgKBQCAQCAQCgUAQlmgDgUAgEAgEAoFAIJB7BIKw5L6KIoOBQCBQDgTq6uqsUCiUI6rcxaFyySaDNTU1VVve3FVAZKhTEAjC0ikwRyKBQCDQlQikgry+vn6SrNTW1la8YM+WiQKqXGnZJyl4PAQCFYZAEJYKq7DIbiAQCLQdAWkdqlGIUyaVr+0IRchAIL8IBGHJb91EzgKBQKBMCDQ2HNSYe5mS7bRoshqWlLhQxjCBQDUgEISlGmoxyhAIBALNIoBQR3hnhXuzASvIg4aBlOVq1CSpbGF3PwSCsHS/Oo8SBwLdDgEJbmkbLrroIttvv/3sqKOOsu+++65q8FA5P/jgAzv00EPt2GOPtREjRlRN+aIg3RuBICzdu/6j9IFAt0Jg7NixXt4NN9zQfvOb39jcc89tn3zyibtJ2FcqIOSfoSDM008/bXPOOactuuii9v3331dF+Sq1XiLf5UMgCEv5sIyYAoFAIMcIoF1hyATTt29fJywLLLBAVRAWDXNJg/Tqq6/aXHPNZYsvvngQlhy3ycha6xAIwtI6vMJ3IBAIVDACIiz9+vUrEpZPP/3US1TpGhYKIeLy4osv2hxzzGG9evWyH3/8sWrKV8FNL7JeBgSCsJQBxIgiEAgEKgOBICyVUU+Ry0CgFAJBWEqhEm6BQCBQlQgEYanKao1CdRMEgrB0k4qOYgYCgUDD7q/gEENC0RoCgcpDIAhL5dVZ5DgQCATaiEBoWNoIXAQLBHKAQBCWHFRCZCEQCAQ6B4EgLJ2Dc6QSCHQEAkFYOgLViDMQCARyiUAQllxWS2QqEGgRAkFYWgRTeAoEAoFqQCAISzXUYpShuyIQhKW71nyFl1vnwlAM9s9gw6x0Hw0Ek/ak0GZa7AKq+/Q9/uS3wmGJ7DeDQBCWZgCK14FAjhEIwpLjyomsTY5ASkqybxFGvE+Jyfjx44sH3vFOREfx4DdLVlIyQxrym00vnisPgSAslVdnkeNAQAgEYRESYVccAiInWcJBQXATQeF5+PDh9uSTT9oPP/zg5VQY+UvDuIcJ/4gjCEuKSGXfB2Gp7PqL3HdvBIKwdO/6r5jSp8QiJRC6T4mFNC2jR4+2yy67zM466yzbbbfdfKvyfffd15//9a9/2U8//eTl14FxaRwVA0xktFUIBGFpFVzhORDIFQJBWHJVHZGZ1iIAyUAISWMCSbnppptss802s0UWWcSmm246PzOGk3mnmmoqm3LKKf15iimm8IPhttpqK3vhhRc82Sxhyc6LaW3ewn/+EAjCkr86iRwFAi1FIAhLS5EKf7lAINW0aP4JRAPz/fff23bbbWeQkWmnndbJCfeQFQ6BW3bZZd0d4jLNNNP4xTvc33zzTY8jjV8FTgmR3MKuTASCsFRmvUWuAwEQCMIS7aAiEBCRkBYktRFCQ4cOtW233baoTZl11lnt1FNPtQcffNDuvPNO40TeDz74wO6++25/vvLKK22xxRYr+l9qqaXs2GOPtW+//dbxIP4gKhXRNFqVySAsrYIrPAcCuUIgCEuuqiMy0xgC0qKIuOBPbh9++KFtueWWTj4Y8plxxhnthhtuKEaFkMIvYTGsHMI8/fTTTnJmnnlmD7vGGmvYRx995O+0/Nkf4l/VIBCEpWqqMgrSDREIwtINK70SiyxtR0pYNFn29NNPLw4BMdRzySWXFIuoYaM0nF6KuAwZMsRmmGEGJzq33Xabv8a/iI7859lO59uImGEH8Zq01lTnIrgLLrhgkaSKAE8aojKeaOfkX8T8xRdftLnnntuWWGIJHyqlFJVcvvbUgsotm7hEXFO39qQRYTsHgSAsnYNzpFJGBFJB/O6779qqq67qGhI0KzfeeKOnRAdeSljTQamTUqeFhmb11VcvxnHVVVeVMbedFxW4qGwiakpd5e6utsin6nyLLbbw+p5//vnt448/dpiEXyViRAHIt8rHRPI555zTevfubT/++KOXrxLL1ZY8q82XstUOSr0Lt/wjEIQl/3UUOZyAAJ2NOhyRkVdffdWWX355Fz6HH364/fLLL+6bjk5G97Lljo1gx5x44onFSbh8lWoSrtIrFTaNJw/3CFwujDQuyjd2d77AhPKrvqVhgbB89tlnjlklExbqO63/5557zpfxMzfru+++8/KpLfjDBDyqsU2ofKmt3wVuagN6r75Ez2HnF4EgLPmtm8hZEwhAJDBMol1yySWdsBx44IG+QRzuY8eOLX5tqjMvFZ3i+eSTT4w5LKwaopN/44033Pu4ceOKJKBU+Dy7ZQVUnvPa0XkTGVF9M0Gb1WI9e/YsaliqAS8JZoaE5ptvPltppZUm0bB0NM55jL9UvYqk8E73ecx75GlSBIKwTIpHPOUYAXXGfCFpy/0dd9zRSQb7rTB3RX4oBmRDAkrFUueFrXv5YVURQmzxxRe3d955x4OQTupX8eTJVplfeeUVXwF1yy232M0332zYrJDC5rr11lu77XX77bfbXXfd5XgwT4mhEsjpHHPM4e3mnnvuqXiMVN+U5cwzz7RZZpnF0CBdfvnlXu5qrn/qVJfKqTbPMDG/DX4n+q3o95t9lnvY+UQgCEs+6yVy1QQCIhAQF81FYB4L81kwaSfEvYiJ3ulZ7+Sfpc8IMjp5hpow8usPOf0nwsVuvghhXb/97W+dgPHMfjTd+WL1mPbkAReemaAtt0rHBqKtsmil3NRTT91s/autVHr5yT/lzl5gQBn3228/+/XXXyf5BVfCb3uSDMdD7MMSbaAyEFDngvpWQzycD7TDDjt4h8Q8FmlFIDIiIZROYbF1j7v8SOAzb4W9Wdgh97333nNgpMnJM0oak99zzz2LZEUduISYBFN3t1PBDhYpaal0bBDWkDHVOSvfcKv0crUn/yo/vw2GiTHqA2SrH8jzbzzy1oBAaFiiJVQMAupgsOlkxowZY5tvvrl3yGuuuWaRZPBOftPCyU2ER+/UYTGPBeIz11xzFeewQGYUTv7zZiv/DHmccMIJdsopp/jF/cknn+zXSSedZN35GjRokG8kOHDgQDvjjDMcH7BhSXu14HL88cfbgAEDvGznnnuuHX300bbOOuvYUUcd5eVUW5BdLeWmHCoTtso1ePBg4wKXRx55pLj/Uvr7zftvO81r3MdOt9EGKhQBaUUQ0kyc5CsM4cO8FYyEOB1SKQKjjgpbcbHKiC/uRRdd1F5//fVJ4qlQmCLbExCApKrOGRpgqa+0dXKvFrBoz2r/zGXRCeWUj7JWW3mrpd6iHM0jEBqW5jEKHzlBIO1oETaY//3vf7bccss5YTnssMOKy5rpsLNDQxJQKg5+FA873K611loeD0NCIiy8V+evcGFXJgIipn/7299sxRVXLC5nTttVZZasYRk7ec+2VYZBcKOM/B5UVuys30ote+S7+yAQhKX71HVVlVRE49lnny0ua1566aXt8ccf93JmO2Y981IduNy+/PLL4tASmpojjjjCOPVZfv0m/lU8Aqrvt956y+6///5iHVd8wTIFEBGRnXntj/r98NCUv1Jhwy0Q6CoEgrB0FfKRbqsQEMkgEPf6WkYzsskmm7hmBLKx2mqr+SGH+MMPlzpnhgK45yIOuTO+rYMQF1hgAXvmmWc8b4TFX5p2qzIdnnOJgOpeBCbVPOQyw63MVNpeRby/+uor1z7S5im3yt7KqMN7INClCARh6VL4I/G2IKAOFxtS8eSTT1qvXr2ctLCvxr777muff/65Ry2/dOIyumdV0DXXXGP9+/f3/TimnXZau+OOO9xbdjhJYcOuPARU3+zFMWzYsEkKoHeTOFbwg8gX5aLti5SzqSKTyjEQd5Wbieu6r+BiR9a7CQJBWLpJRVdDMdUJp2VRZ8u+KcxL0BJIhoeY34Kh48awRBmCg6Hz3mijjdw/S0EJ169fPxs6dKi/lz86d937i/hXcQhQ7xg2GTzyyCOLQ0Fyr+TdjBurDH4XIi+0X87LUvvX70Fhs89yDzsQyBsCQVjyViORn0YRyHasdMB8QYpQ/N///Z+fUCvSsvLKK9sVV1xhV199tS9TZm8VdsFkO/+NN97Y96uYfvrpnaz06dPHmNuAyabTaIbiRUUgIFJL3auOlfFSJFjvKs1WOdN8S8NS6l3qL+4DgUpAIAhLJdRS5HGSeSRZIaPOmEPs/vvf//pXNENDEBc2CsPmfCDOHJp99tndja382WCrR48evhz6559/nkSFLjIU0FcPAhDblIxmn6uhpJSP34OISlpe3Lg4IFS/GTSIqZ9qwCDKUL0IBGGp3rrtViWj01UnzcGFzGNhm/1ZZ53VCYvIi3a+ZBdQ3DhnRQYBpo4cWx25bPkLO58IqJ5SW/f5zHHH5iotO8Ne/D523XVX69u3r/3000+eOH5Sfx2bo4g9EGgfAkFY2odfhM4JAmmnK9KB1uSyyy4zdv286KKLfIdTCApzVZhgC2HZa6+97JtvvvFSROedk8psRzZSrYnaxEMPPWS0hWo2KmupMuod7fz000+36667brJzdUqFC7dAIG8IBGHJW41EftqNQEo80ntWRGCuv/56m2eeeZywsIz5pZdecnf8MhQkwtPujEQEnYoAGgTVHffSuLE9u1bISHh3asY6IbFsubLPZCF1S4eChFknZDOSCATahUAQlnbBF4HzigDCKv3a5pkOG0KC4TyZmWaayeezXHnllcXOnM477djxm33Oa5kjXw0IqK5Vd9R5d6pDyqorbRNaNZTFIv2dpP7jPhDIGwJBWPJWI5GfdiFAp6wvazrm9JmIpUFBPa6t+LfbbjtjYy1M+rVZqtNvV+YicIciQN0hfDHM2dB9hyaa48gba7/8Bjhf6Lvvvpukvee4KJG1QMARCMISDaEqEICkpGQjWyg6bzpqCAzm/fffN5Y9M49lpZVWsrffftvdS2lYsnHFc/4QSLUEagdsHqhhQOq/Oxt+HzoYlOExVs3R7jV/qztjE2WvHASCsFROXUVOW4iAhgQQXBoOkMDiGeHGdcghh/iwEKTluOOOczf8idS0MLnwlgMEpE1hyS71P3z4cOOQw08//dRzp/rPQVY7JAtp+Wj3YFDK4A8SxzAoc7m0dX8pv+EWCOQNgSAseauRyE+bEYBo6Os624ETKe9wV2fOTrja0p89WnRCM37wq7janKEI2KkIQEbTOmNlUHchn2l7h5CMHDmy2M55p/dq+6oYues57EAgzwgEYclz7UTeyoYAHbWEGfbYsWM97v3339+HhdCyDBkypDgpN+3k8R8de9mqok0RUX+qA9VjGlFaR5AU/KZuqd9y3qftpJzxtjYu8qFhsR9//NF22203O/XUU+3888+3F154oTgcRLwiLSmOwlbpps/SUupd2IFAVyEQhKWrkI90uwQBOnU6anXW77zzTvEMovSkZ4SeBECXZDQSbRUCErBMJqXupG1BOIvAtCrCCvWsNpueq8XS/d133904/BEyIzxGjBhhW2+9td17771e2pTggad+IxUKRWS7ChEIwlKFlRpFmhwBCbRU08JeFJijjjrKtSwLLrigPffcc+6WfoUq7OSxhktnI1CqLlLhymnbnCl1++232/3332933nmnn8DNc0dct912m3F1RNytiZM83HTTTX7dcsstBknh6AkutIdcc889ty2yyCJ28cUX+5laHGVx2GGH2RNPPFHUXpWqz1KYl/IXboFARyMQhKWjEY74c4eANCx8jWIef/xxXzVBp3744Yf7WSu4Q1ogNfGlmY8qTDUA2RwhVLmYbLvOOuv4/jqcwj3jjDP6NfPMM1u5L/bx0VXuuLPxNZaO3DmCgvLOP//8bnMEBbs5c7gnpIXnaaaZpni2Fkv5meMjAg92uhe2Iiqy5R52INBVCARh6SrkI91ORaCUsBNh4fTmRRdd1L9CORyRybgYhYkOu1Orqs2JqZ5YqsuS5qFDh/rFPdcXX3zR7uvLL780XeWIry1xlEqf8uH+8ccf20cffWTLLLOMt2cO/4SoQFrWXXddg6g8+uijTsQ17NkY4EHUG0Mm3LsKgSAsXYV8pNslCCDU+JLEloDjq3zzzTcvqs9Rk2u5Z+qvSzIciRYRUH3hIDLJPfWpuRs8a46G/GF3BwMmYIFWkD1W0BjON998dswxx/gy5u+//95hSHHknnDnnHOOPfvssyW1ian/7oBjlDG/CARhyW/dRM46CIG0A5aWhdNr+QKlk2cuy6uvvuqpZ8lNB2Upom0BAqoLvOpedcnhlmgYMNIMpMSlBdFXvBdhATEZNGiQPfjgg65xURungGweJ3+4azM55rccf/zxxUMRwTAlgRUPThSgKhAIwlIV1RiFaA4BddISdHTGdMrqmAnPV+Z0001niy++uLF6CCPh11z88b7jEUjrgvrUxRL1G264wbIaBPlXnXd8Drs2BbVpckGZZdT20+XJYIM7Nn7ZOPGpp57yZ+Gq8GEHAnlBIAhLXmoi8tFlCKhzf+ONN2y55ZZzLcvZZ59d3JOluwi8LquAFiQsoSuv6dd/9p38hN06BNJ2nt6nWpnWxRi+A4HyIhCEpbx4RmwViIC+xFk10bdvXycsrDT58MMPvTQiNBVYtKrLsvZXoWAiKqq/qitsJxZIZy4xnwtNFZhCCjnqQDh3YnYiqUCgJAJBWErCEo7dDQHmO2AuvPBCm2222Zy0bL/99r7KBPfotLu+ReirX3UBwbz55pt9M7Soo/bVD+QEM2DAADviiCN8a3/FmGqz5BZ2INAVCARh6QrUI83cIaAOm10/2XSLybfs4cHciDBdj4Am0PLlL3J5+eWX25FHHhknDpeheoTpfffdZ1ddddUkhKUM0UcUgUBZEAjCUhYYI5JqQIDhBr7i2SlVpGWrrbayr776younL/tqKGulloE6UD0gZJlwG0NC5alN4SpNlmLNPss97ECgsxEIwtLZiEd6uUSATpkL891339kaa6zhWpaddtopCEtOamzUqFHFOiJLGqqQoM1JNis2GykZhAQGEazYqqzajAdhqdqqjYK1FgF10Ow+uvrqqzthYQdcnS8UgrG1iJbXv+rnmWee8YP8NIwX9VIenMFRGNPmWTU3cuTIokarPKlELIFA2xEIwtJ27CJklSFAZ60DEQcOHGgzzDCDkxY21GK4CBPCsesqXQSFlVz77LOPnxtEbiRkuy5n1ZOy2v9uu+1mTDpn1RAm2n311HEll6SiCIt+NNh0XuXsqNK4dc8QQTnTqOSG0l3yLmLy4osvFrc3n3POOe3666+fZDiCdqF20l2w6chyZrHk901dpO4iLJwVxM7EPHOlftqaR83TyMal37/eK365y5Y7tiYIp25pvLpX+cpVhjS91t6rHML466+/Li5vzsal/OOe3mf9xXMgUG4EKoqw0GnoBwUQ/Fhww/CDo6NIf/x6rx9jS8AjDP7THyJxKp2WxBF+Kg+BVCCJtBx11FHF84X69Olj7733nhdMAklthI21on20v87BU5gqNn6L/P7AHAPWrfk9K56W2uo/sDHXXXedL3U///zz7eKLL/Yt79G4nXHGGXb66afbkCFD7NRTT7ULLrjA3Xg+77zzjI0HTzjhBDvxxBPd/ayzzrJ//OMfdvLJJ/tQi/KjtqTnrrJTTNON4lQfvE9/I+RT77oqz5Fu90OgogiLfiR0JvqBlfrR4Jb6aa5aFQfqUH6sSoc09K65OOJ9dSBAnetidRBqcZY4L7vsspNs10+70FUdJc9PKVLBmP4G0azo9ymCCLnUfXtLIPIgsgLxmGWWWbz+OcV74YUX9lOQl156aVtiiSXsd7/7nS2yyCL229/+1v2wsow5TwsttJAttdRShj9OTcZtscUWs+mnn979PfDAA+3NaoeEp9zCl9VX4MocFvpF9YPUB4Zn3XdIZiLSQKAEAhVDWOhM1JGoHBIsPKf3ei+7qXfyk7WVHj9M0tUPNusvnqsLAdoKdS0h+OSTT7qgmmOOOew///lPsbAISvzSNuS3+DJuWo0AGOo3ltYBbjwzBMRZTwxVYMqNudIkbu36ut9++zkp2XXXXe3dd9/1E7yHDRvmu7+Sn6FDh3pedt55Zycil156qQt8Tvpmh1gu7glD/Ezk3nfffX0VGgFVXtkeWRf9S/EnC8L3tNNO87Kr78WdsoQJBLoCgYohLAKHH3f2B54Kjbb+oNI4lBZu+qHKLezqRQCSqo5aX5rPPvusfyWjZTn44IMnmYRIOyRMdODlaxPgr9+3cH377bdt//33N04UvvLKK4t4yx+/Ud23NSeqd4ioJp5uu+22ttlmm012qCJpyf+jjz7q2jfaxy233OLJkx/lHQf5vemmm+zoo4+2H374oZhN2k97816MrJ03lJ28kHeuzz77zA8CZYn/PffcUyxHmt+0nO1MPoIHAs0iUFGERT8UfuQvvfSSH5/O8juWOT7xxBP29NNP+/XYY4/Zww8/bP/73//8BNLHH3/ccOO5sYuTSu+//3775JNPHDSlxQP36XOzqIaHikdAHTFf0Ztuuql/QSO8WPKM0XvuswKq4gvfhQVIyYcEPUMo888/v9fBoEGDioSi3L9J0ubCIKD79etnb775pj8rX0qTPgjDvBaGiyAskKnUZMN89NFHhsZCmhkRBMqpeNPwnXmvPNCu1bbpM3v06OFlYy6OiJzyRZ4VTm5hBwIdiUDFEBZ+GOpMPv74Y9too438hzTVVFO5TYcxxRRT2DTTTGNTTz21u/HMe2ze6+I5e2kculevXjZ48GCfLAeJwXR1Z9KRDSDibkAAjYo6X3XYam9MuJRQ2nPPPYtf3Hn6Oq62eqQOhD+EpWfPnv77ZbIrQy0Y6kt11d7y8xunDSjNHXbYwRjiETEhft7hT4Ka9CGz9Dn0LeyQLJP2Gcojw0pMvk01LHqncHmw9Tvg4w6tFmVjorG0jspjHvOuvIVdnQhUDGEBfn5IGMaP+/fv7xPf1l57beNabrnlbKaZZvIf15RTTlkkLXQmTIBbc801bbXVVvNxZMaSUXNycb/WWmvZiiuuWAwvEoSQ+uMf/+haGv1Y046oOptE9y5VWr/6Aqa9bbLJJt62mMvywgsvOEh02PhPw3Rv9Npe+hRD7sFWv3fmDumohFNOOaW4J47eS8C2PfWGkBLAX375pS244IJ+sGI2TvzI3+uvv+4TbBHo0047rWto8S9io3uRoNtvv91YecZpyBi1r3Ll3yMtwz+RtEceecTmmmsub/cnnXRSEfe0rkhO9VCGpCOKQKBJBCqGsPAjSX8odAKoKJnUhkF1q+3UpVWRZuWKK65wP3yZQTzSizjoOJgNz0F3kBd9MaGp4Z7OiCWKmoynDjXNT5Mox8uKQSArPCRsOMUZAsvKkNdee83L05qOOm0rCDw9y64YgDoxo8L3oYceKg4JsYSY36tMOfFTXBzNgFaHPgEjd+7V73DP4YvSvO2+++6TzG/ivdqSysGQEX0MK3Bk5EfPebBFyBgSEmFhKE4fbXnIY+SheyJQMYSlVPXww9LXAHtk/P73v/evAYgGWhYRFk4fxUiFTweUvSSY7rrrLp9kCUkhPPFMN910rrFJ1aLqxAinsKXyGG6VgUApwUEdI1ywv/32W1t11VW9fR1++OE+IfHnn3+eRHi2pKS0FQkwCQbcdN+SOLqLH+HUWYRF/QP48nGj9HmmjhDY1JPayrrrruvtAQ3LscceWyQ4qh/ajeoVO40/7T90r3BdbSvPQVi6uiYi/SwCFU1YKIw6lZSwZDUsIixNEQs6DcX11ltv+RASHRHbs0vjgvaFFQsY4spbR5Ot3HhuGwIIFrUFdd4QlpVWWskF1Mwzz+xf1tttt13JSdotTRVNgeJvaZju5E910FmEhd9z+rvO1k3aLt555x1jM0H6CPZk0aaC1A/5Vt55TvsJ7tPnPNanyh2EJY+1073zVDWEhQltzFOhA8kSFk2Ga4qw0Az0Q2XDsA022MDjQrtCnCItF110kbcYdUrESbi8d0Ldu5m3vPSpQKFeNfxw7rnnFjcR0wRtCCwrPzDNtS38IPCIUxdu0W4cvpL/JPQ7g7BQJzLpPW6qN91jH3roocU+oXfv3sX9YVSf5F33ihc34sJwT9tK25v8dbWt8gdh6eqaiPSzCFQNYXn//febHRJqTqjQiWic9uabbzbOkIGspMNLDAu8/PLLjmNz8WXBjud8I4AAoQ1gNM+J+wcffLA46RPiSnugXUCQP/jgA+eztWUAACAASURBVPevTt4fSvzLCi95Sb/a5RZ2AwKqi84gLI1hrnqVrfknDA/rcEz2VyGv+JE/4lOdy86mkfWffd9VzypDEJauqoFItzEEqpawSMuCYGnJkJAA0hc1k+6WXHJJF0zMZ5GmhW23We6HUSfVWIekOMOuHASkMSPH3IuUolljhRCERavRUg2LhGtzJcWf/NJuou00jphw6mzCQp1I+0EeVEfcS0MyYMCAImFBsMtI2OsZW+F5pzYlN4ix7tMwXXmvMgRh6cpaiLRLIVCVhEVkJTvpVsKnFBC844cqDct///tf35IdwkM8Ogdkvvnm803oiEPx0ZGpcy0Vd7jlH4FUMKW5leBi7wwtbVZbQNumuQsjRozw5fZMxGUZdKmL1ScixGkatLu8Ca00f111r99UZxCWxupfZec99STCcuCBB/pEfNoCHzfqC+Sf+mwqTvyrzmUrbFfbQVi6ugYi/cYQqBrCgmqe/VggGFnCcs0113j5s51KKVDUSbJkkcmVxIfqV/MW2LBOQkp+S8UTbpWHQCo4JFBEJhBUrBxhU8FZZ53V28XKK69cPBBxp512MsisDsZjIiYXWjrcOABvhRVWMHZmxigtxV95aHV8jvX76gzCojpJSUZ6z3sJco5rQNOqoUE+bjD4l59sWPcwwY/qXrbe5cVWGULDkpcaiXwIgaohLE2tEmqOsKjjkHaFnXTXW2+9IvlhmbQIiybwIsBC2KgZVb8tAsPeHDrBmTks9957r++KPNtss3l7geDOOOOMvncPw4h8gSPYJNzYxJBNuNC2YNC4SEBUP4qtKyFCH5MSliFDhkyipdJvt3UxT+67JfFoa/p0fhtat88//3yyCCu5TpX3ICyTVWs4dDECVUNY0km3zDmBZGhISBvHNaVhUYfFVzS7URIe4cOcBa0QYtdbnRaLf4Xp4jqM5DsJAeqbzhyysc8++7hGBaIiMst5N7vttpufa8XqoVdffdU4HO8Pf/iDoY1hDoyIyzbbbFM8U0bxqj1h676TipbLZDqTsAAAHyFKUwQVd+pczz/++KOts846rsWlf2BDSREZgYj/tP4UVu/zbgdhyXsNdd/8VQ1hYVlzY0NC1113ndewxp9LVbdm/zNBV7P/tQEdHRNHzdNZYdDEiPwQp+5LxRtu1YMAgknt5JxzzilOvqV9sJW7hgbURiT8IMEYdkPFL4QaG3LD/i4YCQl/iH+OgPDrbA0Lv+mUcHDPb578jBo1yljGzMcQQ8Z33nlno7VFndJmKq1uld/QsDRatfGiixCoGsKSalggGtKw0LFweB1CA+0IAkLXN998Y1y4M0mS7f233nprFyZ8Cc8777z+Ff2nP/3JOF8Eo46Mzks/bGy5d1E9RrIdjAB1rIut+TmXCtKB0OIeTYpMti3omaFGzsLh3CuR4ttuu03BGrUVvlEPVfqiFGHpqK35U4w10Zr6FnnRe/qKxRZbzOuevZp0LpDyir9K06hkmw/lxgRhySITz12NQNUQlg8//LCoYdFwDpNvuWc/Fb6AOUAte6HG58Id4aPhH86M4euJzkfnFaUkRR0Ytu67ujIj/Y5DQPWMhoXhHMgKbeuCCy4wVgalWjb8SoDhrnu5I/SkDWTy5tNPP+0ZFyHquFJUVszCLdWwdBRhySJD2vpdY0s7y7EMWtbO0LG0Z9m6I4yISxpXNp08PgdhyWOtRJ5AoGoIC6uEdJaQSIfmsPAMGdE1yyyz+K6lesZmoiTuWgHC5Mg999zTLrvsMvv000+LHZaaTdohZTsr+Qm7ehCgvqlnNHLrr7++E5aNN964OOFSnTyCTV/oKj1hMfiR8Np88809DojPMcccU5wHIb/4T+8VV3eyW0JYyomH6lDpDh8+3IeBIaRoZamPLbfcsjhn6eijj7YvvvjCzxDivUir6rhS61A4hIalnK0r4ioHAlVJWJgEyTwBNCwIBLZVZ/4J539AbLIXK4xwY9iHFUV8/WqvDbQzyyyzjG222Wb2/PPPO+bqmHjo7kKlHI2wEuLQ/ilnnHGGk1tIsFaMkX99TadlSVcAqZ0oHpY39+rVy9snk3KHDh3qQeVPdhpfd7sXcWhKw1JOTJhvAu6qozvuuMPYb2X//fe3/v3721/+8hfXrjHpluGgfv36uTt+mJDPcmdMSlgk/MuZz46OS3kOwtLRSEf8rUWgaghLOocluw/Ltdde67ikRKMUUBISY8aMsYEDBxZ3t9UQ0/LLL2+vvPJKMS788+NWuFJxhlt1IKCVIAcddJCTDEixdjymDaiTV1vA1r0QUFuRQGR5s3ZQvv32292bhHRW6GXjUpzVbAuLziAspfAlfeqd+qLvUH7AXP55h3t2rgt+5F9to1LqSvkNwlIpNdZ98tktCMvVV1/tNdoUYaEDkkBRR3PYYYe5cIKwaC8N5ruwFwTqYow6qu7TZLpfSdUemGsircgiiyxizzzzjIPBewmw5tChjYmwsAmdCMv111/vQYmnpXFl01L7xb01ecrGkz43l5/m3qdxNXUvIYkf5V24s5Msvzu0pYMGDSoOn0mr1RRe5cpfU3lvLH2l3dh74pSfbPxyl51931HPYKp+klVvc801l+PO2Unap4q0hT33qqdSeers/GfzoPSxs6aUW9ZPPOcLgW5BWFpzlhDVowl2TPCjk9TwkvbQYOdSrQrRF1a+qjVyU04E1B6uvPJKm2eeebxNnHbaaZNpVZpKUx08naQIC3FotdCNN97YVPBm30nIpx5JS8txU/dKuRfuDz/8cPHwyTPPPLMoUEVySpW9UsqYp3zq40u4PvLII0XCArlmwjnvRFBoX/Kbp3KUygtlS/NK3lWOUv7DLZ8IVDVhEcFoKWHRj1EC5eyzz3bhpLkw2NokDDKD0Y8WO0x1IqAvzrvuust69uzpbYJdbt966y0vcGs6PtqYVpYwH0YrTqRhaS+CtEPy25o8NZUm8XVG2yaNVKCQf+GealhOPvnkIuHLhilVjo7Of3vjb2/4UmVur5v6P4Y85557bm/vDF/KXfGTdxFxueXNTvFN78mn2lfe8hz5aRyBbkFYNDmyqQaaNmbNVzjrrLP8x8pqIw0JScCwwyWGTpaL8GGqFwGpw/fdd19vE6wse/DBB73ALal/BLDaiDp+hje0pX9ThEXhGkNX75lUzsTPF1980efXPPnkk3520VNPPWVcDGm19moqrN61JO6m/KTvuCffTzzxhJeFOWOXXnqp74mEthP8H3/8cXv55Ze9bNyn4bPl411T7+W/KT96xxBg9lJ43HXfGlv5U7ytCZv6VR5TN9039U5+1FZoP2iPX3jhBeM8NbVPdnZG00U+wZz6UbwsRihVfpVNttLK2oon696a51JpyI2ysfO0+urGfkfhnn8EugVhaYmGhU5fHb+EE+pnOknIioaFtGSadxipUfNf1ZHD9iAgknHssccWt9cXYWmpNoO2orbF9v59+/YtEuK77757kuypLU7i2MiDiLjIFG1WE8+5r4Qrza8+DlSO1GbOj7SclVCuSsmjtoBQfnlWXyebrR+oG+pKCxHkP682+SVvBx98cPG3x8+oNb+vRn524dwFCFQVYVlrrbW8carzU2NtKWFRQ5aGRUNC/Hh1qbNENY1BWMHcw1Q3AtKisASe4SA6wT322KO402lzbUBfd7JZBqul8xymWGon5ZZ2qiIsu+yyi+eLtgrBVvunzeo+r4JFvy/yxz1CUnlmng8Ckot3+NE7bLl1ZdmU/zzkpa04CEthSzzUgwhKqbLxrq3pdUY4lYXfqo7VSHuqln5spGHivusQqGrCoh9YS1YJqQoQEvoKZv8WflTqKBEC2SEhwrVUsCiNsCsPAXVsHOHAPhy0C3ZD5rTmlhjaCBdaFi42nSMOvlpvuummyaIQAWpJ21LebrnlFjviiCOM1W1//etf7cgjj/QrvZdbUzY7uHI15ac970rFzw6ycie/3P/tb3/zPBxyyCFeLsp26KGH+rsBAwb4O8LhnuZH8aRurbkvFZ486WpNXKX8loq/lL+2urUlfnAEb7Dkns0M2RiPe13Ee9xxx7k/1REaR97z3NL8tiV/LY27lD9+D/fdd59/XKa/J35jIvuT/QDDIZcIVA1hSb98pWFpDWFRQ6bzF2FBi4JQgaXzlZd+qaJ9wRBOYXNZw5GpsiGgzu2iiy7yk5dpGxzpwGqK5oxIBUtFOQRRcwMuueSSooaOdkQnmrYnwqXPzaVTye/TcmZxyJYrhmKziLT/mfatOpBdKtZKbJP6AGiuXZUqb7jlB4GKIyw0ODU+YNQ9Ew41JIQaE7IiwsLutRgJnKbglx+WmWoPAggQl+LlMETmIGCUflNxxrvqQIC6piNnO3YNC6F9W3jhhYvL3LMdPWHUppicyOaDEB3aEmGZyIjJhqsOxKIUgUAgEAiUD4GKIywUnc6dKxUGnPez4YYbFoVBSliuu+46R4yvsqYMO9xiIDhzzDGHEx6GgDSOi6BZdtlli4fVMSYqYRQCpylkq+edNCUvvfSSrbLKKt7eaBcsd0aNzhb7tEvaBnOhRo0a5apoVlUsvvji7p82xfDijjvuWNySX/FWD1JRkkAgEAgEyotAxRAWERSKT+fO2T8svXv99deNbfnZI0Nfr3y5spoAooEwOeWUU+yzzz7zbfVfe+01S69XX33Vn/n6ZfwTQoJmRfNWID6aWIZm5eOPP/b9CJQfhFOY7oEAdU3bE7mg7UA6GC5UW4OUrLbaaq6BweZab731jFOZaVO0Rw7W5JyaaEPdo91EKQOBQKA8CFQUYZEWgzX1HEZI54+g0Ox2PYtg8MwlbUspW35kE5+Ej1YErbDCCnbhhRcWh4HQqqREJRVi5amWiCVvCKR1Tn3TFqWxYxWahg9FStTusNUeOQ38gAMOsLfffnuS4hFP2p4meRkPgUAgEAgEAo5AxRAWcqtO/fvvv/fTUXv06OFnu/DFusQSS7h2hG3zl1xySXdHW7Lccsv5Fy3v8Vfqwn/v3r3dLyczs/qDL2cmU3IAGNoZTDr8I/KE8FK+3FP8q1oEqHPVuwqp5zfffNPno6D1YyXFiiuuaIsttpixIzIbV7EZFxqZ7NJK2o7iUJxhBwKBQCAQCEyOQMUQFogBm3eJHAwbNsx+/PFHFwA///yzjRgxwg8k5J6DCXnP/Q8//ODPzCXAT6lr5MiR7p8lq1yET8mJvqhxY16C8hDCZvIGVa0uaZ1TRq1SkeYFG+JBW6GN0M4g1tpwTrjgRwRFYRSH/IQdCAQCgUAgMDkCFUNYJs/6pC4IgbTjl1DAlrCZNETpJ2lMsLkaMwgs0sMorcb8hnt1IJC2L0ok0oJNW8m2NbU7ubNcXm6EJz6uaD/V0T6iFIFAINCxCFQMYVGnntq6TyFKiQbCAT+6Un/Ze/xKmDR2rzBpfEpD78KubgQgGCmRTes/2x6zz9WNTJQuEAgEAoGORaBiCEvHwhCxBwKBQCAQCAQCgUCeEQjCkufaibwFAoFAIBAIBAKBgCMQhCUaQiAQCAQCgUAgEAjkHoEgLLmvoshgIBAIBAKBQCAQCARhiTYQCAQCgUAgEAgEArlHIAhL7qsoMhgIBAKBQCAQCAQCQViiDQQCgUAgEAgEAoFA7hEIwpL7KooMBgKBQCAQCAQCgUAQlmgDgUAgEAgEAoFAIJB7BIKw5L6KIoOBQCAQCAQCgUAgEIQl2kAgEAgEAoFAIBAI5B6BICy5r6LIYCAQCAQCgUAgEAgEYYk2EAgEAoFAIBAIBAK5RyAIS+6rKDIYCAQCgUAgEAgEAkFYog0EAoFAIBAIBAKBQO4RCMKS+yqKDAYCgUAgEAgEAoFAEJactoFCodBkzngvP+l9k4HiZSAQCAQCgUAgUKEIBGGp0Iqrq6uz+vp6z31tbW3xvkKLE9kOBAKBQCAQCASaRCAIS5Pw5OOlNCnkJtWmcA9xSd/nI8eRi0AgEAgEAoFAoLwIBGEpL54dEluqSUGbgsFN7uPHjze5d0gGItJAIBAIBAKBQKCLEQjC0sUV0FjyzWlNeA9hac5fY/GHeyAQCAQCgUAgUEkIBGGpgNoSKfn222/to48+sjFjxhRzzTu9LzrGTSAQCAQCgUAgUGUIBGHJeYWKjPz444/Wr18/W2KJJeyVV17xXDMUpGGhnBcjshcIBAKBQCAQCLQLgSAs7YKv/IGlMRFRqamp8UTuvfdem2eeeax379727rvvultMuC0//hFjIBAIBAKBQD4RCMKSo3pJJ9Jy/8svv9gjjzxiW2yxhc0yyyz2m9/8xvr06WNvvvmm51qEReRGRdHcFtxjybNQCTsQaDsC2d+YnmW3PeYIGQgEAi1FIAhLS5HqJH+QkF9//dVTGzFihN19991200032ZAhQ2zuuee2FVZYwd566y1/DzGBkKTEhPBcGGz8hAkEAoHyIaDfXPlijJgCgUCgJQgEYWkJSp3gh6GfUkuTRT5effVVn7+y5JJL2ttvv+05goykpIR7tC+PPvqo/e9//7PHHnvMXn75ZYP4hAkEAoHyIJD9CAgtS3lwjVgCgeYQCMLSHEKd+J6OT50f5CMlIy+++KITlqWXXtreeecdz1U63PPGG2/YwQcfbPPNN58PHU011VRuL7vssk5aCEB8YQKBQKD1CDRGUkLb0nosI0Qg0FYEgrC0FbkOCifCouhZCYR57rnnbMEFF7RevXpNMulWk3Ivuugim3322Z2k4G/llVc2tDG77LKLvf/++x5HttNVGmEHAoFAyxBIf0P8VtPnlsUQvgKBQKCtCARhaStyZQ5Hx5eSFT1LKwJhWWyxxQyNieawQGbGjRvnObn66qttrrnmcsICecGkGpg07jJnPaILBLoFAo1pU+K31S2qPwqZAwSCsOSgEsiCOj2ISvrVpgm4DAlBWNCaaJUQHagIy//93//ZnHPO6YTlkksu8VIRVvGlceakyJGNQKCiENBvlEzrt8U9HxXpu4oqVGQ2EKggBIKw5LSy6AC5pGF54YUXbJFFFrFlllmmOIeFdxoyuuKKK4pDQueff76XSnHktIiRrUCgYhAQIdHvjb2Qhg0bFkSlYmowMloNCARhyXktirA8//zzRcKSrhJSB3rllVfaHHPM4RqWCy64oFiq7777zs4++2w75JBDbODAgfa3v/3NjjrqKPvrX/9avI488khr7iKMrtSv4kndSt0rrGz5ScNn3+Enfa8w8nf00Ud7eY444gjj4r3eKWwahrIfeuihk5T1mGOO8WfSkd9StuLFTt+Xyl/6Xvdp+DQOhdd75ePYY4+1Aw880CgjF/HIT6nwLXmvvLTFVr4UlmcwV/7l3lV2ik0WH/JEPnH/4Ycfir+N1mod+S0qDEO07D6NEZkpRhw3gUAg0CEIBGHpEFjLF6kIy0svvWSLLrqoLbXUUsVlzbxjWAhz1VVX+T4tbC6nOSy4Q2iY84KGhpVELI9ma3+WO3NxX+q5pe7ZeBSuJbbCpvlQuPQd95SfYTFsPUPiuCgTbrxXOPlXGPzpHWm89tpr/ozgUZqE0b3sNIzcsOUuO33X0vs0LPkjT1zkQ8/Y1F2pOBUeuy3v0zCKK3Xjvjn3xtJubTxZ/9nn5vKR9c+zwoAfGpE99tjDnn32Wf+98NsR0RAJ8Rct+KdweG1sXksLogkvgUAg0EoEgrC0ErDO9i7CguDiHKEVV1yxuEqIjlYalnQOy8UXX+zZpDNtbWfc2eWj808FQFvSb63QSHEB367GSOUnH9mypIK1FDbN4dfc+1JxVpMb5ddvBO0aRCY1La17/BFX6j9bV2m8cR8IBALlRyAIS/kxLWuMdJKY0aNHFzeEY8t+DO+0rPmf//xncQ7LhRde6O+bE3buqUL+pcSC+/YICwQYceTJqJ6VJ8rHhGoJyex7+Qu7eQRU18cdd1xxhZ1w1bvmY5nog7DDhw8vajfTCbgTfcVdIBAIlBuBICzlRrST4tMXnwgLGha27mdI6O9//7vnQkIOW/edlL1cJpMlOcIwD5nN1g+CNOuWh3xWYh5ESpjLwhChDL+d1v429HsbMGBAcXhJ8YUdCAQCHYtAEJaOxbfssSN01QGjKRgzZoynwRwWLWuWhqW1nXHZM1vmCCm3hEwadWsEe0pSiC9V8adxdsW9ypHmES2L6rsr8lQNafKbwTDpVlsCgKl+H8K9JWVVXZxyyik+R4a6ylMbakkZwk8gUKkIBGGpwJqjg6UTpqPUFx/LmrVKSHNY6FzVMVdgMZvMsoQEAp1Jqk888YRPVGVSJReTaXU9+eSTvtuvsFLYJhPoxJcSmCNHjvQ5FtiYaq27ToS2iCM3hx9+eJGwqC20BmP97ogrNCydXYuRXiBgFoSlAlsBHaeE3NixY70EqYZFy5rzJpjLBTXl0lfzU089ZYsvvrgPhU055ZRuMyyma5pppvH7P/7xj8YSb4ywK1d+2huPynLPPffYbLPNZg8++KBHqfoTOW1vOuUOn7bDcsddzviEL0NCrCiTAd+WEhbVhSbwoq3hgFEM7/LWplTGsAOBakIgCEuF16a+FNNVQhoSSjvjcnSo2Y6ZONWRpzCSbupeLoGbloE0MGhTWO4NWVlhhRVs1VVXtVVWWcU4JJJzl1ZffXVbaKGF/ItYhIVwWWyUX9LIvkvTzYb1TEz4l/XXlF8En9JUWR5//HHbdNNNXTNEWL1P00jzlt7jt1T6YC/3rN1Y/tJ4aV9pOOXps88+s2222cZ22203++abbzyLIgZpeDRgad4au0/LWO575Yv9bERYVKbWppUSFpZLtzWe1qYb/gOBQCA0LBXfBjqTsGTBUmdNHhBSmFRY8V5+smHb8pzGpfQQGgsvvLAtsMACxRUgEqppGvKPwNE975kDJIGWkog0LPGVilPupd4RnnS4UtKAX5UjaxMGLBWf7pWO4iGcwhJGq1RIS+7YKhe24sS/7hVfY+XGr/xwjxF2DMOBOWTwk08+8XdKU3mQX5WjIYbScSqM/JTTFg7tISzKn+JiIzq0e5gsRuXMe8QVCAQCExEIDctELCryDmGAKaVhQTDR0epqbwEVH7aEnuxRo0b5VuUjRowwll3jjsDS+/amTXgJDe4lDFn10bNnT1tuueXsww8/9GR4x6Wve4VV+J9//tk0T0RxafIy7zTMxlJy8IUQsA0777C//fZbv4S9JzohT/hlySs7qnLJDzgofdImDtzADX9KH/z0FU+8uJMPjPyyw+pPP/3k4cGae+LA/euvvy6eL6X0CCt/aJlIA//klbTwJ6GLO7hhKCtxf//99+5fuPLuP//5j+M+77zzGpoh4lB65BmsuEiPeEqRqhQTT7CD/olktIewkDXiUXuGpFHPYQKBQKDzEAjC0nlYd0hKEogQFk261ZCQBEIqTNqTCQSWOmzFgxuG06JvvPFGu/POO43t7rWjKO/Klb4EInEqXTQsfOWjZUmPLFDZlT62BDECdsMNN3Shi7vIAmVYf/31jUm6GLbH32KLLezPf/6zb9o3++yz+xyTHj162IILLmiXXnppkZDgn/Q32WQTX61FXbBqi/Of7r33Xo8PoY056KCDbK+99vIzoXbeeWefY/Poo4/6jrZrr722EwD3aGa33HKLD2v95S9/seWXX95mmGEGr2c2EWTOywEHHGDzzDOP78Ez//zz+7ubb77Zg4OByA/Cmjyz9J38/+53v/Nhs8cee6yIJYdmUsY//elPtu2227o/TgAnXsrC3CiVgfkgM800k58QThnYSRbz+eef27rrrmszzzyzv6NuCNuvX79Jho5Ul7Rf3avM5bZFWJh30t4hoVJ56+j8l0oz3AKB7ohAEJYKr/XOJCxApa9MOumUNLzzzjtFJPmiPuecc1wAK0zxZTtuUsGQpo0gRoBzBAEGAsJ7tArkl2fhJHKy6667uvDWvhx33323C/CbbrqpmEOE8hRTTOGEAqE9aNAgu/zyy23ZZZd1t5VXXtlXHykARI3JvpAWyNvBBx/sghsSAIkQeYCwMJzCZGHO42HfHDBDawGh+O9//6so7brrrnPiQLy77767H7vABOt11lnH05pxxhn9PKVbb73ViQL+IK8Y8FKaTDrmHeW+4YYbPC6eIRtDhw51/yeddJJNN9107o98HH/88QYeLOGF4OD/vPPOc7+vv/66u3EY58cff+xukBXmDEGgTjvtNMeA85t4Jiwr2ZSflKik9eoRlflfOQmLCDtxku+OznuZoYjoAoGKRiAIS0VXX8OcB4rQlIalXEVU50ynLSEAUTn33HOLgltf4BCAp59+2pNWuPbmI41HhIWly5AVBCLDQghQLibcot3gKIPFFlvMyQPDHTJs0Q6RgDwgPCEDCO90Yi7CFsICWbnrrruKwgkNDWSDoSiOTMBAUEgfoSzDEA744I7G4eGHH/ZXHEQ5/fTT++Rgzg6SATOIzAMPPCAnj3eWWWaxvn372ldffVV0Zw4FZR48eHBRc/TBBx94eDQlGJE0lrmjOWL1ERiCHTZlJx+QHcypp57qhAXNybXXXuvaNOF84okneno77rijDyl99NFHrtVacskli4TlkUceccIFkfvyyy89Tv5ByPAH2ZGWS3WpvBQ9d8CN2mo5NCzCg7YE+VU5OiDbEWUgEAhkEAjCkgGk0h4llDqTsCAA9KV8//33+9e0hKmEA8RFeSsXpqlwkOBgSIhVQhACNBpoAxjKgWygEWG/jMMOO8y1CpoLorD4h5AQdtZZZ/WjD8ir5rAg4HhHGTGEU7khSoThBGzmjqy11lou0DUUprKjOWGYB3KBZgOz//7720YbbWSstMHIL6QIwpJqWK655honTJrgKQ0R5+IQ52WXXeZx8A+N0nzzzWfahwc3VvDglj0QE9IJHryDcGLOOussj5PhJ2ElgkGcYLXnnnu6oOYgTbQuHMapciDEWeU07bTTumbGI03+gZ3aR+Lc4bdKsz2ERW1PGhaG8KSZIn697/DCRAKBQDdGNud9nQAAIABJREFUIAhLhVe+hF1nEBagQugguNVxMwzDEIW+qHmHUEX4MmyAoTMvR4eexiHSwZAOQ0IIzvfff9/TU978IfmHYOGd4mHS5Pbbb+9CGgKgibgiJf3797fNN9/c52UQDVinZV9zzTWNYSMEtQgL8bFBGfNeiJM4+vTp49oYNBCYfffd14dvGEJRvNj33XefExbtw4Ibmhs0OZpXIw0W2hEIC/NoZMgH2iXmmqiMn376qWuDVlttNSduDA1BSMjXPvvs45oPhp0waFiIEw0Q5AcjLIiTd2iieIfmCM0TmhPSkDn77LOdQKLRQWMFPrQD2ofIj+qHPOpe4TvCLgdhIV9pXsFFGHdEniPOQCAQmByBICyTY1JRLk0RFoSrOlXZ5S6ciMPLL7/s8y2YuMqEVgSXBEU50xbhULpoWCAsDNG89957Xjy940H+03IrX3fccYcPFyGIEeRoQzAiBQh1BK80CFmyhuaEoRm0GMzdmGqqqXzYBcLGKiAIBKtseCZNkQCIwu9///uioJcgh6gwIVZDR+QFwkL5tEmZ8ibCkmpOWP2DX026BnfyBrE4/fTTnTCkq34Y/iJPIiVnnnmmkxIIl7RMSu/888+3qaee2vddYagLDQvxot0SYSE92iMXZBAMmNdDXpkUvfXWW9sXX3zhGKtN4DclAv6yzP9U32hYdFqz0m9tUgqXEha5tTau8B8IBAKtQyAIS+vwyp3vriYsEjasvkB4Mn8CTYKGFOjYJTDaAx5CQRfxiJSgYWGOCvNVsquElLc0XdzID3HtsMMOPqyBQGVohNUxCGPFzXDSb3/7WydiikN4s/KHXXRZfYNwRxMD8XnmmWfca5o27yETIgGkw0oaaVhECiAsTFDNzmFh6TCreTDye+CBB3p6OuiSdxAQiFuqdWG4ijk+IjaUjbxJyFJPGmaCZFIGiJrIm8oLYeHdH/7wByc5aNY0JMR8FhkIkMpJOgrP5F0IHUNcGNzVLrhP8VJc5bKVTnuGhFLMiE/lAk9hWa78RjyBQCBQGoEgLKVxqRhXdZylhoTSzrSzOlUEqgREmn65ASVuDBuYoVVgKIRJpxjSz5ZXAkfh0GKwM64mybI8mCW4GnohHubBIKSZ9IqgVbkYumEVDcNQ+mJnWIwJrGhkpEUgDkgUZGaNNdYoLqlFm5P6Ux0y6RYSwPwIGWlYNIFZZID5N+RNq3bwDymCsLBCByO/PKMNYWdaDd2hAYE4sVRaQ1VnnHGGx4mGBeKGkfaFOSwQNFYZ8Q7CQpyQIa0SAguGyXbaaadJMCAtJvZqMq9HPEH7Vaqu9L5ctuqtPYSF9sSluCCKqvty5TPiCQQCgaYRCMLSND65fythV4qwSEirs+3IwjCsoc4cm7SVPiSB+/YYxUUc3KvcEBY0LJp0y0Tb4447zljVwsUEXJ4hH0yUxTB8BeFAYEsTxGod9hxhfgkCFkMYSAjEgL1E9ttvP5/IC7HBjWEdkSS0G9ttt527MyRGWDQWmtvCah7NkUHoc4SAhpo0JARhgQRo3xbyoHplyTNGfiFY5EGaE96xwRtDL9KwiJwxt4fVUvgnP8xVkUZo77339nCEZ1kzfign5AcjwsKQEu/IO5hBWCCK7AuDRoYJqNrED2LDUBlhKLcmHbMUW/OMiLe9bcIz2IJ/apftISxKRnGxHF0ToTvj96X0ww4EujMCQVgqvPYluCXYECqawyAh35kdKvmRoATajkpbaUA0Nt54Y5+siraAM4S4mAyKjcaBZcUMtaAFwTC8wZwTaS2EIfNEGCZi2TIGocTQDZNn0ZAQl+Jl2fS///3vIinDPwSEDeHQOpA2K36Y7MqkVoZmJPzZ34SJr1plInfSh+xopRFxshEfK2+04Zn8EgfDWOzvIsFPGhtssEFxhQ7kRkNIQ4YMcW0KWHChHUIboiEs0kKLwtAaK600TCT7tttu87Kz4grNDYQF3NFSQbJEqBhG6927t2urwAscmOeCRindq4f0MOQdEkA76SgjklEOwqJ2h9YKDYueOyrvEW8gEAhMRCAIy0QsKvJOwhbCghagqwmLBE+WuLQXXAS1ykpcCCEJatxJFwEtgY6dEjY9N5Yv3PVOWgxWy0AANEeD+JRmWh6lg/BK85Xe41/kjbykgk5x4qY05JdwkA75V1q4cy935YdwKituaR4gH/jnooxKlzAYbPxjwCJ9z73eYeOXeJQHxeGBJ8RFvrPviVd+03uF6whb+W7v1vzkG2wxDJuJ8HZEniPOQCAQmByBICyTY1JRLnT6mKYIS2cUiM5cggghpWfuy2mIt7E4lX42PQSWwkjI4gc3CV+FQZBr7gcTWxnG0OF+EuJKh7h0L5s4dS+bcAg6PZOW7hWn0k/D45bmnXxJ+Kb+Uj9p3Om9ypn1i5/GypG6Z/3xjEnzMcHJLZWPB6Wt+GTzLvWXhi/nPelj2kNYlGfFxTAjK9Qw1GFnlMMTi3+BQDdGIAhLhVc+nSUmD4SFfKQdtzr5ckBMXAjHbBpKTzZ+8IvJCmeFx5bgUTj8K78iLMzNYP6FJpUqfJZkZPOEP8Wbajua8peGSbUfhElNikOp8ildwvA+fVY8uHGlaZbyh//Uj8Kn8ab3ei87GzZ9TnFpKg7F1R6b+DEpYWlrfNK+MbyUTo5ua3wRLhAIBFqOQBCWlmOVS58pYenoww9zCUCSqVQgZgVy4s2FMH4bM5r3wXwNzgVK9xlROIiDiFFj8SgPjb1vqzt5SMuqeFLSoXvZ8iO7sTj0vprsUoSlMVwaK7f8q/6ZuM0+M2ECgUCg8xAIwtJ5WHdISkFYGmAVeQAPYcLXsIQV7yV0VBF6lo07/iSUEEgffvhhceIq7/UOW+HkJk0B7npHmPReabfFzsarOLJlS/0JD+VBeVTY7LPcq8lWG0g1LMKjNeVUmMaG91oTV/gNBAKB1iMQhKX1mOUqhIRzXlYJdSU4KYlIhTgYSWiRP96lgjoNx3sEUzrRta1lkoBra/hS4dI403zjnpaZexEp4tG9wqd+5VYqvWpwU923l7CkmNGmqh23aqj7KEN1IRCEpcLrMwhLQwVKeCNEdM+b7H0qdNJ3+M0KIPmVO3Z6T5isH+LkSk02nfRdW+9LpUNeMGl65DedE0N7SfOn/Lc1H5UQToSlHMuaVd6ff/65SIKzGhf5CTsQCATKi0AQlvLi2emxBWGZCLnIxESXhjtN8EwFedaPwiLcJOAa8yN3heE5vU/fE1epd/LTGltEI42P+OVeKi5pAtKyp+GDsJRCrXE3TbrlRG0drdC473gTCAQC5UQgCEs50eyCuIKwNIAu7QIHDp5zzjm+Iyube7H7KyYlIpzVc9ZZZxUFDrvV8vXNTq+Ex7RGkEOIGELiHB3CpeTAIyvTv1LkROXmuAAmCbNxnQ5KJFnICX7I4wknnOCHM4rgsIHeP//5z+KhjCmRKVOWcxENuGHKpWERCVThhKeeww4EAoGOQSAIS8fg2mmxBmFpgBqBjGGXVg4sZAM9ts7XVvAILX0dDxw40HdgZSt5DLu0smssu7+m/kUG8COhhFDXxXvuWQbNDrnsfqsDGHEnjMJ5Qu38R1zEK6P8MTm4T58+XmbKzXwmGeWBTePYkRYSpzjYpn+33XYzhjcwclfYarHLRVhU39WCS5QjEKg0BIKwVFqNZfLbPsKC8JsoABvu02clxpwMrlLv5Kd5e2JqE+8mDSX3Brtg/DWeK4WV4Ga/FLaFR3hjs/3+u+++694Q3FquzPk2vOccIgwnIUNYOG9Hm8S1hGjIz9dff+1b8EMWtJmYhCTx46+cZECCU+W+4IILbNZZZ7Wtt97ajyC4/PLLvVykiR/Sh9Cx7f6ZZ55ZJFFsrc/5R2zpjylnHj3CnPxTXZRDw5JiSvFUFzkpamQjEKhqBIKwVHj1NkVY1JnSybowSjhHocADqnKuCQShwN4iNVbPHiM1dVZfW2+F+jor1KO9YIM6wkxuivFP/spdiL2uUO9XbX2t1daPs4LVWr3VW90EYU5+6utrrb5QY3WF8VZXqLHaeu7rrLZQsBrylJnMquSEwfXXX+9aBg4w5BRjjirQuUr4lYYFLQPkRBoWTm6ed955neBoXoLIgOOmhCbYIipK97333nMCBGG55ZZb3BfhFcdPP/3kw0+clMx5QyJOeCwVf5pciq38pnFDNjjviLQfeugh22qrrWzZZZctHsqIX8JBWDjjiKEw5Z89ZtAMkb+W5CXNVyXdl5OwqM45dFJkuJKwiLwGApWMQBCWSq69CduCU4RSy5olrHjvwi5LWAo1ZlxWazW1Y622fjQn15gV6orKlJqacVZX/6sTlkKhQfhJiLbErocsOdUpOEGptzqrtxq/6goNpAXiwh8kpmAQlV+ttn6sk5aGNxP1O2mZEB48S4hcdtllNuOMM/pcFMrMkBDnAem9ho04CBCh/vzzz3vtQ1g4qBASoyEhXuCf+DFKN9WWKF5OfYYwzDLLLG5zGrLecZAiBwROO+201qNHD5tiiin84MNhw4Z5vCIPXj/uUvofQhc/yg/zZTAMgREnw1lffPGF3XDDDV4WnXOjcJAkTrU+44wzinGgYQnCUhrvxlxFfjiNOz04sjH/4R4IBALlQyAIS/mw7JKYJBhbQlhSoVhfDynhYpnrGBtf85ONr/3aCvaT1dePtfHjx1lN3XgbVzfWxhXGWp2NNyhHKeOEBGFa38hVqLcGzUqN1VnDVVsYb5Nc9ePRtzhhMRtrhQJXrf3K+Tnja52xSFhn8yAMLrnkEp+b8sQTT7iXLbbYwk8K5kRnjLbcR8gzJJRqWCATnPasIaHG0iIehJaIC/bdd9/twy2QloMOOsjefPNNT4/TiVdZZRUnMdNMM41xQajwx1k0OglZxM8DNfFPpAkvIl+DBg3y+LAxTL6deeaZDYEqP9ikxanJEBaRpI022si233770LA0gXn6CvzV1pjg/OSTT/rrltZfGlfcBwKBQOsRCMLSesxyFUIdaCnCIqGqDrXBhnQwp4Khnlof7qmpGWVmo+3mWy61DTf+va23/g624Sb9bf1N/mLrbNzf1tuswV5n/f623gYHFa911z/Q1lnvAL9wX3/DQyZch9r6G+qS28G2/kYH2nobHWDrb3KArbfJAbbuxv1tnY32t3U23M827nuQrbDSdvaXAwfZ0G+/tYJxOjPangLjSZOMRlEuhncoj4Q+JGHxxRc35qeIbKDdmG222ezEE0/0OtPXMX7QprC9OuaRRx5x7cdKK61UPDcIDYb8C8dsxUvwM2mV+TJoOjQvBm3HeuutZ9NNN53dfPPNxjwXJuRis1oH0sIKHUxj8WfT0zPES+SLSbNMphVJws/OO+9sCy+8sL3xxhseRHiV0rDEHBah2rydEpbjjz/eXnnlFQ+k31fzMYSPQCAQaA8CQVjag14OwraUsEgoMk+EYZeGOSkMd9TZ+Jox/nzhxRfYPPOtZDPPvY9NO+9gm2qe022qHufYFPOe5fZU855vv53vIr+m6XGhpddU815gU/p1oU05L9dFE66G56l68Iyf822qHufalPOebVPOe4ZN3eNMm3LeM23mnufYb2Y53DbZ8iJ75+ORPjhUi9albrwV6up9iAqBIZIA9AgKkZO+ffu6lkOrdHjP/TLLLGNzzz13UZuCO9qIdNItxOZ3v/uda1iyBx0Kt2xVk67mxLAUerXVVnMSoqEYNDULLbSQzynRKhzCSOuxxhpreJivvvrKo6YsLTUiUmhTmGzLZFLyIncRIuarqH3wHkKXnXQbGpaWot7gTxiDuYYUWxdD+A4EAoG2IhCEpa3I5SScBBIaFiaZ8uWuiaYStvoCbLAZdtEkWshLw/yVgtXZbXfcbquttasttPSJtnDv623B3nfYfMveZQut+ID17H2fLbDcfdZzuftt/mXvL9q/W+Ze48JtgeXutwV6cT1gPXs9OImN2/y9HvD38/e61xbofbct0PtO69n7Tluw993Ws9ctNsdC59tu+9xjH3/NLBfzSbdogZgAXGo0atQoNENmt912m0+aRYOwyy672KabbmpbbrmlMUcDgQ4mp59+uo0ezRwd8zku2SGhnj17OmH56KOP3A+TWdGGQEawWTr8zTff+MUkVZ41WZV7NDbTTz99cZXQd99951qOq666yuODrKTXOuus4/liTxjqRXETjr1jdJE+eRk6dKjnQ4QHArL33nu7BodJt/369fMVP9tss41Prk3bARnQHJaUsDDpdscddyyWozWkyQtVIf9SkvHqq696rttaVv3ejjjiCNPQY4XAENkMBCoegSAsFV6F6kCbIiwU0Tvo4hQUNCsNK4TQttQxZ6V2pI0Z/5ONrTX7ZXzBRowp2PBfCjZ8TMG+/bnefhpRsNG/FOyX0QUbParhGjW6YLpGjirYiOQaNrJguoaPKhjXiNEFG8b9LwUbxn1yjRzT8H7kLwUbV0/u6q2mZrzVjBuPEqhIWFJBI+HNqh/tvYKgnnrqqf1iiIZ73Bg60QogJt1CMDR8w66lzGFhHxU2kSPetdde28MxkRbSM8MMM7hNOpyKzXyUlVde2Sfp4l9zVSTEODSRpdIXX3yxtzCEpggLdbbhhht6/K+//rrdeuutrgWacsopfY4LaXEx34WLPPA8++yz+/AVERLfqquu6nFQRspKOZncKyx23313X5WE/yAs5dk4TuTn9ttv94MxvXLjXyAQCHQKAkFYOgXmjkukKcKCgJSAd20Lc0HcwFzQtLCMGG0LE2qZWDvCaq3WxtebjRlfcOLyS43ZmFqzX2vNxteY1Uy4uOcaV2P26/jCpBdumWss8Y0rOCGCFHH9Wtdwja0x4z1za1Gm1Nb7LBvPe6GuYHVkqGGxjpOJtFxoIjbffHNDQ8KEUoT/1VdfbWg2WObMhFiIxU477eQaCorPjras3NGeKQwJaR+WTz/91BG6//77feUVRJC4rr32Wo8X+9///rfPP8EPc2gY8tHGbc8995yHR+uCxufss8/2Z/5BGkSymN8CwWAIiTKwuoe0iL/Udd1113n6aGIw+Jlppplsjz328PxQVvJ1xRVXeJkpI+Tl3nvvdf+kzZBQuqw5Vgk5NK36p99T1m5VJOE5EAgE2oRAEJY2wZafQC0lLOpgG3IOcdEFeUHbUmMF+3XCkuMGfuAzXCbMefV5r8x9hUxMuHAr51VP/IXiiuqJIE/IajrNQ4KfbeiZfwI5YFUOhrLyJYyQxvTv39/JwTXXXOPPTMJlSEiTbtGwQFiYdKtVQhpOU3yyUxyFPUM20rBo5RFDS8yfWXLJJYv7dejrHE0Py6gPPPDAIoFJ4/VMZv6JpKncKtO//vUv96n8Kk/M32EyLloYhrQIx8ZxECjiwkCamHSroa3m8pDJUsU8CnfmnaQTZVtbADDGCGvuwbtacWstPuE/EOhoBIKwdDTCHRy/BFSpISEJObLQeKcKG5DGBdLCvJZJd5gVtckWRe5ZW/6y7s09K9xkNiRmgnYI4UO5JHQZ1oFs7LfffsUVQxIsElRs5sbQChoF8GLTL7QumiArDQtaFxGWFLtsfsCSS+mwIoj4GNJhXon252CeA25sZPf3v//dWFmChoPhKOYbPfvssx5143WTTblBQOLKcA9DU0pLcWCTdzQ/2267raeP5gUDeTr55JOL2DHXh7OHuhNhae8cFtX5XXfdVdTYyW3y2gqXQCAQKCcCQVjKiWYXxNUUYaEjRYDpajx7ohIQF+7zbSiPhASTTJmzAenAQFJ4j5E/lihvsMEGrmVhbsm5557rGhkNCbHahp1u0YgwhwWj+EthByEQttgjR440JrAyxMPFcIxWEO2///5OGnCfaqqp/B7tioZqyK/S8oSb+Cd/CEvm1UDSSFuGNMmb2gTkhHQhTkxQRsPCHjR6v+aaaxqrq9AQYYSb4qsWW8S1PVvzC3tpuJg3JfJTLThFOQKBvCMQhCXvNdRM/iR80LDwxY2AamyVUDNRVdRrhnsQRGhLJPxVgJRkIMAxzC0ZMGCAr+559NFHfXkvmhEMQzRMxGUFTVZ4I6gkyNN7DzhByPOe4SjigESwc67qBX9MvD300EPtmGOO8eEpTfblXak4FXfWVlnIP2Vhm3+M8sd77iVUGeo64IADHB/IDMNBTz31VNE/c32uvPJKJzNpPNl0K/25HIQFDKgrYSxMwBX3MIFAINDxCARh6XiMOzQFCcZqJywICgmGVMhLWGPrve71ThWQhsNNBACBxpUKI8WlsNiKL7V1z3vqIhuOeFM/SjfrlqZT6p54S8VVKj7lIcUs6w9SI3+l0qsmN3DDtEfDkrYN4qKuVYfZd9WEXZQlEMgTAkFY8lQbbchLSwhLG6LNZRAJbGyEREuNBEvqvxS54H0p4YNgT+Mo5Yc8iQBk/ROv3JTvNP1S8aV5Te9Tv2ma3ENC0nwqXEpO0veESZ/lv9psyok5+uiji8M4bSk3dcilOgztSrW1lChP3hEIwpL3Gmomf92FsCAkJCiAJBUczQkfvZew51kXcSHQwJH3xIvhPfcKm/qXm3tMNC/ZPPJe80q4T+NWWOVJzy2x03ymZCTNL/GQzzR+3qf+5SdbnpbkoZL8lIuwCE/KzrwnTdCuJCwir4FAJSMQhKWSa2+CapoiNDUkVOFFnCz7qcBOX6Yag8b8yD+CGz+pQSCVEt6pW+onJQgiIylBUNxpGGlWRB7SuOW/ObuxNAin+NK8penjR3ngvlRczaVfae9LEZa2lkFxMSdJe+60Na4IFwgEAq1DIAhL6/DKne+WaFiyAit3hWhDhiSY07IhfFPioPtUeKf3JJuGSd+l8cuf3NLslnJL3zcVtjmykL5P86Y4cWvMpLjgLxte5E7ushVf+pzeq7xp3hQGOyVDPMt/Ng7cccNk48Jd79xDEo+e03BKI32X3otktHdIiDjRmGHYy0erzEi/uTyk+Yn7QCAQaBsCQVjahltuQnUXwpIKPMBPBQTv0qGO1G/qrkqTgEz96V0pO01LaaduusfWPXGLFBCmqbSy75Q/hUvjyRIC+VG6PMvIjfgx2ISXu/yldpoX/JEXrsbCpXGn8aZDYYo/LRdu+E/jTcNzT92pvHpHHAqrtBV/Y3Y5CIvSF2GJs4QaQzvcA4GOQyAIS8dh2ykx06FjmhoSorNVh9spmerARCRQZadJlXLjPQJLQiv1r3uEYEoK5C6beHmfCle9w87iKyHLO8JJyKZhssIbf6STNWm9lSofy7vT+NN4S/lX/PhLw8ld6aXx6J38E28aXmGEQ5qucE3jk3/iTe/TdLLu2edSaSh81iYPmPZoWJSeMGA/G5an6zmbZjwHAoFA+REIwlJ+TDs1xu5CWLICPX1GmGBSoYYbfvgi1ntVjJ55x1c8BsEjd+4Ji53GqfDYuKfvuFd43nOv93LnOavxSf0pfqVN+qXyoLRSW2GVpvIod+Lk4n02ThGs1J17DPnNhkn9KT3ZaXoqN6RK9+QBgy03ntPwuHPhJhs/8o+tfHlkzfxTmu1Z1qw86vd20EEHGcdChAkEAoHOQyAIS+dh3SEpqQPtLhoWQERgSgi99tprvlvr9NNP79vei4BIAMofm639/ve/N52mLIHckkpJhSbxKm7CZp+z8aV+s+/Ig4Qw79J0FDd2Wt7G4ssSoTStxsJI8AuLH374wc8W4gwiDkqcbbbZbODAgX4itfyk8Sr/2EpDttolp1Fz5AHnFn311VcenPOLll566eK5PoqbulL4bDo8p1jx3Jj/NKz8YbeXsJBPtSc23GPX5DCBQCDQeQgEYek8rDskJQmGaicsqSDjXkKOAwx79erlO/xyACGH/mHkRwSG044XXHBBe+SRR/w9wo84UkHPPQIpSxwUX5oHjyTRDJQKIz/Zd9l4yEfWjbDULWFldI9fCU6+8o899lh7/vnn5a2Y/zTOrHBXOQnE0QWcas1BibPMMovvxnvppZfan/70Jz/zaJpppjFOps6aFDu9U1mVNiTl1FNP9ZOmOdV69OjRxfp64403PBh+KavCpPeKtzGMeK9w8pu1hVV7CYvSSeulVF6z6cdzIBAIlAeBICzlwbHLYqHDxFQ7YRHAElzYGA4Q5KTmqaee2s/p0bEEEi5jx451fxyAuMQSSxjb1WNKCdtUEKUC3QNkNCASzLxTWriJVChMauNP+U7TSv0oPsWTzlGRG7Ymf6IB4TgGSAHnCikvSkvPSoOwXLhLkHO8wRRTTOGHNL755ptFIge54HRjTrH+4x//aMOGDfNoFIfilC3hTdxKlzSUFuE402i55Zbzc5V0Fo/yoXiastPhpWwajYVT/O0lLCof6agdNpZmuAcCgUD5EQjCUn5MOzVGOlFMJREWHbWY2pOC1vgb+ZPgZ0iI05rXX399Gzx4sJMXtAMYBCTEBANh6dmzZ5GwpALn+++/t2uvvdbP2slOpMSf0vroo4/spptuMuKHGD3wwAOuMVBa2A899JCfHUScnEt02WWXuXZCxIk8yd95551nt912m40YMcLdJIB5UJpoPjiLiDTfe+8996f3hNt1112dsHD4ImVEi9GUIQ2lo4MTDznkEI+D/MjIH/mlHBykyPCODGnppOhPP/3Ubr75ZsdPm6kpDU6C5swiNlpDkwMOEBYIkgiL6ohhuzvvvLOIqeL49ttv7V//+pdj8I9//MPPg1I+0nqUW9YuF2HJxqv8qU6z7+M5EAgEyotAEJby4tnpsbWJsCAzJ440WH3BrK6+YPVMcuSk4wmXbmvr6t1PSiNacl9vBT/7mY7dBXA9JKJgtfV1Nr6+1moKtVZn9Z4Vj88nWdaZFWqtUM8QAXM86qxQR54majIAWQKdvTA4aXmdddYxBG6PHj1so4028gMN8SdhiEBddNFF7T//+Y/XkXC79dZb/STnGWaYwYX2UkstZccdd1xRKErYQQ62335798Pp0AyTTDnllHb55ZcX88LXP3M10HhAXA4++GAERjlfAAAgAElEQVS/32qrrezLL7/0dJ988kkfcpl99tn9HfbWW29tEC9MESszJwAzzzyz+yNOhrwk5PGLtoiTn3nHSdDMC3n33Xc9HuWbcmYFqoQ8+cWwRJc4LrjgAn/WPwlkPROncFtooYV8TghEefXVV7dpp53W4+jdu7edfvrpBlHBMFRFnUBSOGSStLknvbQsbMKGBuyf//xnUQNEvsnjHnvs4QQHvAm3ww47FOMnP9l8Kr+yhQUaFjRGmObCKGzWVruDhH3wwcQ5LBMOCPf2nYYh7UKBHxstPEwgEAi0B4EgLO1BLwdhJUBKaVgkmMgmnT8dZ7Gjrjcr1OHewE9qaplQWGf1NbVW+HW8FX6tscK4uoaLhR2MwEAc2ngVagvmV02dFWq5av0yhnaYfDpuvBVqas3o3As1Nr5mjNXVjrf6ulqrY2XJBM2A8i/BAWFhbgpkhC/9Sy65xIUamg2MCAvEZJFFFikSFt4h8AkLAYFUbL755jbjjDP6PA40AhgJO05hRlgikCEYe+65p2255ZY+FHXGGWf4EA15Y2Iv2oPDDz/c1lxzzSKRQktBXGussYbHg0Zo9913d7JFvCeccILHQX4pG6SJicT4J60NN9zQSQH5ZeKw8qUhIXZehSQQtqGuJ2pSGoRmwzyRlLxoWAnMIAM77bSTD7GpTQlrhReeaEo23nhjJ22Ude6557ZtttnG0PJA5Jhk+/HHHzt+ELS55prL58d8/fXXPmy17LLLOgbMP8KQ7yWXXNL69OlT3O5eeTvyyCPd7/LLL+9DVssss4w/9+vXz7755hsPD2bKqztk/gmr9gwJ6bekuCCqb775VialUo8ptS/1PtwCgUCgpQgEYWkpUjn1J+HSFGGhM6+rq7VatBbSZ0AA6rjMasej1TB77ZXX7KKzz7OLTj7Nrhhyll0x+Az7x4CT7dLjTrLLTjjVLj35DLv4lDP9uujkM4zrwpNOb9F10Umn2YUnndpwDR5iPDe4NbhfNOQ0O+/EwfbgbbfZL6NHuN6lrrbGyUyDOqiBcKkaUsLC1z5khPkXGIT/pptuam+9NVGgMJTDXBeGcTAIOYgA5AM3BCRzNBiiQbCtttpq9uCDD7rfxx9/3IecIAUMT2DAlCGaFVdc0QW2JpAitCEgkA1IEiYVcpCc0047zViRg4EYMYeEeAYNGuRkg6GneeaZx/785z/7MAr+mLz673//2/P28MMP+9AK7iIs7Lw6ZswYj5M2ATHRhSN5EFnB5pkycHEPeYNEzTHHHLb//vvb8ccfb5AFiNMXX3xR9Id/CMu6667r5WRiLsSDOJjzAlFES3XNNdd4Xp566inXsKD9QcMC7iIsrLJhWInhpnPOOae46kZ1ywRq0oEsfvDBBx4fNnugQIx22WUXH67iBflqzJA3THsIC5hlk0D7x9WgPQFHiNPEZ7nz22sqf43lO9wDgUBgUgSCsEyKR8U9tYSwUCjvXH0ARp3shH62HuFdY4z5XPPPK2yjlVexbXqtaPv2WcP6r7y6HbDSarbf8n3sTyusYnutuJrtufKatleftdxuuF/T9lx5ddurD+6lr71XWcv2XnVN23PV1W2PVVe1vVdbw/ZeZQ3bu88aHnaPlVexPfqsapsuvIid+Kc/209ff+EqHdf2uOZnvNUbK2kmaogk1KRh4QtdhAUCMuussxpf4QhJDMIe7cS9997rz5ANhlOYE4FBoHAh3MAUjQ2CFANZQGOgeSgSgBALhC9paaihb9++LshZ9iqDkMastdZa9oc//MEnnvJMenrHpFbIDloDNA4Mj5C+hm3w3yA0GwSzwkHOIEiQHeVLcWOnBlIm0iIBShi5Me+GOSjMBUJThGaEuCExkC/8Eg7CAqFj2XM6rwV3zL777uuEgiEf6oQhO+qHuqA8EBrC3nHHHZ4OQ0YiJNQr6aCNQVNDWGlryCcXcTCshFZIQ2BqD2l5dS9c2kNYFBe28tBAVlhtBkHkY6DW6gvMKWPeU8OQpkhLGj7uA4FAoG0IBGFpG265CdUUYaFjlWDCRuDTsRd8HIiOt2A1COi6hk729WefslvPO9ueOP10e/H4E+z14wbY2wMH2OsDjrE3ThxobwwebK8NOsleH3xyw3XSyfZ6E9drg0+a+P7kwfbKkBPslVOPt1eGDLLXThlsrw0+0V4ffKK9dPxx9tbpQ+ypgQPsg39fa3XDfzCrG2f149CwNAgI5sP4/JoJyEtAibCwb4iWNDM0hLYAIsEkTgxzDiABWtaMEETo4e/vf/+7DRkyxM4991y/R2Azt4Rhou+++87Do724/vrrfV4J/s4880zXQCDUF1544SJZ0hwWpUP9aHiDuRcIbjQsXBAS5nuQPsMh7H+icE8//bRrjfCPH+bnMMdEmhmRJzQrkAo0IXJDq0GcXEzWPfvssz0sk3chaOeff75P5IVwpQYSlLYZ5t0w3MVwD0SMicaaIIy26qSTTiq2L+JROYmXYSI0VO+8846TDjQsaGrII2WCbJBnhpaYp3PPPfd4VtSeITekgaaK4TU0MOBOPaFVQgPF8J20aGrnaXl0Xw7CAi4Q+7q6hslfaJV++OF7JyY00praX52w1NWPdxvygmZwUo2LchR2IBAItAWBICxtQS1HYdTBlxoSSoUPHToC39XaEybdMtmWCbC19bVWqBtnhV9HWf3o4Vb34w9W89WXVvP5Z1bz2cdW8yXXJ1bzxedW88UXE68vv7Sall5ffW6133zccH39yYT4PrWaLyZcn31itV9/bbXff2f1Y0Y6YSnU1Fnd+ILVkXe6/0QnL8Ly4osvmoaE9LVN9SAcN9hgAx+O4OudYRT8ScPCe7709957b1/Fc8MNN/gqG1a/oI1hGIgwn332mdc2pEETc9GUQF4gEAhmtACaQMpQFARC+5ZQB6ojCBBzUdC+QKSI48YbbzT2iOEZoa3hFxJFC8TkXQgDWgg0QiwxZsWMVvgcc8wxnh7DJHKjTOSB+SXYTIjVhFXcGE7BXViw1Fh5TJs2btLksLNrWk7mkjBs5AR4wqRqb2P19TZ06FCfB8TwGuSFVVxoSyBA4KFJt9tuu62/ZyM5yKVWHZEHhosY5ptpppmceKHhASfVE2QI/2hbICTE25gRYWnP1vyKm3leGCZUN5zWzHArhB9Cw46+DURFw5hoWCaSFsUSdiAQCLQFgSAsbUEtR2EkaEoRFgkTsluHOt2FfkPmkf1oWBqueivU1liBr8Rxo61+5DCrG/aj1Q3/0ep+/KbhGv6D1Q3/yeqG/9zya1jif9gPVj/8W6sf+a3Vj/je6kdMiF9x4nfYcKsfPdoK48ZagY6/3uzXcTU2tq5+wvfqxLkKKWFhqAcBqq9tYcJXMEL2r3/9q5+uC2HRHBaGPng+8MADi8IaDYGE22OPPVYcTnr//fd9jgnaDIY95AcixCRctCwsh8ZoDgtEA4NAleYBwsLmbJASTFo/kBNt/oZ2hTkgWqKMP+aHkDZzYCAbEB0MRIVnhoRIC3PFFVf4sAxDM3vttZcPQ2EzNwU35sYwf4ehLgQ/OKD10CRYaSuwhfNf/vIXJx4aAkJjsuOOOxb3ZiHd4cOHe/qQC1Y04VdDQmjA0JqABeSFPLOHDoZ8QMggWpAnDBothvQgadpRlvIpP2CkpdIeoIl/qq/2EBbaFHgoroEDj7f//e/Jhg+AgtnQr4ba/fc9aKNGNQyL1fJ7Kq4O0sTbJjIZrwKBQKBZBIKwNAtRvj1IOJciLKmGBe3EBMWKL1FWqSAuPkTE8FHtOCvUjHXiUv/LSKsfM8oK436x4v2vv1ihDRfxoLkpjB1hhXGjrPArcU+IfyxxjrXC2F+tMBYtz3ifaNswXwUNUMHGoQnyb1jlukHY84SGhSEZSIuGhCRUIBoSjmgYmIuBoMMgBCEPCE60JwhSCeqrrrrK3RlSwTAEgTZGS4+FOenhzvCEyBJLqolTxAgBKyHL8lzeQTrQQsgwrEUcEAAENvNc8HfXXXe5l1RQ4od3mtQKUeGZoRKVm0Bp3Ssd3hMXlzQSDDGxOoo4zjrrrEnikHYFMgXxg7SIUGjoC/KjDeVIBy0Rq64giRhIGGEhlBA1hoTADK2P8MQfe8GgTdE8JNwgXmi1IGWaUAyWDNMxvMc7TXZW3XmimX/CJSUsGS8teiRtYXLYYYfbM08/71NUbrrhFuu7WT9bZKGl7Y3XtVcO8200XywIS4sADk+BQDMIBGFpBqC8v5bwbIqwSEg13206e5mw3pnJI2g5as3qSlz+jsm67bmIt2FZszE3gCXTEzT7DVNLG6Ys4lTLKzlO0E5QN2gF0BDwBS/SgDCWkGLYRXuVzDnnnMWzhBg+kaBmAin7tDCvhbkizJtgbgVzYTBoMyA7EA6GitDOIJAZ6kDQI4yZN4KGQUNCmpOR5oU5G9NNN52HYSkxQ1hslqZVMyI5bLePxgGtB8M2kDLmgrAFP/M2mPOh4Rwt+2WJNBoNCVTyDQkTWeJZJAWbNiGMmOOC8Cdu5vTcfvvtnh7DXAcccIDnhfxIi0QaIiyUH1wgJgwB4Y9LZAR3cNIcFrQkGhKiXDIM77CxHxoqaaDQUqnuIGTUNf5E6CAyav+Kp5Stch595NH2ykuvTDIPthTRaSD3EPyGP3YTathRaOKKryOPPMoef+xJj+v4AYPthIGn2kcf/GAsGnKtZWG8ja/9tWGyeDF0qdyFWyAQCLQUgSAsLUUqp/7UYZeHsDQUsnliIzDks6V2NpyeJ7UVG67cSzPEPQYBpHIjwNCu8NWORgUjIS0/EA7ICvMkIBwYBBUCk0mp++yzjxMS5nawARtDNxACvuol0Ji0y9APc0Dwg2BlDgvDFsTbv39/1w5oyEZLogmvOJiwitaACbesQkLYc6TA2muv7UubWaWDwR/7fECESAttBESH+5133tnJkYZ/mKQLGSCudGm3yAlY6N4jn1B27jXEgs28GjRJxEV6aEnQSrF0mHkyDJExJEVZsNksjnxDJJiLwqof8gAJRPujybmEQ8PCEBErf9DQsISbNKTtEqGAsKFpIl78YiBvDF9RfuoHUkU9HHbYYUU/ImAqX9ZW/A2E5dVJCEvWL88NbU6Epc63Aqjz5coN5y7h55hjjvUhITzff+/DdvKg8+zdt/+fveuA06K6vqv/xDRb7MaKQWyIooIldo2xRGOMmmhMLLFEREUURKpiARWkCiqogA0LFppBQaQISC8qIL0uZft+Zfr5/859c78dNiioYPZj38DstDdv3tw38+Z8t5xbDN/ls8USHkIYGoGMk0Eg5qHNXc3usxKwEthaCVjAsrWSqqHl9KO8NYClht7CFpslH5DYjKEff10SVPCjRvBB04R+vPS4Lmk6IMut+llwvx6jfwg1AeQiIaDRjy0bxo+dfvBZBz/ArIdEcJwIMgga1DRBTQiddfU6enN6LfVnoTmJpGr0w6BGIdluvZ463RKUsV00Han5hfUpMKOmhm3nPajphNfVOquva5u45P0l66JWibLktaglUj8aluHM8rwuASLzF3HivZLMjiYslZ3Wy/tl/1A7otofal+oWVInYdar90wtER2WNTqL1yLIoawod8qf7VPtEa+zpUnLtHygJWZMiwFLtZP0+pvuJmgxgMV4gJmElCxzxx3/xpgxYwXdjPloAk6sfw7ee3saOQ/huZS9MWJmXYIV3+pYNhWs3bIS+F4SsIDle4mt5py0NYCl5rT2h7VEP2xccvo27cE3Hed+yowfKM78iOrHivWxbi71g8vyPK7n6DbL6KTnq8ZCy3CZrD9ZPnkPus7jvK7Wp+W5TJbR/dyn+/kB5zqvp+ssl2y3nseltp9LXed+Xlvrqd4O3c8lAQs5YBSEbK5uXptlOXNKyjS5rtdM1qHrPFa9HXpMl5uTsR7jktfilNOwJA5q23Sph8y2QGV4gQvVsKisCOZWrVotxIsMvd+wxsPzvUfhncFTkUmZ+zV+WEw+QdBj9mn9dmklYCXw3SVgAct3l1mNOoMfBU7fpmGpUQ3+no2p/kFJVqMfNMpCP07Jj2Dy48jzqm8nyybr5Xryg1+9nF6X9ek6z6leLlmnfsSrA4VkGa5v7iOclIFej/Uk9yfrYZlkW5LrLLe5c7UurV/r0CWP03GWfijkkVF5a316f9XbofUm9/PczYE8ltXra/nq9VY/ruU2t9Q2tmjREtOnz9ykyObaVbXPABYTtmyArDkWIZvNiPwCjykngBHvT0Lzps/ijUGT4aQjhH4EYWr+L4PmJpe3G1YCVgLfQQIWsHwHYdXEohzIOe3ogKW67PWjVvVxqSrxbceqSm2qzaAc9SOoH2eWZV3Ja/ADqx9Aggr9xZ2sV+uhpoPryTp0O1mex5N1VS+T3E62U+vQ9rEtyQ+7Xl/Lccmyyfq4refwvnjsmyYe0/tlZBYdj3kup+R5yfboui5ZltfRejZ3Lda1ufq0rNZV/X71ePWl9lfLlg9i5syqjNPVy/33NvuemjT2ocrF7ON+uYcI+HLOUrwx6GMUrw0ROUBAYmOiGNqHIk9yYlWd/99XsXusBKwEtk4CFrBsnZxqbCn9YNQGwPJtHyh+4PRDllynfPQDqMd1yU7lseofT37gWEbr4fHqZbidLJN8QPQ87qsOAvSYtqt6Ga1T69Py3J/UurBe7Xsto+ckl/qxrn4uz6k+KcDhMb1fbT+vn2wbnYfpS6ITy/F4cqreLrZB25wsx/2cOSXP0TZrvdo+PVfvQY/r/upLlUHz+x/A51Oni3Fm05Zuegbr40wuFSWFo7MKZcJ9BDAjRw7H6lWrhIn5ln/ci112OgivvTQRfjqC59DMWArfK0YYVJqou2+74KaXt1tWAlYC3yABC1i+QTD5sls/ADs6YKn+UeJHSD+q2lfVP3Z6XPezDl3Xc5JLPa77ql9T6+NSj+lSz9Flsn1apvqSZfVDz2N6XPfrB1nr1GUS7GhbkudWr0vP02tp/XoOl3otlU9yn5bjebqudXFb9xFQqIwUbOg5Wr9uazndr3XwuN4T13mvyWtwX/UpeW71Y9xmWznd2+w+TJ4yVYw0yp68ORzB+kI/gJPOwE1niaJ44zJ7Hqn3Q3R4pD2mT58hIWyLF67HtMlLMX9eBT6fvBQLFyxCRcV6ICIJXhq+m9k0Jn9zjbT7rASsBLYoAQtYtiiiml0gCVgYusvQUuaK4ZT8+GxpUK/Zd2lbZyXw/SWg4GjIkHexfMVKASwONVSI4Aah+JvQ50Rza2VJYugDz3bphdmfTRfLjpwUQfJu+TTz0JWWwCYCnGwEWoweefhZXH11E3z44eeyTziGQseYhuiZax1vv38n2jOtBABYwJLnj8HWAJY8v0XbfCuBbSKBIM4D5Poe3NAX9mQnCOFm6W9ispb7wmbrwU256NftOcwZPw1hpYchA19Fx5YPYsHMWZLGwvEcif0hoaFL/sMQWLWmEqkMTUmGa1FAjlyFGh4LWLZJJ9pKarUELGDJ8+63gCXPO9A2/0eRgEcfGaIKakmoXWHST5qcaOkxfrWiYaGJKJ2mCQf4cMgIvNX/dXgbyjH6tTfR5/6W2DB1BiLXx6IF81FSWSpamvGTpuDlQYOxfGUxvAAgLuKlwiiEFzgSFs1s45szP/0oN28vYiWwg0jAApY870gLWPK8A23zt7sExBzKaKisk/MloZaFgIUaEiIJCUMOQkkS6gchvGyAiKYeksClfISVDoKSCgTF5YgcH83uborRn34MHyGGf/ghHu/0NFavKRETEbGR8T+O4PoOfDEg8dIWsmz3zrYX2KElYAFLnnevBSx53oG2+T+KBAS0MDAqxgyaDNQjASD3i0aE7rRGE0KtC8GKW86EoBEiL5TEnMwoTvVJ+3ZtMXX654ZULmD4MvDFvIV4952RuO+e1pgzY35crzLlWg3Lj9LR9iI7tAQsYMnz7lXAwlwwTNC3OafbPL9F23wrgR8sAXG8NYE+EnlEwBKQ7yWh9dB91LDI7thU5JSnMOXj0Rjetx+mvP0eIidE+xYPYcrESRJBFJKLPwKGvj8Sz/Z6EWXFnrisRD61OqTmp4uuBSw/uBNtBbVeAhaw5PkjYAFLnnegbf6PJgEqV+hUS2DC9WxM7McGUAPDd0mj6RgxFNAhJYjgl1WgxwMP4dGL/4w+194Cb0Uxejz4CGZ8MkmiiSpLyrF44RI4mVC2mQCRCc7J2SI+LAJYcsqdH+1+7YWsBHY0CVjAkuc9agFLnnegbf52lwBBCDUsRtNBXQetOoY4TwEKG0EaAOWFIagR7QsJCV0PYXkK/ppSeMuKEJR46H5/e8wdP1UASv++L+CmG27CpPFTcuYl14ng+fRh8eHw+lXWqO1+v/YCVgI7qgQsYMnznlXAQuI45WHp0aOH3JXlYcnzzrXN3yYSICiRRIQSiBwgDA1zMc0+nAleqHkhmYocI8CIIjgeGWupZfEQplMIyysRFJUhTAd49P6HMGXseEMqF/hi+gkd8reE+GzsFDz1eE+sW5s2PC2hDWreJh1pK6n1ErCAJc8fAQtY8rwDbfN/FAkQeDD/j8kNZIAKwQqJ33gspONs6CIKmPWapHCh8Tvh0nMQpipR9uV8FM2YK4Dl5a49MOdzalTMOW62Em6mDG6qAvfecS8u+/1fsHZlSkhy3divN/b3/VHu117ESmBHlIAFLHneqxaw5HkH2ub/KBIQLQtBi9DsE6QYPxZfwIoLJ12G8WOGY9iQV7F25VLQkVbKBiHSZWVYPG0mHr7uVrS+9G9IT/kSQVEKUTaDyE8jCMm1kqVXDAhcAvqyxAS3oU8rEc1QDKK2kOVH6Wx7kR1WAhaw5HnXWsCS5x1om/+jSEAAC6N/6ETrMiu1odWndsVNl6NizTLcfc0l+EP9Olg5bTIi1xXfFTrdOpUpBKWVKJwwC8VjZ8JfU4mgNCtmos8/G4f27dqg6T13Yf6CuULDT1p/Oq14TgTmSgyZtRkmaeKPcrP2IlYCO6gELGDJ8461gCXPO9A2/0eRgDjXUsEhc+zTouaeilK837MLHr3kbLQ/vSEqRo1CWJ4W3hU5j8kuPR9hKhCafhLJrZk1G0FZCZyKMqxevhqrlq9BppLJDukLQ7cX+sMwKonmJWYtshqWH6Wj7UV2aAlYwJLn3bs5wNKzZ0+5K+t0m+eda5u/zSSQAyzUrNAMFPnwAxeR7yAo3ohhnR9F77Mao1uDo5D6YDiCogpEGUd8WeiMG/k+yKtCx1uClw73N8fU8WNN/HJMMhcxDDoK4GTTEtIsiRE9V0KbbZzQNutKW1EtloAFLHne+Raw5HkH2uZvdwkQrEi4MrlVfANU/DAGEr6L0sWLMahpU/RrWB8fXXguUiNGSTRQlHVAHxeqTCrKyjBz2jR89uk4LP7qK6RKioDAQeBkhBHXmIEIWDx4fgaRZBlitJGhjLO0cdu9m+0FaoEELGDJ807eGsCS57dom28l8IMl4Ps+Qpp2mPQw9OD6WTheBpGXxdyPP8YTF12E5+segpL77oU7fyGCsnLxYyHccJwsSkqKMXDgQHTu3BkTxo9DOkXzT4gZ0+agT4/X0fmxF7Fo4YbYr5Y5iRwBOsqma91tf3AX2gqsBGABS54/BJsDLJaHJc871TZ/m0pANSwSrhzQ4ZagxRfgEmVSmD18KLpdchFeOuI3KH38UXgrVyJM0/TjxuHN9EMhvT6Jbw30KCsrR0WlgwEvj8DvTr8Xhx58A0YOWwey3Bo/GU+0OXTyFcZci1i2aZ/aymqnBCxgyfN+t4AlzzvQNn+7S8AAFiYhDOD7JIMzjLau6yAsL8WIXt3wzPlnY9IFZyI1cjiCjesQZSoR+XSWhYAbL/AErGSyJm9QywdaYebML0C+uaINITauC+GkIvhUrJAojlmaNTTakOrmaP+3+w3bC1gJ7KASsIAlzzvWApY870Db/O0uAXWyZaQOI3ZIb0utRzaVRvGSxXjqn//AA0fWwYy/XIbMpHEISjci8jKG+VaSFhK2RHA9H+sLNyLKRmjzQBtMnTwdngdkPSCdNSHMomFh5ufAFbOQ46VjHpbtfpv2AlYCO7wELGDJ8y62gCXPO9A2f7tLgKYgP3AQgloSD1FARAG45ZVY8MlYdPvLVeh0wjHY2PZ+OF/MRFhZYhhsowBeQNORL7Bl6rTpuPfu+zB8yDDcf1dzzPh8JoqK0vhw1Bx8Pm0dsmkCIaNhiUJfrsdreoEr1HHb/UbtBawEdnAJWMCS5x1sAUued6Bt/naXAAELw5hpEhIti+cjcgNkNmzEkE6d8fhJDTHwd42RGjEEfuFShOly4VMRzQzjfcQcFGDthvWoSKXFR6X5Pfdj3pz5GDRwJA4++E+4+65XUbLRZGt2MpGw5IYgaOFsEi5u9xu1F7AS2MElYAFLnnewBSx53oG2+dtdAgQskkeI0IGaDwEsPsKKFAY1b47+pzXCoJPqIz12BILiVYicSlBDEtBBV/5R0+LBQwjH9wWwtHqgFaZPnY3K8ghzZ/lYvTyAUxHBy0QIqWVhYkUBKzzLApbt3sn2ArVCAhaw5Hk3W8CS5x1om7/dJSCkcTTqCHAJEfoBIsdFUFqG1+5rhpdOPA6vnHAU0mM/RFi2HpGbFruOMSXR74VmIZp1QlSQzTYEWrdohfFjJ4oJiGYgoeF3xJJkyG4ZRh258ANyspDLxU5WAlYCP1QCFrD8UAn+j8+3gOV/3AH28nkhAYIWcqLIkqy1mSyC0hKMaNsWrzY8DkNOqY/MuI8RVpQgyqZy2hWGM9Pvhb4oi5YswKMdO6BLp8647qq/YeqkWcikIqxdE6K0xPivCIGcxD/zj4eQWRAlINo47orqZZPt6uJLlqt+zG5bCdRuCVjAkuf9bwFLnnegbf52l4CCFXKoEEa4TGxIFtt16/DWvffg9YbH4rUGdZH+dAzCynJEngPHyzKmKDbnBMJeG4RZlJZswPrVa5AuyWLerOU469hKt60AACAASURBVPQbsddeV6NFixEoKYkTKjJtEFl1AwIWT7QzHp1+45xCJJUjE67L0GeaqJh0SGAN+V6Mr00VyOERBTHbXVT2AlYCNVoCFrDU6O7ZcuMsYNmyjGwJKwF+8gkL0tksyHob+QGWTpqMXtdcjZePORzrmt4Od+EChKkUIpc5hALoPzrOEmB4fgoBaff9AEEmQvF6D++9Mwe9en6BMaM9CW12PJNeiIRxDJ/2fUYmGRCSyVYiFAcX8rtwNqy79Kth60jfbyAVW8qZreZkAUssCLuo5RKwgCXPHwALWPK8A23zt7sEqGERsrj4++9Rw+K4GP3yQDxy9tl4se4hKOveFX7hWoSVlYhccrXE7rZq44l84VUJ/KxoTzYWFsMj94oLOE6ErBvBDciEK4cRBiEEtABwXFc0KXTiZWoAsE4BMQa40HQEgqIoED+bJEBh2/XfdheUvYCVQA2XgAUsNbyDttQ8C1i2JCF7vLZLgGAlICUtvUocD04mi7CsHONfHohOZ5+ND09vhIpBgxBsWI8ow2SGnqAOCYcWh9kQkWhGfIwfNwZvvv4arrj0ckyeOFUUIQJYPMCPzMwszRHNPPzP7NBiijJOvwaMUHsSgOAnlJxDCliMj01OsRJrVixgqe1PsL1/lYAFLCqJPF1awJKnHWeb/aNJQDUsBBGMEPKyWaxfuADPN70bbevXx9J/3YLs59PECZf+K5HrGjWJ6Dbox0LTjSt+LIWFKzFz2mTMmjodC79Yin9cfzcGDRyLoqJQtCx+KJYg+SOgBcCawrVYvHQxXC8rQIXZnMPAkdBpMQUJGCJYiQGLQTyicZHj0o4fTVz2QlYCNVYCFrDU2K7ZuoZtDrD07NlTTuYvS1EpU60cJ23bulptKSuBHUcC+g64joPQ8+BUVmLl1Kl44tJL8PixR+PLm25CdvoMcbiVOOUYOAiAEK8SmofiXEReBoGbRuT7WLW0EB3adMXfr2+BgQNGIU0OFhp36OPi0S8FmDp1Ds4+58/Y/8AGmDRpPt1ajMYlYnJETzJI0/yUMwNxPQdYWAevy392shKwErCAJc+fAQtY8rwDbfO3uwRUwxIGPrxMGl55Kd7r8hS6nnEaBp91BipeeQXe0mUIK8olnJnRRJzV1dUs6aeShetmQVATeR4iqlP4n74rgawiCA3LratJElt2wX4HXIlf7PYnDBu6Hj45W8TXhf4qsWMu6xLfFvq3cNYr04zF2cKV7f6Q2AvkhQQsYMmLbvrmRm4NYPnms+0RK4EdXwIKWKjRiDxXMjR3v+VG9Gl4PIafcwbSYz6Gv34dwnQKfkjeFdLx0xRkuFsoIWorGV1EkxKCEA8/1BpfzpphwEVkAAtTFDG6iFE/LJtKuyguCnHuuY/jp7v9C5f9cSBWrgxBnMMcRQJYpHJxejGOuDQPEbQISKHmRbUvO34/2Tu0EtiSBCxg2ZKEvuNxDkK5gYjDTmJbTTS6ZNVaVgbDhAknedlkHcn9XN8SYGGZ5PWqn2+3rQRqgwT4DtHxNvI9pFevxEv/vhX96tfFqjtvgTt/LsKyIkRuVt5HEx/Ev7H5hpwqVItEEN+Vjq3a4NTj6mP2pIkAQ5KJVARaEIy4wnDLsOWs4yOTifDHyztj932b4Ihjn8VX80nzD2Rd+rCEkiaA9Zp3lCYgAhZGERnQIo6/sbanNvSTvUcrgW+TgAUs3yad73CMgyEHHZ10fc2aNfjXv/6Fo446Cueccw4aNmyIV199VYopWEmek6xn7dq1aNKkCY4//nicdNJJcv65556Lo48+Gpdffjlmzpypp6Jv377YY489UFBQgF69euXqZzvMYGjVyjlh2ZVaJwG+a8K/4jlIr1iKV+64Bf3qHYLyZ5+BX7gMYbpUwIwAG2pJYso4fWsUsBSuXIXCxUtx3223Y8wH7+PeO27H9X/9K9atWyeeJuRsCcKMMNz6MiYAr73+BQ797QPYae8n0KpdITYUGzAkTrlRaHxZQpOYkUDHcPsrYKFfjOFoqXWdZm/YSqCaBCxgqSaQ77uZBBoZhkZGETZs2CDAYs8998Q///lPtGrVCo0aNcLuu++OF154IXcpAgpqSlgHJwU7hYWFOPXUU3HMMcegRYsWAl7uuOMO3HTTTWjevDm+/vrrXB39+vXDXnvtJYClS5cuuf1cYVs428lKoDZLQHhQ3AyC4kK80eRWPF/3IJT37YmgaDUip0IY36oAi4IWZnquMg25mYxoVDq0aIkvp0/Hf94fig7tHsb69UVixDEkcdSyOMLbQgvSmrUh/nLtiyjY50n8/ZYvsX4j6yR/SxZRzHrLRIkkkhOSOvFjMYDFZIwmmLGmodr87Np7NxKwgGUbPwkc8NRMM2TIEPz6179Gt27dcleprKzEmWeeiQsvvFAADQ8oQNFCqVRKVqmdOeGEE9C6dWvZrl6OO0tKSuTYgAEDsM8++whg0euxvAUqIh77pxZLQEAItR30G/GymDnyffS+9kq8Uv9IVAwagKBknWRopvcsyxrtCv8SQChwiUCNSSAhzwE6tW+H6RMnGHOQ8Z0VEGK0ISSEM6Yh14uQcSI8/cw07HJAF9zy76VYtToUK5J5nw1NvwEs1KSY8OZk1JBh2rWApRY/wvbWYwlYwLINHwUOQDqz2ocffhiXXHIJ5syZI1fJZsnDADz99NM47bTTciYdBTg8RrU1c51wWrlypZiS2rdvL9usm1oYBSHc1rIvvvgi9t13XwEs3bt3l/KO40h9smH/WAnUYgnQ/ELtSJRNY/DTndDud6fixaOOQPmLLyEoKULkkXLfhCJTF2lCiQkSTDizaDr8AMu+/horv16AG6+5ClPGjgZCT0KlSRDH8+h0S01JEPuyELCQ/bbz0+Pw030fxi13zBfOFipTGcFMqv8gcA0HixqieEBmFqLmxQAZA2JqcSfaW6/1ErCAZRs9AkkQwSqXL1+OevXq4amnnpIrqFMtN4qKinDKKacIoOE2QUjSpCS29igCNSz0eaH5Z+jQobj11lvRuXNn2c/zCFgU7PTv31+0OfRheeaZZ+SaWobl7GQlUFslwHeTYcOZinIsmzkDPZrcgY6nNcb4yy5DesynCEpLJeGhqEj4XuW0LAHCiMkJfbhOViKC+vTojkvPOxuN6x+DmZ9NMI665F0xEc7G24S0/qEvyQ9dL4TjA089Mwb71+mEuvVfwMSJntC9SAohanBEs2P8VAQoKVghWMoBFmvSra3Pr73vKglYwFIlix+8RmBAsMFp2bJlAjY6dOgg2/RrUW1IcXGx+Ka0adNGjinYkYE1jmbgAZ77k5/8RHxTjjvuOJx88sk4/fTTwfWLLroI06dPl/P556WXXsoBljp16gggoqPvX//6VyxYsEDKWeCSE5ddqUUSkOc+DOGUlWLuhx+i7Xnnof3RR2FRkybIzpqLsLxCHG5pEiJ4CCJG+xhTkMmmHBieFAQoL16PwmWLsXbJIjzRrgPuuaMpHm7/GNZvKDVRRfwBIppWgo0Qnh8JYOk34HMcfuyT2Hmfh9HxkUWoYGZnSVnEMcMzoCUmqWNOIcO/oo64RntTi7rM3qqVwGYlYAHLZsXy/XZSS6KghCDhyCOPRKdOnaQy1aJwY9WqVTjxxBORBCw8rsBF62jWrJmYeC699FIsXrxY6qEPzHXXXYf99tsPEyZMyDWUGpZdd91VyhPk7LTTTrJ+7LHHYurUqbk25E6wK1YCtUQC8m75PvySYnzUpxe6nXMWXmh0EioGDDCEcZUp43BL/pTQgxd4cGnqERMP8wjRdkMfGFL2u4j8rNGsZDx4lS4yKQ+uT24V4xpLplvVqNK5NpUNJTHin//2FnbZtx0Oq9sVi+YHEhHt+8YhXkxOsWaHJiXj00JzEGcLWGrJo2pvcwsSsIBlCwL6LocJOFTDQoBRt25dMeGwDu7XY6tXr5ZQ5Xbt2kn1ucEt9oHRay5atAijRo2SkEnuS6fTUgfNQNdee62ES9O8xIlRR3TwpUmIJiSClJEjR4oWhtodTgqIZMP+sRKoJRIIhX/FR+XK5eh+4w3oWb8uRpx/OjKTP0OwcSOiLKN1+IPB5AwK4NELRfxRqC2RrMu0+UQhUuWlKFu3BmWFa+S82NNWFyaWh9YbySlE59oQrh+IluXu+4Zg9wNbYN/DX8DkST6cmPVWLbZGw0qYRMdbBSvJLM6mw6gxIgjjpCZhjiHmfGs6qiWPda28TQtYtlG3KxhQUMKQY2o3NMSYYENNMgQZjP554IEH5Op6rjYlqY3RfbpU7cvtt9+Os88+GwsXLpRD1LBolNBzzz0n+1gvr1m9fq3LLq0EaoMEoiAUh9r08mXo/ter8MKxh6Gk1d1wF34prLdMdmj8SOiz4sGPXPighsW4u9KbNmJ8MiL0e64Prr3iCpx50sn4YvoMREzRTM0Kyd8MTsmJ1JC+GfMS/VimznBwXMPHULDb4/jzX+dh7XrG/xB0iONMnPyQtVDrYgBUVa0GiNBxX8cRjgV8t5Pvt77zbISWTR7PNc6uWAnkoQQsYNmGnUawwll//Tz44IOgOYeaEk6M2uFEcMGw5okTJ8o2fyVV/4XEQYmaEf0FpQOT1n3jjTfiiiuuEPMSK3n++edzPCzqdMs6LGAREds/tVgCAlgcB96qFej9t6vQ/+iDUflGfwQbVyHKViLKMlLHl+zJYWgAixs6cOlwK/AB8A2qwIIvv8AnI/+Dtwe+jmee6IIOrTqg61PdUFJaIWXp/yImnRxTLTlcSPUPLFoW4Ozzu6Jg7974/eVzsWxlCI80/TnAQlBknG9DjRSS2CNGAzqbABOOCwpcvvjiC+F4mjt3bq6XedwClZw47MoOIgELWLZxR3Kg0PDl119/XXxNevfuLVfhAEJgQh6W3//+96DzLScdWPQ4902ZMkXYbamFUZOOaleGDx8ux9555x05n38Y1nzAAQeISUiZbgluFLTkCtoVK4FaJgEBLK6D8q+/wks3XYdX69dB5RsvIShei8hNi/+KEQl9RWgK8uBR0xLnaKZuQzI3E4QQ2DjkcwE2rtyAL2Z8icULl4HRQLExZ7OAxfUgOYQ6d5mOPQ/rh4I9uuD5lyqQylILKhcQrQqdbYUHpspOJNc2WhejMeU7rVpYUic8/vjjIFgh/9Ls2bNzQIb3xB9JOr7Usm63t7sDSsAClm3YqTowEJRwIrCgI+zFF18snCrcN2jQIAEVV155ZY44jvupbaFGRrUu3HfzzTcLt0rHjh1Bmn5OHKgY3rz//vtv4nSbjBJSwML2sHzy15hUYv9YCdQiCZBfJfJdTPvgbTz5h3PxXqP6SL33NoLiDYgyKTEXMamhRPckaOOEOo40/WJ2IUhgVmWClQCREyBIOZL2h0iFRNJqQiK4ER4VMe1QyxmAFiXOA19diDrH9kXBru3RqUsRNhazXgVEHDdMdJFoTxK+MEm3W5qXOY0YMUKiA0tLS2WbP2x69OiBefPmyTbffR2LZIf9YyWQ5xKwgGUbdaD+4mF1XCdYIFDgL6BDDz0UjRs3Fs0KQ5Lp18LcIzyuAwodZekwS/p+BT7MFcScQaTyb9CgAS644AIcccQRQs1Pp1oOUHo+AYv6sKhJiPVoXdvoNm01VgJ5IwHz7EfwafIpKcKANi3w4PH1MPJ3pyA17AMEpcWIaDphFmZqI6kbIYeK/KOmxZeZ9Rithi95fx5p3x43XX8D1i5bKS4mBDuiyeT59BmjdoREcjEfC7lcHNdwtbw++EvsX6cjCn7VGs8+76C8ggy61J8oWDGAxeQZUiBkzETqk8IOoLaVEYOqdVVz87Bhw0DiyIqKilw/cTyyk5XAjiABC1i2YS8mQQurVbBAGzMjghiOTA0LBxpOHGx0wCEx3N///neMHj1ajiW1IjT93HbbbaJZeeihh7BkyRIpw0GS5TglNSw9e/aUfWwPj2s7ZKf9YyVQSyQgWgoCiEwGMz54H49ffCG6nXI8SlreC2f2DIRlZRLpE7iOaEEUsPB9ES0JIYz4ogBO1hFq/lSqEiOHDcNF556H1g+0wHO9emPVipUiUdGw8NwgnuN6SO/vBwQzwMBXpuPwox9HwS9b4tHOWWwsolMucQ/920xEEDM1M2pJnH2puWE9m+kzA6IMGNF3nPxPXbt2zZFLbuY0u8tKIG8lYAHLNuw6AgQOIhw8ZLCMQYsOJrqPS13Xy3Nbz0su9bjWwW2u67b+skrmElJq/s3Vo/XZpZXAjicB8TbhGyIzHWmFDK6iDBP6P4/nLzwP3Y48DKWPPQJ34UIhjAuyDggQqFWRXEF8N3PRdQQNYq9BFFITEqfCiCK0bdkSz3R6Au+/9SY2ri+U64lmxtiGTCi05BhipBG1NREy2QiF60L86epXsMt+HXDMyW9j2gxfHG8JWEziQ2NOEg0LtbUhI5A2BSz67vOH0KRJk4TugH1JDQyztitR5I7Xv/aOarsELGDJ8ycgqWHZe++9xaxEOzYnBUFJgJPnt2ubXwslUAW86e/hCx5h7h6GEvODzomJDWnC8QJHnGYJE1w3K8kOixd9hd7/vA59jquHBdf/DelPJsBfW4Sw0uQPEtMNIUsEePRloa5Df3TQH0V8UfgjJIKTccQM9GCzZvhq1nQgchEFWURgwkPWEfO2xOFF0nZCkTBA1jXmn7vuGYx9DnkIBfv2wLiJJKmjbsU1vC8xx7/n8V4IdAiDNtWvJH/wkH9p4MCBGDx4MN57770ceElqVhXg1MJHx97yDiYBC1jyvEMtYMnzDrTN36IEFHATWEj4MU0uce4eai440YRCDhUvyCKI+PFn2C+dbR0smzIOPa76I16qdziKb78D2VnzERSlEGVccRKh2UdgQUTHWONNIvyyrJsAJKJplYlEPfFN+WTUaFx2wUV4rnt3BOnKWAvDM0THoo4nsaLH7PUCX2j66d4y6qOVqFPvQRTs2wfNW2dQVMbYJNK5GAddIidhy2WKAGpnYu0r71OBCGWivikELHTMf/nll1FeXv5f8qyuzf2vAnaHlUCeSMACljzpqG9qpgUs3yQZu39HkUAVYIlNrSZ+WPQO/JjLCj/qouWgpsMzBHCegyibwtDeXfHY2afh3QZHo+zJLvCWFyKscBC5sYNrjqRN8Egcnqx4g1oTDz6BUOggk65Al05PoUG9+rjm8qsxaexk+FkCm7gZGiEk7YoBT0ytL2DIBzZuDPG3v7+Cgn2fxdGnjMK0mb4w4RJ8hcgIAKIzvf4TYCKRSAacqaN9koySfa37ueQ5VrOyo7wB9j5UAhawqCTydGkBS552nG32Vkvg2wAL/TsMcgngZCsFVBCwMDzYc9II0xV49v6m6HDy8Rh7RiNUvjcM/rpihGmH9iTR2JAszjDLKmMtgYOZ6T1iAJALP8jAyabEJNT2gbY4bL8jcNDeh2P8mCmyj3BC/E0EtFBnYgCL+qCImccjN0qEYSNKcfgxL6Jg98fQuv1cFDEZomhZUtJ2apKYIoD+L6IhSViFuJ0EJKp1qS5QBSxWw1JdMnY7XyVgAUu+9lzcbgtY8rwDbfO3WgL8AMvHN6dhMXBCKhBfEyYNZApkzj6cVAWCog3o0eQ2PNroBIw69SSkP/oEQXEpIseYg3xhuDUAx4QhG48R9R3hljHY0KSTlbDm0A2x4uuVmD5xFsaMGIfyonSVhkX8XWIeFgEuxmmW9XFiUF86HaG8PMLNtw7FTrs3RdP7ZqO4xEQRUYsj9i7RttBUZYCPghIFIaxLowwpk82BEh5PlpcG2D9WAnksAQtY8rjz2PTNARYNa+YgxgFL5zy/Vdt8KwHzATbffoES/KALpAh88VkJmFE5omNuALeiDKUL52PgvU3wdOMTMazRiUiPHSvhzGSsFS2GhA8rB0rV+2JI5IxfidG1mPolkSLxEC9DbMEEzibQSJx2jS+MRhfFkX+5KB/6nUSorPSELO7Jpz/BXgfcjjYPr8N65hUK6CjPP7FyRlhvDXFd8l3nO785gMIyag6yj4qVwI4oAQtY8rxXLWDJ8w60zd9qCdAqIrOCcP2gx3E0RkNCsECP3ABhZTlmD30fPa64DE8ddyTm33Q9stOnIqwoN8cF5NDXwwAWRQoE+ApY/JhIjhFHfshywKrla/H6gDcx8t2PUbmRpiVJAfStgEXccZmBOQqRSRNwAI8/8Rb23P9vaHz2W/h8GvOQmabnnGhiExOjlxIWoZy8VHvyTeCFBbVM7iS7YiWQxxKwgCWPO49N3xrAkue3aJtvJWC0hJsAFmovGJljQAA/6Pxwq28HGWwJWMb07Y3uZ52GbkcdjrKeXeEtWYQwVSGAhR9znsNoIgNWWGeIIDThxMQhEt7M6J8wgOM5yNKUFAI3/PVmHLzvkbjk/L9gxuQvzekCMOJ2xeBE/VdE88LsRKEH1/WIp/BEp1dwcJ2bUbBrW7z5ris8LXTJYeR2wPDmHGAxZqXkY6AghRoVBSW6T84jIrKTlcAOJgELWPK8QzcHWCwPS553qm3+JhLgB5mkbvwE0xdEPuaidmCGZeb3MR9nj5E1QQBX6PZdpNauwpsPtcCzDY/D+787GZVvvwl/zRpxxI0CV7Qorucj8AIErgcmSaSZyAuY+JB8LLHzrVzfFw0L+VSo7vhgyCi0eeApNL/rMSxfVCZaFlHsULNDEBWbqoxWKBL/l5CcLfDED4Y38/6701G/QQsU7NMTTVukxPE2EGZb+gOH5l4jkyJAtT+bCMZuWAnUMglYwJLnHW4BS553oG3+VkmgCrDQJ0tUD+KrIoCF2ojYZqJROpHnYM6Yj/DopReh99GHoei+JnBmz0JQvFFCncOAzLLMHQQEXkgkJDHNdMI1/wg8IpA/RTUxgfC1GA4YLxMhysZz7DbDNoiGJvIMD4yCFnG4pY9KTDBHUOMDFWUR/n5DfxTs3x11TnwXn08n4DJJEnltwjDVzBi7U3yTWyUxW8hKYMeTgAUsed6nFrDkeQfa5m9RAgIYJGqGuMIABnEYISCghiUw7LKe4wqBXDZTiShTiRcfeRjNTz4Rb5/aEJVvDIJfuBpheQkiL23I5WLAImCHbi/Mqhx6cIKsgBbxO6HJyKeZh+DB+LYQSZQXVeKzsVNRvj6jQUkCmqoAi4swDq/mPp2zTMQYhCAHHeePRq/DQUd3QcEvH0SLVjNRVmqihajJ4fU90QS5EuqcQ2VblJgtYCWwY0rAApY871cLWPK8A23zt0oColSJFStyglGzmOSEBk2IhiTyPWQqS5EuXIXud9+FVic3xMpmTZCdOglB8XqE6XIJexZ+E9FgGGJa5goyvis0BvkCFrJ0tKUnLBU4gfF3kWSlEfDKi6/imDrH4PILr8DyBStyjrcCrsQZmHWYcGkCDfrWqI8Jm8vZdYGNxSHuaj4GvzjgIVxz/cdYs8ZECxnAQi0LmW4TKpytkpYtZCWwY0rAApY871cLWPK8A23ztyiBnEkmjM1BEv1ijCbiZSLghY6qgXisZitKwPxBPf99G1qfciIqBw+Ct3whwrKNiPwsEDJKhwBCzUtSIegDY8w+oluJSdsYZmxMMdSSKGBp92B7/OHsy3DJ2Vdg7pT5EkktwCbOrmxMOVWGHYIWAhZzLwa8+H6IylSEt95biQOOaIZ/3DIVa9eGEi3k+qzBaHVi4v7Y5XiL4rIFrAR2WAlYwJLnXbs5wGJ5WPK8U23zN5GAApYYl4h5RflXyMHCiWDFI1Ga78KvLMHM4e+iy1VXoMVRR6Dy3dfhFy5DlCmPnXRpSoqTEYnqhmYm47jLTTrdst5xE8ahrKzUtIWJET0PTpaAB2jbsj2mjJ2KMB0ZPpY40IhtpB+NgTzGbVdOEEI5ghaGUZuUAOl0RsKb+77wCfY9+CbUO7E/ZswiQR3bYM5iAkSW1zo2EYzdsBKoZRKwgCXPO9wCljzvQNv8LUqAgIUzJy5VC0JQIeCAmgv6sfgBIjcLr7gQfZs1QbffNcaTx/wWla/3R1C0CpGbNhE6khHZ2GW0btF+0PGWDLIMiQbQ7P7mmDRlsuwr2lCMeXO/RHkpQ6KB1i0ewpBXByOoyCByGIdsnHZZXxKw0FZkAEeETIb+K3TiDRAEnmR+pj/ua69PQMPGLVGwayu06rABFZWsw0AUzUZt/VekG+yfWi4BC1jy/AHYGsCS57dom28lIBIgqBB2WmZijv1MhEI/MGHJIVUTgYdZY0ag89V/xHMnHofRf/wDstMmIKzYgMjNiCaFwCb0AzHvKI+J1B0ztzEzM3Ukg157FUuWLZNr93u+P26/7U7MmTVPsEOrB1rh7MZn4KKzzseC2V/kFCACWGL9SpUppwq0kICO9PucfdeDmyWQiXDVNd2wx6FPYp8jumDWbLLwmmgh1idTvDAb9q+VQO2UgAUsed7vmwMsloclzzvVNn8TCQgIiP0/GMXjhVl4kSOureLnEUYIvQBuKi3RQWNeeQGPXXgG+tU7BKWPtIe3chGiTJmYixQAcKn/eDGj+fAhXCkRAYsxC8XuK9IeYgfPNSHULZq3xhGHHIuD9qmLiWOm53xYfJ/tc+FFLvwYWEl+INYXBXFocxZhlJWIJoY3kyjuvQ9WoF7Drij49f249/6PUcJkiNSyxLwvGra9iWDshpVALZOABSx53uEWsOR5B9rmb1EC1QELo28MYIngE6zELh5eKo2y5UvxTNN/ocPpDTDm/NORHjUCQfFaRA5NOcbZlioSOtDmCN7Ep4T+JnREYWQPw4g5G+ZcghB10k2nmDgIuPOO+zD41WFYuaQEfioSwOJmfHieKyHRbkTyOZLNkdXWARjpI7wsrN8RwMIUAjQJZTMRlq8MccKpj6Fgt9txQqMnsXwFHXMJpFje+ttu8SGxBWqFBCxgyfNutoAlzzvQNn+LElDAQt8Q5vORYF/6gZA6X509QsCrqETx1wvQ9ZYb0LL+b1HWqS3c+bMQlm9A5KdiEGJ8SMKIGhQyoQKh6AAAIABJREFUzxr2Wd93haLf0PT7CHyajxhObLI/h5JUEZg4fhKymQCffjIZJczSTBUPHWSpeaHyhW3MBUabqCKaoCSOmQBF9EK8NhMHRczRiGw2QlFxiDYd/oOf730zLrj4daxeRbDEZIYefC/OrmjVLFt8VmyBHVsCFrDkef9awJLnHWibv0UJKGChG4f4rMTJAAUrKGAJQlRu3Ih1s2agy9VX4qkzTkLqw3fgr1qIMFVsUiqL9sRkcjbaDmo9qMGgZsX4mQhgYR6gkCR0Lnwvg8DPYvWqlbjh7zdit133xhNPPINMOkBZSQptH2qHm66/AUPeGAw3lRHtSzqbgcts0EIYRypdUZVIBmkDWAwpnAExBCWmyMdjC1Gv/n0o+Pmd6PtCGmmy6VLPQy0LgZMFLFt8VmyBHVsCFrDkef9awJLnHWibv0UJGGdb6lOoYWFuHaPYEMAShfB8T/xTgsoyjB/4Mp4463foc0YjpEcPhb8+Dmf2XeMsIuHMNMVQ60HwQoI3ggvP+K9sAmCYrJAamRAbNhSj1UMdcU+ztlhbWI55877GEx0747QTG+G26/6Bif8ZjbCyKnMzGXlNWw0br6hh4mSNsi6qGaN48ekEHAGvvjERR9S7HTvt2RoX/XE4Vqxm8DZBGv8SsPCO7WQlUHslYAFLnve9BSx53oG2+VuUgGpYCFiotRC/lfjzzY95ltE/XgaVa5bjhbuboFP94/D2BechM24UgpI1kjtIHF0IUgSoUG9BNQ39RJj3h4DFzIZCn5wr5ENh7h9qX5Qu3/CjEDBNnz4X7wx+F8Pefh9OUQUiJnFOu4iyRl3i+QRWcQh24ILJFgmONMO00ehUEcl5HsQsdOXVz+DnBzyGgj3b45U3i5ENAFeaYAHLFh8UW2CHl4AFLHnexRaw5HkH2uZvUQIKWMRNlhoWuouIpcUQtIn/SboC7/XtjocvOhfd6x6B0kcfhbdyiZiDCGaYc0j9UbhOHxYJLWZ4MSN6Qh/TZ8zCJ59MRIo8KCHDiglYsqLdIJBxXIIlAyBeenEQ1q8tNooTJ0Lk0fE2QBSHRpu8Q5EAHxNuLcmKBGYpaBHHX0Y/hSa3kOcCfZ+fjQOP7I6f/KYHTj57ABYvN/crzi7WJLTFZ8UW2LElYAFLnvevBSx53oG2+VstAcMeG/t1RAQUJqlgprIcGxZ9hVZ/vgTtTq6P/5x7DlIjP0ZQtAFhugyghoPmHwktZoQOExOaXD9enLV56IhPcMzxf8AeezXCf0Z9bSKPhESuAn6QEaAxbdoMdOvWGxdddDn6939VOFRWLl6Fgc8PQLcnnsKqxYskEinwHWOmMkqc2BpkiOWorfkvwCLJGyH1uR7Q+pHF2POIPtjpgG7o3c9BJhs77YikkoQssaZoixLc2nJbrMgWsBL4n0og7wALKbj5i0t/dan0ksnFaPPmzEnL6lLL6/lc5vNkAUs+955t+3eRQC57EPlQfGYyNiaVdGkJ5n30IR679Hw8flxdLL3lVmQ/n4OguESYb0PPQUDQAqNVoWcI6fdpTspkCV6Alg/1xb51bsMu+9yK4R96oMsLQ45dLw1XTEMRhn4wAo1POQvXX98E69cxVBnw0wG6PtYF11x6BWZPnggwhJl+McxVFGMUuqAweaKMQcLOazQ8bIdQ9QcRfDci5x1SqQiTZ/qoc0JPFOzxDG64bSXWbQyVSFdMVNTMGAI9kxGa2iHKhiMZI6k2Get4E3KHXP7wsY7jjY6ZXE+Os+zL5Nj7XfrWlrUS2BoJ5A1g4cshmVPju+K2JDvjryDXza0nb5rlkwCHx/hC6QutLx7LaF3J8/NhnXLg9NJLL2HvvfdGQUEBLHFcPvScbeN3kQDfT/kYx59dfnp9mlIcB1Emhd7NmqLTaSfitTMboaxbT7hfr0BYkRJnXNFqxBwoSgiXyTITM3/8AMuWleKvf38K/7d/axx3+puYPtOH50QgqRvDiunf4gUuHMdBOuWBr9zcuavRu9cgvPj8a1i9eC3CSlfAkQAWOuoyZxDbKKAqjmqWtgusiMObWcYADGKKbNqVPEJjJhbjsOM6YKdDBuPGOyuxdr0xRdEkxfYrAElnKyQjtNQRy4UyMloc84PNgBQFLTz2/SaOpQpOtAbd1nFU9+tSwcs3HddydmklsLUSyBvAwhtSsLE5gMGXIon4ZYCLtSxJYbCcvkB8CTkI6YuXLJcv6xaw5EtP2Xb+EAnoO2vea2MioZaB2gxnw1oMeuBePHdKfXxwViOkx46DX7gBYUUlfI9aCOOsSwdbmmNoWhLYQA2JD3z88Reod9ydKNjjUbR+LIuNJRFomjH+uRFoNvLJrBtm4LoZ0Zy0eugp9OjxBt4dMh6pEuYxAiKXTr0hfDeb43Qhuy01IgY4aPJDY8oi0JC2kAHXd4V0Lu1E2Fge4V9NP8Auh7yE/Y4aghGjPGRco0GJIvrUmDBsLukYTODFiVjFXEtii3LX5FU4mzZ8/17QPuCSeZG41DH5+9dqz7QS2HoJ5BVg4W3xBeGgxWnp0qUYOnQo3nzzTUyePFnAB/cnXywFI6ptkROr/WF5PafaoRq/aQFLje8i28BtIAF9R/nui3klCEFfETLILvzsU/T421V4ucGRWHjDtcjOmIGgtAxRNhNrSAgLOC4wxNhHJpsBkwryO8+h5Nk+I3FQnSYo2L8PnnvRQUWaICUGLGTSFX8XcrY4mD13BkaOGosr/3ILxo1fKKBm6cJ1GPufcZj9+XSE2Qwinw6+hjmXUUYmpxBBSmwCis3QBrBUlfMDBxkngBsBrw9ZgSNP6I+CPR/DvS1mCIiSiGwxOVHLEsDJpoxpyDcAzsiIYyMBjQnHpuiNBub7a1e+qftSqdQmgCWp6dYxOl/H1W+6Z7v/fyuBvAIs+vCXlZWJCeSoo44SEwjNILvvvjuuueYaNG3aFF26dMGSJUvEhMRzkr8CzEttXl4FM1zq+v+2O7771S1g+e4ys2fklwT0HdZ3lEvJ2eNnEKbKMODRdmh/xil4o8GRKO/7LPw1a0W7EjlZAQkuzTr82seaDppN6F/iehE2FoU4pfGN2PlX1+O8S2fhq/kBsvQlyRifEiIdwp2smyZRP5rcfTf23OcQ7L1fXUyaPF8cart27omLz/09/nbFH7FiPhMhGnI6yR3EiCRhtzVgyfC/EGAYACMViLnKMPgyColaFiprbr79Hfxqvwew816t0KrdHJSVKTAJ4UkiR1+yVAsaE5ZdalKMc7EBLWac499tBVe0DzgGp9NpcKngJPlUaTkBmDFASx6361YC30cCeQNY+ODrx/nRRx8VoPKLX/wCP/vZz2Sd4OWcc87BSSedhD/96U/4xz/+gWeeeQbz58/HzJkzMXbsWBQWFn4fGdXoc1QmSR+Wnj17Sps5aChA49JOVgL5KAEFLPrxE78S30U2VYYVs6ai41/+iI4nHo33GzdA5duDERQXIaLJwqH5JEQgDrBiL0FIfzUCHpqDQmDylJU4qXEzFPzyNtx0WyG+XhgI7wk1LMLXJlYecqr4yDhprFi9FhtKHNxxVys82/c1rFlVig1rSlC+rhiFixaaqKTQBR19STpnzE/U0lDzEfuSEDjlnGFVw8LreuJIzGuvWuNg7LgNuPzK5/Gz/R/GZX8eiUWLTX4h03ZqWUjtb1ICiD1ITD/KisvrbVvAQvmXlpbK3KFDB9xwww25H4ccWxWk5OMzZtucHxLIG8CigxbFeuedd+YAC7UrZ511lgATHqNakqrKkpIS6YF58+bh4YcfRr169aTce++9Jy8cD+4IH3MLWKSb7Z9aIAEDwKldIUubh9SGQgzt3hWdzzwFg846GeXPd4e76CuEFeWIXLLfhnCzjBAyDrvEC5GYguhESw0L0OLBl7Dnb+7Bbgc9iWFDXWQqIvFrcT0fAW0zOcBCTYmHFM1MANp0eBr/vPlejPt0JkIGBjkhIjcDMAQ6NtsQ5IjOg9enQwy3Ej4tXNd9jFgiKR5J6dIZF1269MGyZQ7eeHMZ9j/8ETQ68xVcdMlTmDhpHbxY60M4Qh8847tCszb9ZYx2R8GKeSxY8of9YNFxpn///njjjTeQzWZRUVEh4+3s2bPRr18/+UGoY6qCF8reTlYC20oCeQVY9OGfO3cuzj77bAEtZ555Jr744guRB4/rC8Mdus2XevHixWjWrBn22WcftGrVCqtWrdrE54Xn5eOkA8m3aVjy8b5sm60EVAL6TuuHWRIXehmUr1iGztddi67HHoGJf7oI2clj4K9ndFC5Sc4TKzSoUeHbHcQRO3TWZcQNrUT/uLEbdtmvHXY75DlMneIjmzaART64cQ6AUFhwPbh+BlnXEV1Ji4cex9QZS0xGZRPJjMhNmySLkSMZmnme0POLppNtiLUpzBTNKCIBGAQzJgyafjVs58iRI9G5U1esW5fF20O+wm/qtELB7s1w8eUD0LbDf7Ch2PjkiJlLhSQ/wFgXNSy8cU6sLTnHu7/jQsfGlStX4qmnngKX2if0DeR0zz33YM6cOf9VswKX/zpgd1gJfA8J5A1g0XvTDzTNPG3atMGUKVPkkL4Y+nLpC8X9nHU/X6oHH3wQ9913H/r27StAhhVoeS3HpdaZPF/bUVOWKo8kYLFhzTWld2w7tpUEXNeDH0Qg5T2dUyM/iyWTJqLLny7HgOPqouTef8P9agbC8nWi6QhJje+Zjyl9Vggc+Onmu0yTUibticmn2X2Dscehz6Bgn2fw2RRGDRrfFTr2CqgQkEHOF9eYhbIuxo6fhutvuAuz56wSp10qNSpKKvDu229gItMBuJUxSZ0xCRmzEP8y6aGagNg2A1bUryWbIUFdhBEjhqJL125Yv9HBwkUBzjznKfxsn+bY65DHcGuTj7F+owFgZMileoVAx4R8q4bF5EoiQKKWR+uv3hf6A1B/2FU/rts6JhYVFQlgYbCDjo38Mcjp9ttvB7XZOulxBTS6/4cutS3adtbHMTB5Hb02j23p3n5oe+z5P64E8gaw8MFLPoj6MHIfH2I9rg+0ipH7OXPiMc76cBPwPP3005sc0/OS5ZP7atq6BSw1rUdse7aXBMRdI4yQzVQi8h0MfOQRPH3B+XjzuLoo7/8Cgo0rEaaLEHnZnJZBxgYxtRithEduJvqK0LE1G6FZs3ewy4HdsfOBfTFukicOt7HPrHzsDcggQDC0CVnHx5tvDUO3bi9h9uyVwslCU9P6wg0Y/dFIzJr+WQ6wCIGcJDzk+aYOE15cBVqE9TYM4NM+FQGpygqkM+V4tu+zGD12spiuWj00Agce/hAK9uyIG26Zio0bjN+KENLxBxl/XBnjk4AgalgItgw44thnnHy1XzgeVh8n9dg3LXXMfOedd0CzEMOaOXP6z3/+g0GDBuVM7dz3Xev/putW35+sV8f1ZBltJ10DkmWTZex6/kogbwCLijgJQLiPD2jyweW2PrTJY9UfXn1p6cBL7QQnBT/Vy+q1a+LSApaa2Cu2TdtaArl3MgiRrajAhgXz0bfJnWh73DH4/NKLkBk/DkHpekROuYQ6M3zZfLjpF2JgAg0lJHKj9oVgZcO6EFdf0wc779cLx536MabM9CU6R/hXqGFhFmfQd4V1GE0t72v16o3o8+xA3HLzfRgzejpcx0TveG4KoZ8mIYvJWyTaFIIT1mD+mRBjgogYtEjKgKpIRjEPRS4qUmUY+MobKFwfYG1hiKuueQ27/KYPTv7dSMyb60taJNqmDLEd28goI6O1Ub+YnEaHZiKEGDNmND766CPx76PZqbKSmqCtBxfaBwMGDBCzEM+ls+0rr7yCdevWbVJX8sdlcl0KfY8/em3WxTFPt7UqvYYuub96GS1rl/krgbwDLHwI9UHUJR9Sqib1453sjurluc2y+uvg/fffl8ii1157TU5LPvDJemrqut6zNQnV1B6y7fqhEtB32GWYsu8hvbEI/du3R9szTsPTDY5B6ROPwvliLsLyEjEV8WsuVPziJ1IFVghYhH+F6Y9DoEePITi0zm0o2O1R9OzrIJWNxKHVdQkEqKGgScfQ+NOcZH4AhcK9QqUtgY2TjcRlRMaNiGxzdGghQKAmx01oOtgO46Ni/EqkNeLHYrbVfMEkiykEkSdMvmxqKh1h+EgHhx07AHse+jw+eN+FnyWdPwEY22gcgqvzvRAi8UZDcv4jRP/+/dC5c2d89dVXIOhgNKGCli31kfYBy32T9oJldNIfhLq9LZbVx2Y6/mq7uJw2bZrcW7KcEtxti+vbOv73Esg7wKIi40PJh1E/2LqfLwqP6YPM/dynL5C+VNzmRE93hkLfcccdsq3nykYe/NH7t4AlDzrLNvF7S4CaBOb0IVHc+oUL0PaKy/FU/aMw++YbkJ0yAf761QjTFUa7Iqy0jpDE8YLqw8IPOD+p2awLkuT27PU+Dq5zB356YF8MGOSgtMIAFnENCciOG8CPeVREMxJrWVwvRJs2HTFi+KcgRxwrZfuKi9ZhwVdzULh6JeQCBCgRQ6iNL0vV55yt4pYBFGZZxdTNcziztQxhdlxgylQXJ532HAp2a49r/zYZUyb5yDJ9AH04giz80IkJ6sw1dfwz0UkR1qxelRsrdQxcvXq1gDACMd23tR3EcUfP0bE0CRSS61tb55bKJYESOWD0utQaXX/99Xj++efxxBNPSMQSy+qYvz3asqW22uPbRwJ5BVj44OkHmg5gBBl33XUXGKq8aNEikZAeZ1l9UPXlZQFd15dt/fr1OOOMM3DvvffK+TxHy2wfkW/bWvV+LWDZtnK1tdUcCfB95IeXiQijbCUKZ83AM1ddgdfIu/LuG/ALlyIs34gom0JE+n3Jt2OQhJyb8/Eguy21sREWLChBo9PuwE/2uBFX/30Bli8P4Hj8+MdYQhYEBMYXxPWZ5dlE8yxesgyPdOyEp5/uhfJy43RK0DFh/Cfo+nQnfDZ+HKI4eka0MrEfC0GKGXcIVjadCXgEpIhWyAAWLVFRGUiOodbtPsO+hzyGXfbvjoaNBmH+13SqjaFPRJ8NDTCIzydY8mieAu6/r7loH7RX+UHnzIhLdZzVY9+05L3omMoyyW0FD9xv7rGqlurbVUe+21ryGrpO0MWwai55HbaJ97OtrvndWmhLb28J5A1g4YuiDykfSAIVcrCQPO5Xv/qVhDnfeOONQtNfXl6OtWvXgmCEREf6Uef5+iBrXStWrBANS7t27UTWFrBs70fO1m8l8N0kIB/JKEQmVYbi5YswrPuTePr3Z2FQw7pIj3oPQfEaIWyLXJpj6BtiQIvLBKmktI29SKjpILsttSLtO7yG/Q+/B3se+jiGfOAiVRnnD6LKIv7o8rrmnzEPGVZaOrmaqGnWzHUDFAxhWxS6VOkKB0xI9YiYsImCWLHRfqhmhefpeMRj2WwaDNnOXSeObKKzMQOeZs/1ce7v++MnB76AXxzUDx2fmI/yCmOSYiQQNUnUChlTFttjzFJsQ/u27bBmzRq5NwUo3CZg0fHR3Pnm/1a10xzX8VP6ZvOn5PZWPzd34DusJLUrPE3rpBNwr169ciZ+NfUPGzYsd7/a1u9wOVu0hkogbwAL5ceXQx++CRMm4OSTTxbQ8n//93/YaaedZH3XXXfFwQcfLERx++67L/71r3/h3XffxZdffildwAedM18A8reQFfeCCy7IHd+aF7Am9aUONlbDUpN6xbZlcxJQjcHmjiX3aTldCnDwXEROGiNfeg7tfn8WHqlfB+OvvADZzz9BWF4Uk7UZUEDTEU054igbAwoCAsdzkXUj8Tu59LL2KNjzAdRp8DrmzPORyRj+FcP1Yj6IBpAQBNCkYxxaJVSYWliBH6yVYIKstgawkNAOOfZZ4ie2SedNAYtE8tD+xLoIOGh+ilyZCVqCwGSkJygiYElnIoyb6KHuiW+hYI8uuOm2mdiwkWOiaS9bZQALNS/UuLgQABWFSFVWYtasWbkPO8fDF154Qaj1k7L/tvVvAg0KHniujkdyTwmflm+rd2uPJa9DTQqn4cOHi19O0heHbeA2l8lztvY6tlzNlUBeARYVo4IW/jqgh/rNN9+MvfbaCz/5yU8EtOy8887gTA2MLg8//HAhjmMoM4njaE469NBDpcyVV14pGhnWr3XrtWr6UgcIC1hqek/V3vbxo+HTtywXKWNkwf0EI+Q8CYQLnz9KDGcKIUKGfgixmp/OthuXLkL/B+7B042ORbejD0J5/+7w1yxBWFmGiB+nwNDbZwJPdCw+TSKxVlV+7DDLsGs0LNf//VkU7Noed9xbgXWFoYQ5x25tQt0vYIfjAdsoH15SJxBAUHsDDB85EstWrJB1EtH5nmGPqygtQaYyhZAIgxFJvH7M5VIFXKoATNVTQTDDSB+jHTJLfpRNiDI1QwQsX8wPUO+ELijY+3HUPWEwxo6nbw/TDFC6LG3MWAaw0FzlStsoawIUkme2bdsWHTt2zHFQVbXhu699m/lle4CFZJ289saNGyX1CnMa6TEmwp06dWoOPOn+73539oyaJoG8AywEFAoqdEkafjLXDh48WLQl1LxccsklaNiwYS7XkAIXLqmNoVaGgKZBgwagtoZTvmlX2GYLWGraK2XbszkJiLZCAItGyiRKxeoKErRKFA/J3cTvxAAGcpREjoM5H41EmwvORL+G9VDU8k64X04Tc1CUSRlNBrWnEp8D8WLhx1uqFnK1EB594EJg5QoHF1/yJAp274TX3nRRURYJYDHKDgOrhKFWdSO5yERGGGalzhYPtsS4CeNFiyOmnTBAZXk5ejzzDJ56ojMGvvQyKssr5CbFYVfOSgIVtiw5cbvKnKXARfZF9MvIwvUYsQQ8228p6p7YR9p/5z1LMG2Wj8qMccAVJt6oyo8nCEw+Jfp43HTTTXjsscdEmzxw4EBJELu1H3MdZ3SZBCo6DvNuWN/2Hkd5DWpYdPnhhx/KfdEVgNM///lP8WtU81BSynY9vyWQd4BFxc0HVl8U+ZUWqx+5zpkvFimkCWLo76LaFAKWn/70pwJWmDBRmXIZIpec+DJwrumTDiBWw1LTe6r2to/vkbyXMaBQSeg7JiCF2ogYINAxljPfPs/x4KbS8Dasw7P3N8UjZ56MD844EakP3kSwcRnC8kJEXkZ8SYyJhZocfrxjmEDSOEl2GCDrG1r9du374KBDb0HBnr0w+G0XWX7sGaYsr7uJ6JG8PqobSYwDaopo+eCDmPDZRGmjfDwltAjwMi68dBaB44mWxRc/mhx0ShiSVAq6/G/AYjIuG74Wmoo8P4OKdISMD/z5undQsF8v/PKg3vjjVT1QSNMQI6C8DPyIoMpFxqmEx7xGIEFeM9FE8Go6rulHX1uwpaWep+U49mjf6j4uq5dj32+rqXrdrJfAhCYgvQ7Hcpqv7LTjSSCvAIsMetUefj7AOm/uBdSHeMGCBRg9erT8qiBZ3G677Sb+LaSZrv4SaH350N0WsORDL9XuNvJ90vdQ363kUrUqOZNG/DtBQAtJ3srLsW7mdHS99k94tP5v8dml5yHz6ccIy9Yi8sqFm0WcX8UPxBc/DtVqhBIebIjfsr4rH/XHHn8dBx7aBDsf+CLeGeIimyW9vfYROU3iRIQCfIyZhe3lpICldevWmPz5FAEs3O+QE4ROtvQn8emVG4fvxNWas/k3vrl4f9WC+wls6HRLU5DOhCGMEsogCDMS5px2I4yf7OPUc99HwZ6P4nfnP4cFiwPIZaU07zOb45DhNZs0uVMiafR6Cja4rXwmemxzSx1ndIzVpZZV+ej2tl7q86NL1q8/WJPXInhhWzZ3LFnOruenBPIKsKiI+bLwgeTD+00Ppg6IyXO0vKoKp0+fjosvvli8zFmu+jnftE/rrAlLHUishqUm9IZtw7dJQN8vggsBI0ohoKaX+JNNbEAQk2GemjBA8fKl6H9/M/Q99zT0OeYwlPfuDm/ZEoSpUvjZSoQu1SN0XPXhB1nRKphw5NhrJqbmd/0A02ctx4kn34aCXa7Dv5tWYM3qEEIUJwE9RBsmvNjAB6kWAnok2zLpVYyzJ/ORfTZ5Ug5+8N5ERWTwRdwmam6qIhMNWPl2wCKIZxOwwkgiRgC5ojWh5ieVicR5ePCQLA787eP46f6P4eY7J+aSIhL2kHiOd59xSJ8fouldd2L+/K+kezhmSnu/rbM2c2xz5ySBD8fXZJnk+maq+0G7kvdAThaNfNpcpUmQs7njdl/+SCBvAAsfui09eApiVPwsn3ywk/v1Ab///vtxyimn5DKNVr8GX7rt+eJpm77v0gKW7ys5e96PKQF9jyTvTQxI+DHnpLoFHuM6syo75AkhlWvo4dO3BqP1+WfhuQb1MO+6PyP96Sfw1xUiyqQRMGeMieCVMF5lfVXAEqjWJQiRzoa4u1lX7HXgzfi/Xz+A9g9nsXF9KARs4vMryXlYmVG3SLvk/Te8JmyrJlQkDcLESZ9Jexk+LeNGCFSWV+LVQa+iX98XMGHceHhkfctNrJHzN01yRdGRGODCdphzCFqC0BGnXyqZSRo3dkI5GjR6FHsf0Rc779cRr7yxRrhkeJb44AhQIzjx8eUXc1BRUY5UKiWOqvzIjxo1aqujhDiOctLxhiaYDRs25HxJ9I5+zLFS28Rr63Wrj9/JMtpGu8xfCeQNYKkuYj6YOutgmHxo+WIlH95kWdalqt2FCxdKeDSd0TixnNZX/Zo1cVsHEKthqYm9Y9uUlICAldi/hH4lnPiucU2icYwTiWhfSKTmOJUoXr4YXf59Gx48oT5Gnn8m0h99CH/tGoTl5QjTGYkwkm+6fNt9ExZMWnxG3ChjbMBImRDlZREanfpv/PLA9jjqpLcxfaqPbDqKGWNNlA65S4xDjGm5GVNo0jIf7GzaJPx7ecAAzJk3V9quMETGjSDE8qXL8OXcedhQuM6EOOeEoCVzO6qtKGDhzVSBJJGRXD9ENpOC74cS5kx/lvdHlOCwY7ujYO8Z/FFrAAAgAElEQVRHcNaFA7FyNZl1SYDH8zmeMUiBoCnAvHlzcffdd4N8VXRUZR6grTEHaSN1rFmyZAmaN28u0ZnnnXeeENIZOWnJTZffdmzTkt+8lXTyTYZXE5DoWM726bWMzMwzpse/uXZ7JF8kkFeAhQ/ntwEKPqT6wLIDqm9zH+vgfkXexcXFOPXUU+VF5nHWry9Bsq6a2qE6iFjAUlN7yLaLEpB3MXaEFU1K7NfCnD00/xCr6IeI2gEmAUyXF2HppE/R+U+X4enGDVH6eHs4c2cgKC1GlCFNP993aj0CMb0IF0rMlyJJBOVjTfI0B74boXhjiHPOa4eC3TriwfZZ2WYSRI8pgHL2HEP2Zgjf6NsiSCjHIqu9WQW+BFrIbn4YhXeFNyNcLJEkWqwaR7YMWNT3hkteQ2XHcYmaH/K18Dq8xPJVZeja6yPcdvc47HlYF/zyoB54vr+DyhTDyE12AMqBSRE1zxABTDZr/Dy0brlIrMlRjU51TZDew/z589GtWzeQcJNtInEbtdSkmEgGLuj4auredn+1Hazx266hx0Ru2+7ytqb/sQTyBrDIgBcDEj6EZLFlhA9tycwF9Je//EWcapcvXy6/HChXfbj1XJU1t/WB5gt45JFH4r777pPD1dF49XO1jpqytIClpvSEbcc3ScC8b774mJgsygZoCNhgdJBgBO5j7h4XDk1BkY/iFUvxStsH0e13p+CFxg2Q+fRDBBtWISwvEwfXiAkKE34TxmxC7haTvVh4U3wPgSuIBF99WYyzzn4YBfv2xrAPPYkOyqTIAcOWU4NCrQR/0LBejTYyn26PYIQmEV5TTVexbww1OUKBT7MJb4ZoQrCJ0ZJIlFL8Q0nGkyASzVDIMGXHM866QnBH3xOGdJuZvigK7jheiUcOAQsRFoAPho9C/YaXoUHj5tjrsI4oOPBVHHbcSDQ+rTtaPfQaSkpNeDMzTpus09w23C5sIOtke1ivkONRbuIrU1WGx3kv5Mrh1K9fPwwdOlR8RhQMvPXWW2jcuDEYwKCTnKcbdmklsI0kkDeAhferLwHJgq699loJTSazLflUfvazn+GAAw6Q6J9GjRqhd+/eOeDCF0tnlZv6sDzyyCP4+c9/jtdff10O6QCo1+JS1/XcmrS0gKUm9YZty+YkwPdHAACTAMpszBXyTZf3GvIRpq8Fo2GyblYig3q3aYPmpzVCrwZHYuJ1V8L5YirCio3iuxKSm0W0H8a8az6+NIcwy7Gby7RM05KYcUKgZcvu2Gv/6/Gzg1/CR2M8cVwlxgjEaTcBWOIszQIYBMbE+INtjWcCC103X3QCFUYJBTG7LSVhwADLsbSUjzVCJqIodtSNKzLlWFZnc45oc5hl3nMkkaL+qPp4zBjsuU8dFOx8NHbZ+3b89JC38Ms6H2PnvZ7AhRf1wtp1Rm/kx/dDMjkCs4D5lsRPx1zY8RhRpFFJXBpZsP0y9sUAjCYk/kDk+MuJY6W25dZbbwUjMTnpmCQbefjHPK/GnJSHzd+hm5xXgEVBRp8+fSR/0J577ondd98dv/71r2VWcjgy3hLAHH/88Rg0aFBOVUk2RJILsR5VX5Lx9sILL8SyZcuko/mw6swdyfWa+CTo4GBNQjWxd2yb9B2SjxujeCRzMTUJxgxEZlv5HlJb4TuIAld4V5ZOnYEOV16NR085GSMu+B3So4cakrgsw5hNziB+LBltxPNF80FzLp1TGdTrZ+GFjoT28n0PfaB16z74bb07sfP+PTBilAfHN8kOJeePUfMYs4swzho+FgUPNFORNVc1s6SEpzaXE+sX8BQDD+11bqrzq0fzlAIRmrLEZGRMPJ7nwg+MBkf4X2KZ8L54fyKrBOgxbYjw1jtv4vC6R2GX3Y7ATr+6GAV7P42CA4egYL9BuPjysVi9ThMK0EfImIUIHAmD6NDMZI4GnLBlhu+F2iWFZWbso/rLtJxRRl26dAHN6GxD8kcgzULTpk3TW5clTXwqr00O1MAN3qudar4E8gqwKJq//fbbQS0KGWqZpZn2U2W6PeeccwTMKC0/KftPOOEEcayl2vL0008XExIjgzgfc8wxQi7HrlLtii65zwKWmv8Q2xbWbAnwHaJZxGgsjNZBPuSxDwo/zGI2kaigAF5pOaa88TaePPcPePmcc5Ea9g68FfNjwFIheYPEL4UfTSopqn1reJ0APnySrQWcgTGfzEGDE25EwU//gpbtyrG6MIQTQLhLItOA+DtN7Q8/7gawsGptN9f1w0bzByNtdFvGiqR5Kv7s81zeq8MswsK0GzdWQAt9b0wGaDH3xFoY8elJyIagKevyPtQsxWWEKVMn4bFOT+CuZq3ws91PQ8GuTbDboS+j4DdvYv96g9Gx83yUVpgQ6KyjmZYjeEwxIEkizX0aH5cqM5ARhD5TRgKUQmVlhfgZvfHGGxg7dqwUoPMuEw3SRK+TjtO6zfE0n6dkH+fzfewIbc8bwMKHRh+cq6++Gn/4wx8kRI+dkAQYpOkfMmQI6L1O+n2l4ieASc4/jdluWRdVncl69Drcl7yuFKphf6yGpYZ1iG3Of0mA7xB/aRvnWn5qYwgg+83HjJqWTDaLIJtF6dLl6H3rv/HUMcdj0CknIzPuQ8NqmyqJkxzStGHMGqKhCSKM+vAjPP1kFzzf9wWUl5aLT4lL1tcwQGlFgHuaP4e9D7obv6nbVcxBpLLPMt0Pxw/10RBEwrYpeRvXc62VdQmTFl8VY87xXUYjcZxgPcbnRPIXSb0GqDHPj8tQbWpMqMug9cg3OZToG8IPvAI6NsFoWag54rXVPMSlaQ+BCzVVPDp23Kdoek9z/PQXh6Fgl/NQsNsdKNirC3516EAU7NoardvOlEzUkvZAtFHGXEazmUCxWHuSvMqmGhaOu8YXR8dFaqlffvllPPzww3juuedyCRX1uD4A+QhUkveQ/K7oPdnl/1YCeQVY9OM8e/ZsMePQW51TUu2oLwk1Lh999JGoKd977z1cccUVYAJE0vEfffTRotpkkizS93NKPqiyI0/+qEySJqGePXtK6/WF473l6/3lSTfYZn4HCdCPRfwo5ONN/xYTTUMfkJljx6LzLf9Cp3PPx4CGJ6Ose094KxciTK1D5KVjYjeaUJhKIwLJH2me+fSTTzF86AiM+2QCpk2eJhwopSUb5IPfqk0XHHDo1dh573a4s9l6rFxluFfEJBQSVPD94A0IctkEsHBfDK8EsBDAcBJ+lZjN1iUNv5hxTFkDOBjNw8zNATasWYu+Xbtj3PvDEBSVIJLEiAyfDsQR2fj3EDoZ0CPnxw69VeYgRlE5BjwwpaHnSf18x7+avwD1jjoJBTsdjL9e3xtvD3Fx4SVjcciRL+GX+7RBz15zUFkZYejwj7CmcKXon0Z/8jHGjx8Xm8YNKKkCKsbxWIGK7uc4q2MJrztx4kShxJeG5/EYqu23y5ovgbwBLBQlXxJVN44fPx40/+jHmS8Sbab6AWd5fbm4zl8FJDqiBobrCnL0o17zu2rzLdT7tYBl8/Kxe//3Eki+h2wN/SRolvAYjRM3L3RcVBSuRdemTdC+0SnoetwxWN2sObIzZiMg8CjbgMg3ifzEHMTsyIjw1ltvokevbigqMY6gAbMbRsD9zZphwoRPpP5/3twaex54Pfaq+yLGfGqig2h9YvCQAgJxQqUpSDQPxlRiPtSihxDQ4jLiKDZvLPl6EcpKyrSIjDUKbMS8Q1Dmk9TOxRefTcKt5/8ej57/B7x1+50Y3b0r1s3+HFG2FGFEh1cPrpuN/VqogTGaFbaNvjkM/eakwEbdLSorUwK0ZkyfgTqH1cVOBb/CA/c9g5L1IUYOc3HI4U+i4JfNcemf3sCA15aKeYhtpHYmlf5/9q4DvIpibaP/Fb3eq6B0EWwIAuk9BBBUrKDY6UVABGnSBQSkSQ+9l9ClCgLSO9K7gHRIQkJIz+lnz9l9/+edOZMcImBBkXizeTazZ8vs7JRv3vmqFQsXfouMdJP8BsHKIWDjAUEZuSoevRYvyyJZjl865GQbc1Op+OH5Rxp7r2/e5c49J3hfu9e/459evjwFWNgYBBoEJty4uqpTp47Yd+zYIQANlWkVqFGNxw6nOt2tjnnv7a6pvO619LcAlnutzPnl+d+qATWu5IKDVjzUD2F4PgNOTpAcnzYL0s78hCHv1sYYnwr4oXpVmOYugBYbD91MRVuCFZo9a3BT78PtguZ0YvTo0Th6/JgAJuQ6aE4CGR0Dvv4KOz2ApeWn36BYmdYoWGYG9uxn5GMDbhcVWqU4SCrTUrQjHc9RJETTaGlJkyPqEWX2mBS3/7wddm7feSNgESIcWiRK3y9uzQ5Dc+DMj7vR+ZVaGOofgGifyviycnkMrV0L0zq2xqaZk+CMuyBBmfhOyqk8ui0e/RxiAVmHEkwIRWNhlMQLwOlTJ/F02bK4v8B9+LT550i7psOSbuDTT9ahRJmBuL9IHxR/thcOHndBo76QUAaWysr0RyekQpRTyQNRfxKmeQMWt4xUrdCSVxcmTVaghOXkphaEPFbnvB65Zw+pQE19HO6Ktt6zhf0fLFieASy5B4UaIIwLNH78ePj5+aFUqVLo06cPTCYZ1l0NGkUwVfvyt3peyI89bqfV9byUqkHlzWEZO3as+AR+o/r2vEQ08lL955f112uA/ZC7mxwKN73Q6rC7XXAIwOKGy2GHMzkBM77sgIFRAZhRriyuNmsGx7Gf4E5NhW4xi8mUXAgqi5LToBYlc2LmYf68JTCbpUWKw2mh3Q6GDO2PI8cP4VqyHQ0aDsa/H2+OyFd+xMmfqQBLzorEGhTbyPJxcpZ+YHJ8luQsdPiVHEPqvV/16YMd27ZnAxZZC5IzISEBxT0aDKdNAK49UydhR6vm2Fb7dayMCsfcQD9M9ffB+JAAjKoZhXZBlbF8cF9c+XErTLEXYTisQmRE/Rfu5LYQ6EmwJ7kwGkVLMHDs6EGULVMS9xUogE4dOsCSboVuM5AUp6P5Jxvx4JPjUaDYcLzz8UrEX9Ph1KlsrACL9BtD6ywY9OJLsVOOIjCti5SZON/FulIb6+JO6Io3TVd5qlTRLfX7r05Vu9ICtUmTJqD16MyZM/NBy19d8b8z/zwDWNR3qQHCgUM0rEDJ2rVr0aFDB7DDKSVaXlODShKlnMGm8mN6tweH97vv9DgfsNxpDeY//1fXAMeXnOiofEvrHanWSvVPp8sBa2oyJn/ZBT2jAjA2pCLO1PsQ1u274EpIgJ6ZAcNuA01/qT8izJaFZY0cy9euXceoEePx8+kLHo6IhoaNP8C4idGCmxA9fjlKl22K+x/5HOMnO5CabsBKUZDgoriECMTl1KSnXHojIQcHdDzH/UZ6we9Q3N0hQ4bg4IEDuaruRsAi3PyTU+OyQ8/KgBZ7Cdatm5A5ehSO16+H1VGRmB/ijwnhvhgeFYg+Eb7oUyMcfWq9iOV9e2N3zCy4riVKvzPkvjgs0kLKaRMiJI59er49+dMxPPN0GWFU8FnrVrBlkSMFWDMM/HzKjad9pqNAqUm4v9hgvFl3Ma5Qh0cDnPx8foHgrFDR2Apdt8BFvywekEmAJE2iWRc5zub4GOmrose5KuJP/ck6/yvfo/Km7y46I1XfRQsoevLlPJO/3Rs1kOcACzuTJH43ViA73c123sWBrRA0UzXJ35hD3vylviWfw5I32+9/pdQcd2IBQRNf3S1EQVa6iHfa8fOPWzHg3TcwPqASjjf4ANZtW6DFxUoX/E4bTWqExQzrSulxcPKki3mmly9dQuyVK+jbtw/mzo/Bnn27YbLaEZ9kQ81aXfGvQt1Q45UdOHPWDYvdQDpd13NyJpgQohCxahHvEBwcYdKcY9as2ojlV+Otbdu2oBj6xk0BFk7uaqfcyQndnCm+hwBEi4uD49RPsO/bBevWNbCsW4ytbRpgepQfpgY8jzkBFTG9UjlM8q+ELU0bYlObFpjfvCGOzJiItEM/wp2eCMNlE6Inm92Jw4ePofQTT6FAgQfwedtOsGQS2AD0E5eRZmDvPheatDiCR0tPRcFiIxERNREffhyNn35OEaUkIBFWV4K74hQgiNZL9C1DrhgBjfBQTMjoAZ/eNJh1oib9G+vj5r94rwIF6g7v/NS5u5GqctOnTr9+/W4IBslrJ0+ezJ477kZ58t9x+xrIM4CFnUd1LoX++Wk8xwGjAIm6jynvU8/cTiH39lV0b19VBDQfsNzb7fS/XDo1BuneXvhfoSjIpcFps+Ha6ZMY3OQjDI4KwbdBfjAvWgwt9jLcyYnQLVl0Qyt9lXhxaaRzM6kUSvf7P58+iSGDB6JNm9bo1LkTNm/dKrgr02O24qnn26LAf3qjVet0XEvUhXdbpzAvNkPEHvJy5CLNiMlX8bjBFzydG1tO0ZmuXbuCVobcciZfApbcO3VDXMLZnW61iqCN7ox0uFOT4U6/BndqLNzJ5+FKPAPL2sW40qUN4j5thhWBlTCrwlNYEFQZMwMrYkqID0YEVUbPgBcwt0NLbJ46Dpf27RR1dPHECTxbsjQKFrgfn7doC1uaWUSw1slFcRgwmwxcjdcRFL4UBUuMR4FH+qJO3aW4HKeLeqKIiFwlp8vmcd1PK6ic4LHU5REWTx56y29WNDjn22+spzv9xfyZ91+9qb65cuVKzJs376bcFNXmf3VZ8vP/9RrIM4CFn8LOpTqY97H6zNydnPfwnPeW+znqu9BqKK9u+YAlr7bc/1a5qdjKkSg0RSiCcGtIjY3F8DatMSAqBFPD/JD6RWfYDx0Xk7luYbwgp1BAVWOeNUaRElf7asXPCMRDvxmCxISrAizY7A6kpGdh8vTv8MTTH+GhIu1Q3m8lVn7nhDmLVjeS9+E2bIKTIPGFEIyIBtGp2yEAC8vL0uYAEE6gSiTUv//X2YDl9i1JToUbBvU9HC4Ymg7D6QLBi+Gwgd+pW1Kgm67BnRYPLf4cHMcPwLxsAcwLZyJrUjQONWmIH16MwpqwACysXA4LQv0wKdIfA14MxNhPPkD/Zu+jwwdv4dl/F0S3ps3gTs0U3BVWn0MjhxlITzewe58LjVocRNGnZ+KBYiNQ6825OHmGXoGlfxhp5SR1W6jYS38vDrcGm4seg2Wco5t9a24ae7N7eC437eU5PqsAQe58bka/b5X3nZxX723Xrh0SEhKys6JV6fz584WDwOyT+Qd/aw3kKcBCgqFQt3fnZ4fneXVODQL+5sbr6hxTEh31TPPmzUHncUlJSeJe1Xn/1lb5HS/PByy/o7Lyb/3baoAjkYqj5KwYhlNwBrYtWoSh77+Lr8uVxomm9WHbvR9a7DWpt+Kyw+C9FNl4gQZxTMBDroWhY8qUydi4foPgCPA24dEVQPsvolGsdGvc/1hPzJrlEGBFTOB2KY4gC4KWRtIBiwIlsnqksziCFTmFS4gjaYmqQJuNeh5yQaQmXHUtd0qa4qaLfRdd8itpEYGLU4IyiqYYcsCWCd2cKjkvyXFwJV6EFn8R9kOHYD9wBJmjxiChxSfY/FI1zAqujNHhFfFVWHl0i6qE3rUi0C0qCN2iIrB+8BDEb9gCV3I6dJsO3aJDtxqwmg3Ex+to2OgoipWZhkIlh+K5FwYgetweZFmkKTVr2+GkJRcBm8e82lNkKkurjXRH0VeVqmu/JeUzN6u3v4P+qvJT/DN58mSsWLECq1atwrBhw3DkyJHs7/wt35V/z19bA3kGsBCQeHdmdnY1Wasq4nV1DzuhAjHqOlNaFVGJatOmTXjzzTeFotpbb72VjazV897P3MvHqg7yRUL3civ9b5eNY5HjSpgPu5zQ7JlIPnscQxrVwxfln8XyqiEwxcyCFpsAd1qW0GuhKIguYXWOe1qt5ETigcNBJVwqQroxbdoUbN+6DTaLXeAKzSlNlb/svQCPlfwSBQr1x6rVTpiyDDjt0jutTntmWhu5KfYgHSH4kBY3bCkCIVoMefzSegCT5AaoBRN9o9zEwvemDa0mZ406MK6cRZeM7OwJmEhwRoslKtfayXkxQbeaoJsy4GbsnpR0aHGJcF6IhXXzdpgXLcKZQX0w/dVIRIdXQnRQeXxbPRTfRgZhcqVyGPR0GWxs+Sl29R+IM98uRfLBEzDHm2FPN3B8vwtB/lPwRNkZKFxqEgoV74UDB1xIy6Dbfo+nXVpzud2w22l9dSNY8wYr6lhN+jetAMEZu714R9Ex9bx3fneDJivwtH//fowaNQpjxozJjhWlypSf/v01kGcAi6oqdt7bdWAOMkVU1DPqN+N/fPbZZ8IEukiRItmu+glcVCCz2+Wt8ruXUjXQ8wHLvdQq/8yy3DhtyW/MOccjtd/k+0VwQycMpxU7vvsW3d95HYOqRmB45eeROWwInD//DFdyGnSTVThbk4qeUgdNimbobM7hCdjHxQitWtw4fPggvhn8Da5dvZ6t57pk6Y+o5NMGhUoNR/Gnp2PzVg0OJ0AOi/SLbwjuCvMQircgt4YTqvwaAVjEb0+sHYqJbkJ3FGDxnlx57L2zJvhbud4XXItc+nXk1DAvKrkKjpLw3U9zY6IHFwy7A7rZBt1kgzvTCldyFlxJadDi42A/sBum2ZPQ9YlC+Obp4lgZFYzVEYFY6PsCZvv6YEZoOIYGBGJgVFV8/WZt9Hi9PoY0HIId05OwKtqBsGfm4qkSoxHiE40Xq36B778/ALq54gQuAJ1bWiKp7+Bib9asmbgaHyeAXVpGGiZOnohUWkF5VHcVT0z1gpxewe8kcM1RoqbYZc/evUK8lpiYmM3NYH2r51Sq8vurUu929H5HXpsTvMv+TzvOU4CFg0iBDzGgPEq1qkN5Ewp1zAajjgpN1BiVWQVFZIwhRnXmb3JYYmNjRduqvPJKQ+cDlrzSUnm3nN4TrlCaJeeDLu097uOp9UFzYAEyhPdaQ0QZFpOwW7rdJ/fAac1C/PFD6P9hXfQJ8sU0n/LY985bwtSX1jN6lhmGwyMmEWYuEijQioVKobTtoU8QvpflYGBDAo2dW3dg8tjJGD1sNIZ9MxWhkW3wSIm2KPDfvujW0yYsZYSxS45EwwNOeMJ7l4BFthSP1bWc84o+MDJxampq9gT7W1r31ybe7AnT8zqXYBcJD3FCB4Zgi3owusUF3eSAOyNTiM/Mu7fjlUIPIuhf92P+R+/CFDMdSV/1xv6672G5fyCW+/pjmX8QlkdEYrpfMKYE1MCsaq0wueYIdPKJRkPfeYgoOxr/LVgPL73YA9evUVGYeMkKp5YGzZ0FTadCro4FC+Zj9qwZsJgyBAeKASb3HjuAweNH4VRSHNIMDXTxZ9fIvWLbS+NwthljR8v2kxZYSclJGDV6FPr274fuPXvg7Nlz4n5WuxChUWwk/M+4RZsrfSJaihH40NSdx8I7b7aHXlnLAhgJB4V8L8FPThv+lrbKv+ferIE8A1jUYCZg4STN1PucYumpc9RTIVEhRyU8PBzFixcX4OS+++6D2hkckYCldu3a+YDl3uyf+aW6B2qAY0oG3PPoNejUP9CFC3k5EXFKoM8jhxDVEEw4aREkRC809HHAsJmxd+1KjG3TEmNr1cQ43wo4QLCyfStcifHShNnh0VuhUq03x0NMldQpcQkui9KvoA8XioZ0p46dm3Zgw5r1mDvnB/iFfI6HS3ZGUNVNOHLEBbvVAOd+xRHJqVIFIVSac0Ue3Xie9aAAy08//STCfOR+4na/b8ztl3cyf0nXZFl5P+uddUzdHx7zHLGcbqGptB2GQ8O53bvgV+xxlLzvPgxr2gjaxfPQrlyBbcdemBevhmneCpjmLcPJj+phWXAQtr7yBub7V8Ns//cwNfgLTHxpFnqET0MTn6/RJKQzpncbjzn9huLijm3QTSkwbPSFk4XkxHgM+ro/0pMSRUwnp90Mu2YB/ek0bf8Ztp04BDPF7gQsQpSngAcVeJ2Cm6VRNwk6pk2bigN79yL1+vVsXRZTpgnTp86AOYu5ABqjWwvhHJ/gTgApa1FywQis5C70kTzXhM8eAZAkWMkHLL/sa3n1TJ4BLBzIilhwYHPnxvPcufE6z1NPpW/fvvjvf/+LggUL3hC1WUVvJnflwQcfzOawqCCI6h0iwzzwL5/DkgcaKY8Xkea+BAnkc3DiYKwbzemWSqRCLYTnqQMiTY3VepZjyWG3QrObcOnIXgys9wG+CvLHTL8XsP/tN2HduA6uhDi4M5Jh2E3CtwiDGkpfKBIcUEwi49tIbgeBkZqGyNURK2xecgOWLCvS0wyERbVHodJtsXqDJpRJKeLIXoDfQVsomkOxiDed8D7+o9nfKg+Ob16jGEV8r5i0PfM2faU4NFw5ew7PliqFBwsUQLdWreBKvg7dZBYiNldCMlxXr0v9lzPnYNuzD6aYBTjbsTsuteqIhb7VMaHc65gd0BxTKtXDtMp1MS/0dYysGIQe5fywtms/XFm1HpaTZ2C6EovogQNw5eQJYW5O/zIuiukAdOnZAwePeEIkGIbwtUPAYXPY4NYdMkYTnfKJxjDQoW07XDx5Fi4TQRetqAxkpmehU4dOSEtOFdXoMtjnFNyQ4iRVv6q+qI/kFh5/b7Q44n2cIdhvJcRRT+anebkG8gxgYSWLgesiYcwBJyQiCrAweuiXX36J119/HY888ogAI+SgkKPC9IEHHkBkZCQY5VmJh3ieOiz5gCUvd+P8sv+VNSD9k1ANlS7iqQR7IwAgu11NpgxqKDgsTgfsNumZdf+GVRj5aVP0DQvA/BpRyOjzJez79gqw4kqKg2GjvxWuvLlW16DpFAFwjHteRG4LnZfRMojCITfFQlIRlyttu9UGF52JGMDo6CV4ruJnePSJDti8SxOO4ixW6qzcWQ2RzijAonJSYmn1+05SlTdpHEEKOcTe52RIA36/7nGYB5w8eQodO3yBjz6sh8ceK4IHH/w3AvwC0KR+A8wYOw7u9AwYNofw/aKbsqD8v7gSrkG7Egfn+fMwzZ6LrCmLkYiJGDcAACAASURBVDlmCTJHLcXRuq2xOuRFLAmogtmBL2FswMsYHFwT/au8gilNW2JEvfqIbtYYMd2+QOzWjUg9egjrZs/Gie07oJsdwv8LGWusbu6Cs0JxkssKXXPCzYiTBtCnx5c4uHOvuN/QDAFYriVcQ48ePZGeliZpPb3sevocPe6qTdF7glmpQK2u5KQC6LHNyO1xSrPsnKv5R3m1BvIMYPEmGOywHNgKZVNxq1OnTqAiLUEJQYjayVF56KGHUKlSJUydOhUZGZS9QrjxV/cQvFAhl5vKU/zIA//yOSx5oJHyeBE59qg0qmLZ8HM4KdGiRPI9pD6LZNtTr1WHkytrpxnn9m9H77dfQ79gH4wsVxp73q8D+6H9cF2jGCgZhoOcFbsQMdBhP4GPi5wDrpCJV2ix44kaTKsdioV4lX/ktrh1RmgnCwWYMHEBniv/AQo+1gGBkQtw/LQbNm8X9HfQDqQL3gAiJSUl2ycLx6C6dgevuOWjDOgq9TYIAaTuBm/+Yc0PKPJYUdxX4H7cX+D/ULDgQ/jPfx4Rv19/9XWkJaeQoIkAjKxjw2kRnCxaHpEL40q6BtfVa3AlZMCVkAXtchrsh8/Duu0ALnQfiMmVozD1hSpYEvoKFhDAVPLDHF8fLI0KxfjKz2JRrWpYUOc19PSrjMOTJuHyj3uRkZTC2I0iXpNLmH274HIyFpTDo0QsYxexbNHDR+LCz2dhsDMBWLT4W5w687MArIJppnSkPL60FKckWzTmqTG2zYnjx7F+3Trs3LEDR48ezV7EqmeY5m95vwbyDGBhVbNjKkBBAkHRD82Ta9asKQAKRTwEJ+SoUBT0n//8R5xv2rQpSGC4KXTO4FYKsNStW/cfZdY8btw48a2KyLKu/kqCKl6W/+8fWwOq/3DSlBOnNB2W06cELZwQxCRDcZHDIYL3uVOvYsmAXhgaGYzoF57B91EhsG7ZCFfiVbjTU2DYOZERbFDsQW0FOi0jx9SzC5DggUTCfbyMppwtFjLo4Zq6EcDx47EICm2IIqWao8B/+yB6rAMmiwGnm2IBKR74MxqINIdbt27dsH379j8jS5EH6ZKiTSpTcnBU3TNlKAICOHXf5o2b8cxTz+D+Avfj8cKP4+GHHhagpUCB+1G7zju4dj1ZtAkDHRIIGjoVmm2Sm2UzQzeboFuswjLLnWmG2NMy4UpMESBmffMu6FGyAoaWCcDUZ8Ox2v81rA98CesCw7AmIAAbw8OwOiwUC0NCMbSyDzqHhmDUJy2wacoMbJ+zCIn7j8CdYRKxkAwX9ZgsAjzR8kl32pGWfB2TJk7AgAEDMHzECPx06qRw1UdndU7eA0M4bVO0i2bx3gCE5wkWyVkfOGAA+n71FcaOGYOh33yDU6dOZevGMIp3PmBRvSpvp3kGsHCQKm7ChQsX0L59e4SGhqJo0aICeBCcEKwQhJCr0rFjR6F0y2BW1ObnRgKgBjsjcirAQhHSP0kklA9Y8vagvNdKz4lBLBbEFCJJv7C89YAUnpGTK6ALV7JubF68CF9/9C4GhgdiXkBlHKnzBiw//ADnhYtwJafAYEA5tzM7ErAIsqd00QylbOrRV6EegpDpkMtBJVQGJpTiIafmFibLn7UdidJPt8e/S/RH3Q9+xqULbjgchldk5jubsrInTY9ImoDll675/7yWU3QqLS0te+JVuauyWCwW/Pjjj9izZw8O7N+P3Tt34dCBQziw7wDOnD4DzU6AosOlSbpHqyM3vdYaErgYmkfJ2e6A4dRg2OwwbDK6tDslTXBdkn84gRGvdEHbEm+jQ7E66F/qbYwpWxOznovAoucCsNk/Cufr1MOu6jUR41sBU30rYHqAP6aGRmL2a+9h4jsN0O/deujTpBn6tm6Bw5vWwpRwRQZyhIariXHYvHUzlq9YgZSUVAEsCFSEg0ECVmGRJvuB4qywJcnF43bkyFEMHTIUFhOjdAOa04n01HQcP3ocdO6Xv/2zaiBPABY1QOlGf8uWLXj11VcF2KCVD7kqTJXFD0U/9FZ4/fp10VJ8NvfOC61atcoGLNRh+SeZNecGLP+sLpv/NX9VDXAi8N6930O9FKkMK7kgQr/EI7YRxzRz5sRnsyP9p5/Qr+7b6BPoh4mBPthf+zVYN26EdvkKXEnXoVsonvBEShbRgOWERFNWTq7CwZyw8pCWIQIsUWzgUcCVHBZp2kodTrvDwAcfD8MDRfug8NOzcXCfCzaTIeLoUBdGfhP/39lGUKYWTYwltHPnzjvL0OtpReMIVHis3jVz5kzhcXXbtm3ZcW5YH7xP1IuH6yyeFzI0okhD+JsxNDd0T0hmt5DfEXi6hYk4zcSFt2D6oqHHX26sX+qKGAxnrQnmlzvdgCtRx4WF1zHijaloXLQRmhSuibZFItGnRFWMf+o1pLabhvSuU5HecwxSuwzED1GvYa5fOKb6R2KYfyR6hVdDpypRaBPqh751XkaXlyIR060jds2dgUMrl8pQDFY7dLMTruRM6FYPgKIzPY0KuzmqtwQydodDmD2zyCuWfYeRw0fBZpGcL/YhNnivXr1x4ODh7P7Me3P6wc17uffZ3Meifn7lX+5ncv/+lcf/Ry/nrqXb/7YZWbiqn0GBu1lb3pwONej4fjVoVaqIw6FDh/D5558LRVnl8M3bj8qjjz4KEhCKhxTwUHmogc38vd+VG7D8kzgsY8eOFc3J72U9qP1utnH+u+6dGlBj4WYl4jXaYRCMqF3qoihNEV6XZs1Oj48V3i/GsMYJjvqwUjn26vkzWBY9EgvbfIYJUVUwuVJFHPzoI1i3boYWdwXu1BToFpuIpyOe85hLM3+SKe+NK2iepRKvKD8nY+GSRMa4IYCiC3nOsd8u2YmK/h1Q4LFh6NLLjpTrOjS7BCxCb9c74zs4ZjkUTercubMQRdxBdr94lPkrzsqaNWsE5+TixYuCU0y9jNmzZ2c7uPzFw94nbkXzxT0eEOix6qIys5zKVQZ82CPsY7My9pLVgDvTgBav4/T3Gdg67gxaBQ7C2yV64K3Hu6PqI83RPWQspr4/H9PfGYOjvZbCtHAPTPO/h2nOfOzs8gVGVwvFvFcjMCuyMib7PouxFZ/GsMrPYnxUMDa2aIpdHb/Anm5fY0u3AVjWuRc2RI+D7fI5mJPioFnNAlSxPwjQTEd7HiS6dfM2zJg2E+Ysi/wMyXjBqTNnkGEyCT8u7EnSdw+5cx5lbSEsI330+PoROlq6MKV20oycYjShJSX7IPs8X8D7qVxFzo8og+d9AiMKazpd+o7hseAD8kn+yfGkYFPulErV6k6VkuvIY4I0ikpzNyuViXOf42++S+4yJ/lmXvn7thvnIlnv2fppAiQTKMtdKtd79NWEsn2O8NlmZOCq/vNfD1gE0fGqL/7mR6iNv3PfQwVZrmKURQ9BCsU45Kao43LlymHKlClCn4XPqwHvDVRUvvmARdV2fppfA7IGJMGTJE0Sdrew8uHIVOROEj9ACmL4i+PMle3ky2mzwpmWjB1zZ6FntUiMDQnEnAA/bKz1Cizr1kvT5bTrQtzgzjJDdzBGUM54V0SXJSIQUuNVEWwSdzGus0VTtEqiIjBw5Gg8yleqh38Vbo5Hn5uHtRs0OGyG2Cm94URCroKcIO681Vk+blwgURzDjWVTZRYn/sA/b3p1+PBhDBky5AZRNrOkN+ulS5eCSrjcRJ1QDHIzpV9VqZ5UmId7yiXajwBVcFZk3d5Yft4h8KGcplmPdgOG3ZDgJcOA5bKOhdF2RJabjKcLf41nC/VHxUJ9EPBIJ7xWshPG14+BefUVaHFOuBLS4Dz9E2x7NiF98Jc41bIxNrxWEzEhlTG6fBnMDvHDFL/KmB4YhimBkZgcGokxUVXQu2oo2kYEYlLb1jiz+ntc/XGXUBTWzWbh/ZdcOnKR4i/FwsnQDDQmcxnYtHkLEpKS4DB00D6IPVZascnUodlhd9qkXg9BuPAb5BTAwEEg7LVT/4cgSfRFpcNFME3Q5Jm+iKXZF10UZeqGADvUmuF40cjP8oAkUZJs+/pcDeQBNA76FaIlmNPuGX8svey9CnwTzBOAqfO5U16RO3NSMbF419+58f2sMOlPiR6m6ZNH6K5Rt0qXumziutBXk/cJhXsBqun3yQmLkYZY/ae/HrDkrqobB4i8qogBldn69euHd999Fw8//HC26IY6KgQq1FshwVi2bBkuX74sHlYITr3H+zffpXYFkvI5LKqm8tP/pRrgOFBmyiRqitgJjkm2mIHjRRJJ6g1whUeOhgAxPC8UP13CxwZXRT8fO4iYgX3RJywEk4MDsalmNSS0awPH0QNwJdEaKBW6lQqXnlDJIg9JQL0BimqHnLEriZxU9KUOmwMuYdLsFpMDzZW/7B2Dkk93RInnRuPbFU5kmgyh08K1kMMpJxuu2CTXQL5Tvef3pIpeKbBARVEFWH5PPre7V3FvNm/ejJEjR2YDFgVMeD4mJgZms3SsxrwUPbtdvt7XVF7ez96sDXhd9Y3sA3K4KElyAJrJgG4x8MMyJ8YOvYrowVmo9MwMPPvETDxfag7KPT4GgcV6Y1CzhZjZcxLm9uyHmI4dYdu5E66E67Bu2IKUmdOQOnkssqaMQdLgvojv3gnfVwnBar/nsSm4Mpb5V8C3QZUwL7Aixld8Dt9UKodlzRtjZd/emNXvK8wcORwxEyei+YcfY9b4ydCybGJOnDRlOo7/fAY2ww2Ly053g9B0+s5hP1AcJq9pXZjLc0Wvpnl5xGCdYorNFrsJ5ooAwRp1gwhS6JXXkGCFsJhvIFghN1KAFQFYCF041m7e/1TfUu1/szZV10S7cHB6bWK8eLWX15dlAxYJlm58TuWl3u+VZfYhr93uevaNNzlQ41gAQo0AkWDMDrdug25INwbClYFbWgmq2F0SpJDzpZT82QoshxtWIwPx+qm7C1i8K4EfpYDKtWvXhPY9vdLSPJmcFFr8EKQwJWApX768GLSsH5UPUw5E5qMam7/VsapL/lbn8gGLqpX89J9eA97jhN8qLHE8OiJqUhJjh5wCD6tbrBoZXZmAxXCLVSPvpdM0FwMPGi4kXjyP2SO+Qbe6b6FnRAjGB/hjQWAATHPmwnn+HFzX40T0YXq5pa0rzVdFvh6OBMvlPVlyzPKcKKPgvpILK73eCo+2hgZ6t5X6NMDpM+kIi+yEAg93wtsfH8ely27YbIbQaXG6CLDk5CRYzULM8UuC/UfanmVMT08XdaHK+0fyyf0Mfa9wY4TgoUOHZgMWZZnERRp1WdSm3u0NQtS1X0vVM971n/sZlT9TAjWXWwcxp5CKuCGCSVL0ZjMbcJgNnDjswokDLjRvlIzy5VehWLGRKF64A54s/A6efqwani0Ujld8P8RHVVpi3fj1sO2Lhf3geTjPJ0KLTYLzwmVYN2+C5fuVsKxeJWJM7ahZBfteq4GN1ULxbbAPxlYqh34+FdE1OBifBgWjVZWq+Kx6TXR85XWMatEaI1q1wdqJU5B8/LgIA6Fb06FbU2FoFhFUU4R+oI8bpwanww4X9WToFFFzQHPaxaQoxUYSrHCqVAErlcNAcjhk3/LwDDj/eCAxAYtHmJENWKSG1q3gSu5al7+9AYr3HVb6HPJw+VSqrquxfDPAkrM0UXffrVSVihwTJww44DasANjXZfQpCVTUokKCkxy4rJ6XqdRhuQsiIe/q4QBQO89z8K9fvx5vv/224KbQCy0BC8U/PFYxf9q1a5c9iNVguhkw8X4Xj9W7mOYDlty1k//7n14Dqt+rMSN+e1aP3uRB1QPHiPBmq+uwujVk2K2CtU7PpW66iLeZkXT2FEa3+wy9q1fF5LAwzPHzxXdhoTAt/BZabCzcKdegZ3pMlxmoMNeqkO/yBij8TQKsiDAJNldYOYIJyd6W7HkDV+JNqPteDxQt1QIFS47F+g0a7BYpChIRhz1P0nGZ1NNQX6q+8venqv74JOuIZfU+9/tz/OUTtPzhtmvXLmE8oCwc6WtqxIgRuHr1qnivomOsp99SBgVQ1BtVPfPZ3O2g7lGpyt9mJ4eLEzgwb+63GD9uJjIzpK6QnUDRaghPw1mZBnbu1tC91yU8WW44HijcFYVL9sO/i/XFIyX6o0jxgXjk4XZ4+vHG8Cv1PqK7zcfyUatgP5oMV6ID9M7rPHdO9CMHRUl7dyJrxiSk9OsjdKIWhURgYVhVTAsIw8zwapgUHI451WtgvJ8PYiLDMKd6JMZHBqGXf3ms6toWF5fPwU+LY3Bu+VKk79kH19VEEdbAbbEL78gOC62mJItCcA+FCEhy8SjmYc+h+EyJLSjscRt0cii1XIQ/IIOeiJUeiucZ4TWI/Vb+5pR7q03Vsbp+s/6V+x51rwK66jdTyUWVY0byi1T/vxEA3AoY/LnnCaEI45zQXOzfBCsS2jFSes74pG6LHPNKFKS4ozKyOjksWYi/m0q3rHRV8aqiqVAWHBycDVCUaTItgHx8fECrF7JfOVjVxgHnPQiZJ3+rgazuY6reyVRdz+eweNdQ/vE/uQa8+7/6TpItRUjFiozcDvoC8ShqCxJD5UNIPQCytylWObJjG8Z1+QK93ngVQ196EQPKP4sD732AzLFTYNu5D87zlzxWH1nCIZwuCBLflANQWB7lyVWlavWqyidTWUrJZZFu3m0ODWmZdrz9bnsUL90A/yneBZ93SkFCvFS01RwGrA654hUeTrNBz+2mixvf+mu/coME9Q2/9tyvXZcO4qSiPO89c+aM0M3jMZVvaeLMelJ0jOnv3QiAGBXZm3b+Wh6q/9AajK9ctGghFi1cgIULF8LhcGLL1h2YO28ZTGYqqAJmp4EMqwGT08CmXRqWrHRi2fdOrNum4eW6+1EuYBkKlxmDR4v3wOPF2qJ4sdYoW7Ilqvl3R4vaQ9Hure5o83JrdH6nC1q/1ArLv54H+5EM2I9lwbLxLDLHfQfT/K0wLdoM88ptMH+7ElkTp2BNrZexrlYNrK4RiTlBFTE1pBLGV/HF4NCKGFolAMNCAzAyKhLj6tTGqPc/RP93P0Tf9+thWOMWGNSgKdaMiob1pxNCT8adfF3qyWiMWs3YWPT3I7kCuuEQ4QYYyJE9jWb21JEhOKYOCkWoMsaW0vuS3Jrf0lqc17zBJNtm4sSJqFevHpYsWZI9f6l5TKU3a0MphMrht+TwjHJGvjcV+LOPvcEHdVZYf8KknnJF8qiEwrPkqoo+Lbi+LC//JNiSIT/UwgWwGWZc1c/eHZEQC8XGUJWsBs3x48eFTxWlUEuOCgEM5bUcpOo+Ega58spxnsTfZJmqPFXD8Tff5T2oeU7dlw9YVE3lp//0GlATjhoLTMVY8OipiN/CYofEV5ILRYA1lwMWqwmGZsPRnVvQ68O66O1XCRP9KmGOf2VseLkmTDHz4Pj5IrT463CnZkh9FQetNmgG7IDLY1pLdrYay6xzuinYuHEjZsyYAdIAq5WsYil2kuNUyq1J+Mi654TpcAKX48wIDm+NAg+1xmtv/4iL591idU9lW7pyITl2ibEupwgVDO9O2lnVoaIfFNuQNv1ZG+vFu32881Xv5HXep34zFW3nZbzg/Zw6VvnSwRp1bxi+hGBDOdNU990q5XsIlKiCMXP6DKxcvhQup01w2/gMrTPDI6rg0KGfhH4HnfUxUoLdBVg8ANJsN5BlM5CcYSA2UcfI8cn4uNEGNG2+D888NxmPFItGoRKTUKhYNIoVGYCihXuj8ON9UbL4IDxZYjAiy49HXd9o1H7qC7Ty64ATE3cjZclenJu8CNe//Q4pi5eKgI/OM6dhP3IApphpOPh5C5xo1wJHWtTHyqhArA6ugDWB5bEyoCKW+vtgnm9l4bl3rr8vZvtWwpwgX6x4tSbmv/4SlrdshqMxs3BiwwZs/eEH/Lh3Dyw2i0eFl21FjovHP5Chw2q1CPElp1mHRp0ZaWlkp0Kv4C+IKdojSlI8D441ycvwtgLSuBj3KNUOHTYMq1Z9jytXYjFv/gKs+G6lsI7jc0pUmLvd2N5y5+QvJ3vlCuCPpKq0dwJonE4qikugxLhYLJnZahH0hjSHu4jM7eFKMSiD2IVloi5M2QmWbYbl7gEW74rlwFPEKysrSxCuMWPGoGrVqkJn5eWXX8bixYuRmZkpHlODTg1YDiL1vHe+NzvOacCbc1jeeuutf5TjuHyz5pv1gn/COUXebpfmfKf3XYJ74nHMxvEgxo9nxcwneE45gyOxdDiscDssyIi7jB9mTsOK4UPQ+61X0b9KKKaF+GN37deROWYUHMePQ4uNh+taCtyZVk88GYqApOSehElQZUE3SUjluCU4mTBhAkaPHi12AoAVK1Zk+0+SAEUSW7KTuVktXJwYGD1uA0qX64ACxUZi6gwHLPS5YjPg0iiu4OqWisK0PDCEJZOY2EUhcurmjx4pOkRXCyrMxx/N62bPqfxFmXNxUEjv1HU++1von7qHAGXw4ME4e/as4G7Rv0t8fPzNivCLcywLt6OHjqBv7z7ISE0W3Dah+yH0KQx07vwFzpw5K0SJEjDmKKPS+p0gxuGCCJVg1QCzwxCeiNl2G9dqmDnZgWlTHJg53YFF850YNtyOZyovRKGy01Gq3EIUKjUNjxUdgxKPfY0n/tMGTz30PsoVfAmVHq6C8g/4I6JkNQxo/g3GtR+LGe1GY9Yng7CgYW9836g3vq/bAcOeCkX0k5UwsUxlTCjjj4llQjDtmaqYX+FlLKv8MjaFvI7VPuFY6x+KJX5+mFixIr728UObij5oEhSOdrXfweIR0VgyMhrzvh6EhQMGY1H/QVg7ehyWDR2Og0uXwXLhHHRzJtyZ6dDtVtB6Lj0tFeYsE0yZWbCK3QRrlgWWLBssJjssJgfMJgesFhcsJjcyM7goB5JTrLgSl45NWw7AbDWEMrnVbmDajKWYv3AtLDZO+AbMFgOmLEOMAXOmAe6mTPnbwvOea6YsXXDAsswGsneLgUyLgXTPnmHWRbDQLAtTuWeK1BDn+a5b7SYz8//lnmVyI8ukw2ozkJmli3enmwzEJdoxaOhc9OgzA526zUDnHnPQqXuM2Dt/ORfcu/aaj65fxqBzt8k4eChRRFw3G2ZcuRtmzb8YBblOcCByJ1uULLASJUoI4BIUFCScxfF2Dj41kHmvGkjqmhqc/K3u834Nz6ln/pkclseFWG3s2DECt0vrCsl640RxtzbviZLHgj2ai/jerbL8nvfk7jOqr/yePP6Ke2VfJ/eDKxOl0pcr9QQIJDoQoEBnkECX2OUEwr4vwQPFPlRcpcydfk6ol8KgdMzC5aJipfSHsOuHVejb6CP0DvHHSP/KGP3Cs5gXHoTMoYNgP7gXWvxlT0ygNOlfxU4zU5pNKIVXipnor0J0AqGtKRR2YQgrwOYtmiMxKTG7yhITEmAXru8VsCE3VrrjF9Y5OjDkm2V4+oXOuL/YVwitsQs//+wWyp9Uk6H0R7Cd4RQsey7o+G6CJtYB++KfsSnOLekN2+Ze2G5VDnKgubVt2zbbolKVl8+ob1HnbpaqvK8lJKL/V32RkcowJ+xP8vupd8NFH82xubFGRLvzLo8OCOufxw5Nmf/SigugCM9JpV2TIZz9UQ+Ju81i4PhxF06ecuPoERe+7n8NNWtuxjt1jqDOG7vx5iub8Pwz41DksX4o/Hg/FHq8Hx59vD8eLdwXZYsPRNlCvVH+kR4IKPQlgh7tiiqFOuPNx3vijce64PXHe+LNIr1Rt2h/fFi0O1oX74C+T7bG6DLvYfazr2Bx+UisqBiKZb6R+DawGuaGvYS51V7H9MhXMCm4OmYEV0VMYCTm+IciJiAYM4KDMTEyDNEvV0ffWi9icNOP0bXBB2jy1ht4r2ZN1ImqjneiauDd6i/h1eAqeD3yJbwSUQvVQmohMvhVVAuvjciQt/DKi/VRLfJDRIZ/iIiI+giPbITwqE8QHNkC/qHNUL1mO7z0SgeUKvMq/IIbIqRKU1Sp9gnCQhqgSmgjVAtrgqqhjfFytU9RNawpIgIb4KWologIaoiI0MaoUqUZwiKaIiikEaJebI2QKi0RUq0VQmq2hk+VJgip1hzh1ZoholpThEU1Qmi1xgip1gRBVRoiOLIhQiMaIjKqCSKjmiIssglCI5qgSrUWCI1ohOCw+oiIaoywiPqoUrUxQiPqIzSyAYLC6qFKtWaoVrMVol5sieAqzeAT1hgVglrh4ZLNUbBEVxQsNRz3lxqPAqUm4v+enIoCT0zC/aUn4b5SE/CvkqNw/2PdMWFiLKiTbjEciLtbIqGbDQbvcyQAHEDcVq5cid69e4ughvRs+8knnwiOC1c1nEiU3JiDSe18jgNU5cHfvFcBGd6nJqH/LcBCwnJngIX1xvpTRFods46961/UOetZyCEl8SIBuzfIOkt36019G+/wJuSqz9z6yb/2CuuX4IIWMpou3dlLM11GTqYRJfW5yNWQ0zInEukETsIbp/BuKicRjW7a6cPE0IV/COYrpnSKaq122BISsX72LEzv0QV9atdC/yqBmBj4Ana+/Rqud+0E07y5INvdlcR4QEkwbCZpfcGJkfadNPXkOPa8U/Q6NVvR1FOwhg307NkT23Zsk7Jq3ktrJLsdP+7ehYx0htJgf3MLM2YHg/YxEvOoBXjm2UYoULgH/KM2YNceFzIzDTjoI0T482Kvo54BmfCcqCVAY9+TNXNn7cR+oPqCN/25s1z/2qcVLSRgoR6M2lh+9S3q3O1S9kFuly5exPhxYxEfFyt+U2w/bNgwYYadlJSUC8DJmhegU/UzT1uwqzBwM0EmFV7ZfdXutBvi2OmQXDP+JoCxZhpIv64jM1WHJcPA8iVO9O1nxxddszBgiB1tO2ViyFA7Bgy0o/9XdowaaEe/zlYM7mrH0C52jOlmR4d3zyLwyXl49vHJ8C85F1VLx6BWsRF4s3B7NH38I7R+PAI9i1dG3xJPI7p0ZUwvF4bhpX0wvGwgFVYgdQAAIABJREFUhpUNx/Cy4RhVJhBjy/pj+rP+WFQ5HKsiamBOYBjGBgZgcGgg+kSFoHv1CLQLD0H7iAh0joxCj6ovon1ACLpF1kTH8JfxiV8NNPV7Ge2r1UNDv9poEvQ+3nn+DVQpWhU1ytaGT+GXUb7wm3iu6Ht4qmg9PPdEc5Qu0gBPFm2IUkUa4JkyLVCsRAMULV4PpUo2RMni9VGqRAMUL1YfxYo3QOknmqFU8UYoWbQBSpVoguIlGqPEE5+gcPHGeO6FL1C4RDM8VqoFHi/TGg+WbIqi5dqiUNkWKPRkMxR+ojEee7IxHindAP99oj4KlWqAwqUaomjJRihaohGKlWqKx0s0QpEnGqNQiY9QvMzHKFzibRQu8SaKP/kOipSqi8Il3sVjpeqhWJlmeLREYxQq1QT/LfYRijzZAP8p8S4eKPoxHijREQWfGIYCJabivjIrUKD0chQovQwFSi9FgTI8Xop/PbkQ/y09CfPmO4XYN8uw48rdVLq91aDgwFLAQt2jBtuGDRuE8u0jjzyCihUrYvny5eIW3p970OWePFVeTL0Jzj8TsBTxcFi8Pd3+eRwWNaF71yNl26qdVF17twFJltrV9Xsx5TcpoqzKd7Nz6trdSFV5KN8W/lA4gXvU0QhAs/+EvwIdTrsDdMHO58hFIWNDgRUqAmrCioGu7Al6dDh0F6yaXYhPkuMuY/Pc2ZjTsR0GhwVgrF8FzAqogG9DKmJ77RqwbloFLe4iXNcIVJLhzqAFkEU45jAoi6HYQDhpk1Gd6SyL3icEYOHY41h1a9IkGoaIBfb9mu89MnYuMuha3YUrl87DbEqHTp8NjHkDmjI7cfWqGS/W+AyFirVC2YorsGmLBrNNKtgKJoIALKwd6a5LABa6mBfsnT8fMFN5VXEvFHi5G33i975Djc1BgwaBbiO4qX5FHSKK5tTvX8ub93E/ffq08IPVqFEjvPbaayI6snqPyoO/Zb5y9EuLL8/i0osmEAex+3AXoJPt6NkJZriqpn87ghaaUGtWA07uFIWkS5FHVoaBtp+vRctW36Fvv33Yv8clwI3TZMCeacBJL73c0w1kxuvYt0nD7h807Nug4chmDYfXaDizTsPSfocw/dP5uDz3JMzfnUPGoqOI+fArLGk6Cl0rNkGn8p+ha8WO6FzhU3R4tj66lnsP/X3ex+iQDzCwYnVMjnoTC954F4vrvIO5r7yEpbVqYk5oAGJ8K2Khb2V8HxKCVcFhWBoQju/CXsLSkFpYHlEHi0LexpzAupgb1hBTgpphVEBrdC/XEr0C+6KD/xC8V6YXXi7RE7WfH4E3nh+JqCcG4A2fiahTZS6qBU9FVPhMRETORGSNeYh8eSEqhkxBYOQshEXGoGLl8QgOn43gyHl4qMQAFCjcB8WeGY1KgbMRWW0pKgbMRkTN71A+ZC58qy6Bb7XFKBc6B8+FzkKlqvPgEzUHlYOnwzdwOoJC5iEweC6CI+YjOHIuwqvHwDcsGs0+W4s1mzT8eMiFQSMPo0JgL/iEjYBf5HQ8HzQLAVVXoHL4QoRUm40xk1Ow9UcNP2zWsGm7hh/3usRYXrtOw+ZtGjZsldc279CwbYeGLVs0rF+vCT01FzkscCJeP3d3lG5VZ75VyglCgRbFKWHHJzuYCkZ9+vQRYqLSpUujV69e2TJYNbGoZzlQ1IDhOXWe93Hn9r8DWCR7/U45LKxDVXeKcKl2VPWvfudO8wJgkcRVEnP1nbm/4+/6nQNYpM68MFn0jBVyM7LbQ3Ay5Dc4NKdQYiNoUeIfl+DGuOG0mmE4GbXXhvSrl3Bk3Rp8WfdtdA8LwvAgXyyODMTCys9gZdALyJo0Gs6fj8B19RzcKYnQs9Jh2K0wSD08ohbBTVN6MV66K7I40lGd6H8EXPThAmDSpEmo16A+Llw67/HH4MT5s6dgyqAiK7k+9IRpExYXaekONGrSD4+XaIz7C3fFR42u4jJ9rjgN2DnZCSYR+7mK5kzgQr8PnAUp3mIPvPONNEUonwKCFjHoYF7Y2J/pOoLWmEK0BoABZOmcjud/60aarGgpFY5pau0N1tQYyp1f7vP87U1P1P3Z/VidEOBKNp8AMS6A3Y6cGKaKE7N+w0V06z4NP59xIemajvfe64qJEzfAZjWQkW5IsEPRk92AywHhN4agx07dJ7MBZ5Z0gte+6STY43ToJgPuDAOMo+RONeBKNuA8r8v9nDvn+IIO5wUdjpNOOM/b4TyTBsfxS7AfOg7bnn0wL/kW8Z074GzTBrjaohlSW7XE4grPYVmlSlhc4QWs8gnEtrAa2BhYHev9X8T6gFex2q8Ovq30HpYGtsFsvy8w2bc3Rvl8jWH+IzAgIBr9AsZhaOQsrOtwEscmOLBngg0bxpmwaaYD25c7kXJJR0q8jmtXdJiSdKTG6kiO07FyqRMtPzmEli2OonXrY9ixWUPGNR3XYnVcS9SReF3HlUQdFxN0xCbruJqmIz5FxxX+jtWRyHwSdCTF67h8wS3qOfGajgtX3DDZDVichrAOMzkMJKXpuJaqI/6a3M9fdiM+UUd8gtRhYRR16uBYrQbSUnThldqc5dHHoWk89W5shmg/ctYcVgMuD9fNBieu6ufvDcDi1U9vOFQdniuC/fv3Cx0Xmjsz0GH9+vWFNRGJido4QG826Xif/2cCFkauvg9jxnhzWDyrmj+RaFNmPXXqVDRo0EAAx3PnzomqV+2k2kGlNyNE6tq9kKq+cunSJREfhoT55MmT6N+/v4jj8neXkfVHUJDtIpzKs0JDNmciJgeDkXm583sIUjQBHghYOJEzqKAdaUnxWDF7CiZ93QMje3yKIU3qYkh4ECb5VcZ3oYHY/VI1pPfsjKzxI2FZvQzapTNwJ0uuim7KgmG3C4+1fA9NWp00+/T8ZRsjiojKUo9FlpALCI9JI31YiMjrbsTGXcXGTZvwSYsmWLpkAQ7s3QuLiV5c6QeGpqIupGbY0bL1QBR/siHuL/Y13m1wDpevuGGlnoONIl6PjIFWFR4dH2kJwdLQisPj6ewOhZLsE2wHRWcYS4iARfWdv7uP3O79qozs08qy5NSpU8Jj7q3G7O3y4zX1nFoY8jfrKPem3p37/K/9Zh9R72A/0zSa3Ht0YoTYUR4fOnwWGzfthY1hA8jhM4CUVDvOnksU+jLCC61Uq5LiJ+o0eTg2BD2azRBBHpcs2IllC3dAM8vfKgwB4ygRwOhmA+6snJ2/xc5rnt2dboc71QTX9WS4U5KF6NRx6rgITaHFx8Jx4jhM8+cja/o0mObMgWnBIiwICcLcyhUx89mnEPN0WSx+rjx2Bb2EQxF1sTPwHewOro9tgQ2xI7QVlrzwAZb7NMSyyg2w4IWPMM+nIeYHt8To8h9ihH9TDIz8DAvbz8DMbvMwquMsjOw0D8M6LcDo7ivQ4u1vMP2bXZgwYCu+6bkG9WsPxal9LrgyDVgzJLC7nqLjeqqO1DQdWVmGUNLlGKNCu516RgR5VunriOepBMwFA5WpuVOx2mKXlnwMSCoVbeU45THPMYI6uWbUXeJOAMl2EG3BPDw7/f0QcAqQ6QVSLYYFcfeCSEh1TnZw1cm9Ubj3eQ4SDjzKTv/973+DwQ9pqkcZKjdFVJiqjs/8vfP45wKW+zF27HhRD/xefrfaf41I3O66ah9adE2fPh2rVq3C+fPnRVDKLl26ICEhIfudt8vnXrymvo1+L65cuZLdT+i8i/2K57mp++72N6j2c3tcVQvxCj25cidhF4oAQibi0Tx1wXAxcrIFhsMOZ+JVnNq6CQuGDsbg5o3Q7dXqaBfug89Cn8PX1X0xM8wf34eHIHPYMFi3b4fjp2PQLp2DK+EK3OnXheWD4bDCIKXha9wSKAhdGHJ6ROBEmmLmxFwhR4Xlln1Qogol4uF5Tj5OTUdmlgmHD+1HXOwlOdswHotGfR0gJd2O5i37o1ipD1Dg4Zb4uNklXLjsFqsvOycoso+opiJQC6ERuSo51kmELMIXhBALsQw5AO+PtCG5K2pSpnkwF0/c1KT9R/K8W8+wHXJv/J7f2qd5H7kzqk1VXjd73pvrcrP3eueh6DPzU3Q7d968X/Qn6Mg0ZQhFccFZBLBs+QqMGTMOVitdvUuvtEy/HjAIh48eFzGn6D7fSVEpsS1FUHR+5+HMkVvDPn354jX06NEfaWl0Gy/1a7jGu3DuqphMBaPOw7AT4Qk8ejdC6kjfhHZdKJxzjBgOGy4e2o++n32KDh+8i9PrVkPPTBMhKihKdacmwZUQCy3+Euz7dsO2dxdmhQej6aMP4bPCDyNrwixYtx6DdeNxWNYehXnVMWRN34iERj1xonYrXPiwA8681xY/hL2BpX4vYqlfDczxfRGjK1XBwIAX0SmgGtqFvYrWIa+hTcTbaB1WBx2qfYhPw9/Cp+F10LFmfbSOfB+967TBwI87o8/HHdC/0Rfo37A9vqr/GYa16oKlw6bg6JrduLDrNH7acAxX9lzBuR2XcGrLecF1EgAuU8aWkqBOl7GmuIjgThBHsMfd4gF3VhmPimDQ7ZCcMtY9wQpBpFCD0yF8+ZD/wC4r1hsc557h+7eZNatOebNUAQ1e8wYt/J27szO+xvDhw4XfFnJcunfvjrlz5wp2pbpfvYODRw2gfzJgGTdugvhkfqsc7BK0qHr4vSnz4GYymzFsxHBs27FdDH62DTeu3FS0a3WvuJAH/qlvoD8QBpdTvjVIzMnRo/mqOvd3fRvfK8opdEQ42cvVpKhe6rK4ndDddjjtWXDZM3F8zzasmTkZu6dNwqGJ47Hyiw74KjQAw8OCMLlKGKaFB2JahD92f94YWVNGIGvSGNgPH4J28SK0y1fgSkgQK0TdaoJuyYLhoGt9Bww6tXIzeqwbTo9iLTk/gqORHfdD9hV2EJZb7AIqSI4HKY+TvpPs1FFRHURMJQJ4kEhxQklKtqN+414oXvojFHikI5q0PI9LcTpMZBUTrHDCIFFTzu5kjxScJCEyk/q2HtVvCZjuBLCotlciIXLf9u7dK9tFfcY9nKp+fjNwdbNzt/sU0hUCN2/Aw2NFW1VdMQ++l78liPllrrxGgEofPSQz3oxgXmOeko6RlklASvCiwM2WTVsxcfxkmLOsonndmlTY3b5tN5KvZwpxIcExdbZkFGa3FBbyGwi8BYBh3wS279oNk9UGq8OJw8eOo2uPnlj5/Vrh2Zd9kpMovfzSOR5BEJ8V30rk7JlZYy9fwHffLcOmjevhsFLHS8ehXTux84c1SDhzEro1E7qZvoqyoJvS4U6jPlga+rz6CoL/dT+iCv4f7AePQYtLhvNCArQrKdCupEK7kg7tSga0y+nQLqXAeTEJ1u37kTV1DjKGjkPm2OnIHDcVKWMn4vKYsYidMhVnosfj55Fj8W39xljVrBkmvVQV46qEYFJEOObVeAXjfIMx3icEU4IiMCkgCNP8/DHNzw8T/HwwqEI5dHnuGXSrXAn9Q6tgSJWX0LVSELr7hGFz169wfNREHB0zCQdGjcWB0WNwcup07B45Enuio3Fy5kzsHz8Bu8dNxMFps7Bv2kxsGjsBm6dMR/Lh49DNTjhNdpgyzaIO3W4dLqcbNosTDruM0WQXccA8AFNFhTcAq2G6u55uf9llc86wY6qBxQGhVjOq43sPCNWZVcelvxb6H3nyySeF4imBC+WzHCgqT9X5mZ83YMmbflg4xDjYqZgIzJw1C0WKUCRUQGjxc2IQjo04adzh2lLV+8GDBzFq1CjBWWEdsn3EgCUA/oXSqnqrd5rT1jlH3te9j3Pu+O1HfF6tpFVet39a9TH2HQbT5MZvER5fhTUuBR45ZrG/Ldfbv/P2V9UbclISajeXIXQPTqrp1mBodkHosi6eg3bxHHbFzMCAxh9jTOtm6PlaDXQKrIwhIYGI5h4aiJH+lTAtPAgb338HplnTYVm7Co5TR6DFn/eYJyfAnZ4KPYsE1QLdQo6KJygZPXwKb5505SRrmLXMX0pUpcCA6AceayE1RgkgVC9kf5U6NfQeqgkFTgY7jY+LE+PU4TSQnOpC+07j8OQzzVDg383xUaOjuHDRLZRsBcuZnmwJVlxSREOF5Gwuj5sO5jjJyTfyvHKepcp4+/q/9VXmq/pLjx49sHXrVnEzv1ONg1s//fdfIVea38CNNFHRxd9TMu8xf7tvVu/xvkd5yuU1nqdomd5bGzZshI8/rof9+w9kF4UgRj3LlM9QcVdYwHnKTk6fxWTFiaMncfL4aYEZ4mMTsHjRMhw6cEz8JvHLASxSad1J8ajwUKvGtlQUZ2/esHUTPmzwMQYPG4Lde/eAumAcieyztKzjLvsvXfFTbOmEYVBkZRUuB7bv2oYOXToh3WqWmlieftitW1esJaeFY4mRifmc4oI67Wj93nsodf99KHbffcg8cRK62Qo9ywQ9Mwvu9Ay4M0xwZ5rlnpEFd0oq3KmpcCVdhxaXCO1yPLS4q3BdpU+kq4KD47oaB1diAn76ZiAyZk+G/ch22H5cD8uaZciaPgWmeQtgXrkap1u1wqbXamH3m7Xw41u1sPWtl7Gh7mtY8f4bmPpyFEYG+WJcaBAmBPljYqA/xgT6YlSAL4YF+mFYiL/YBwf54mv/ShgUWBmD/V7A6BB/DPWriG98K2BApecwMiwAg0L8EP1GLfR79VX0qVMH/et/jN4fvYevPnofXzeoh17vfYBpXXsi4/BRmH86BfvZs0g/cRy2C+fhzkgX9M9uZOLqveCHJbun/sEDNUBWr14tTCarV6+OMmXKiDDtXD0rt/7qPm/A8uabb2ZzCNT1P1iMv+QxDlixc7LgsRABcOXihs3BgWIgZu4cFCteHPcRsIwdTn+hQjGSwey4uvBwz39RPpGvZ4IRc/1NFqO8h1tmegbGjRmLH3ftFrTfYZPeL8+fPY+L5y9miyZE+VgqMVlQf4J6CzLImHcBSHzEPdS1oOtmYeFBnQhOMmqKE9BLfDefVeUlsRIWMSw7OQ+cwahUajiFroaIXSFEAbLsfE5OXor4cYkkxRt8PjMjA1s2b8L1pGvizSRlGdSZOnIYSelpHjVQCVwEgCHRdevCf4kueJnUK6GNZg5gYlsR+IiVGIkeFZdFXbI9CSg9YhyPWYRqVyqmkmsiYpfAhUsXz2LzhjXYvXkd1iyai2UzJmDdzImY1rktBr5WE5NqVMP00GDMDPBFjF8lLA4JwkJfH+x79VVcbNYc57t2xKFuHZE+PwbOc2fgupYIV1Ii3MmJcGckQ6ejK7NJiI8kIFLfQnET+eDkm1ORVX1/DmiRtevdqvKY44jfyMaRK2K2PychrmzZxgaWfbcE3Xt2Rcf2HbF29To47A5s2bofTT8ZhLLlWuNfRfrhjbr7cPaiW8jGhYKtZ2VLfzFcmXE7cOggkpKvi3fZbFYcO3ZMcMdySsVS3qqkOXf92hH7kAIsbdq0yY7WLPqkN2vg1zL6A9dv9w5e48bFm6Jf3mIZXlPnvV9NwKKe9T7/Vx6r+iNXltzLLVu2CG443VWw/BSzsey5N1V+VV7mI84ZALkso0dGCyeBCxYsRMzsuXA6OBZzmp2HirSpVF3OuWYIgEIPrFa77RdLn5z7RK/2Gg0EUlK2tHX7FnzV7yuYrKTL0tKfz1G0vHrtakGDJOHh2KfOmWATounHH+Ph++7Dow88gPgzZ2WgUFpacVEoUjcMirXE7hLBGxnIka4I9CwL9CyzBDhZ5Nxkyp2Lj8xMMdnTss9+cBd2RX8jwEzmqu9g27MHrsRr0C5ektzVSxegXToL7dJpaLFn4Dx/DOkrF2Jbzy9wsGcXnO7RBWe6dsLprp1woksHHO3SAYc6fY7DndriwOef4vDnLXGybSsca9wAu159GasCfLDWrxI2BlTCD77lsT6wIr73r4jFvhWwONAXMb4VEOP3Aub4v4C5gZUxy6ciYgL88W21aphbNQpTw8Mwvko4hkdF4vTMGdBNJjj0ZMTrx+9tpdvcnfd2v1WHpgY7Wfx0PPfggw8iMDBQ6F2oZ1u2bCm4EeRI1KlT5xeARt13r6QcnHLykxOB8m1gd9rEuJwybSqKFSsmAMvkidHCysIlTI7JApVeOyQL08PG9P4w75HoGc1cDcmdEy5XspIArF29Fk0bNcHhA4cFQdAcLowcPgrLliyDi6sRD5hi+TQXQ4nTKoQK0XxewSbm7XEKJiYxToacxAhaJGCRipNSnVOCFwk03EJ3g4PdQ4xYXg8IUNYlMqX4wiGBEjkUwokaiRzLIDedSqpuilQk0MjKykDvPmQDf4fde3bj8w7tsey77+CgkzXWKNtA+ETxWEzRKRrz4GqQRIUThgBmBE8eMOYpqABn/FauqjQb3Fmpgj1MSx3b9XikXz6DlDMnEX9oP1aMjcbMr3pjZs9umP1lNwxqUg9NwwPRPMwP7aoEoW1IZXQMqIDeAeUxKqACloQGYG1IALZUCcPOF6sio/dXyJo5F9bNu2E/ehLOC+fhuhYnZOdSlp4mCBqjKFPebjgJbqVpMquVG8eRXH+yboQZjqhwVe3eqecRzyqYDaI23sWVMV3026E5rcKDLttz5OiR+LjBB4i7ekXcTLz508mrCAlvIPw7FC3TFw2bXcbFXGBF+O7wFFJxCPr264etXlGMZ8+ejXXr1omJj+NG0QRVqjtJVV6xsbFCafVuTvre76I+iZrE+T234nx4n/e+/07q4I88q9pKpZ06dRKO5lR9Ms/r16+jY8eOwoMwwQuvMfXe1PM8p75HhH7wdDt1v4eR5P1oNslQfVddVL9lb6XPI6nvos7f7D5eyyFC8k6CcdKZHj17Ys/evR5xkywY9fx27tqVvfDid7D86ntowMCQNA899JCw4FLvvG1KukcaRBDj9IAYEYma0agdMKijxN1mFZZ96edOY8uCOQLAEMiQeyO4OCaT5KxmZUAnXcq6Dj3rGvSMBLjTrsKdkgDX9QS4rlLvRu48JgdH/r4CLe4ytCuX4Dx3Fo5jx2DdwhhPy2CaPR+mOfNhmjsfWZMnI2vSJJhmzxLppYYfYtuL4fjxlarYWi0UO16MxPYXq2JDVARWV4nAqqgIxAT5Y8jzz+LKpIlwp6fBpiUiVj+a9wELOzd3dgDVCShXJduRPggKFiyIokWLimMG//rss8+yAUvt2rXvaQ4LOy07t1qx6l4+OOyM8QFg9szZKF60uLASGh09VqB7B1eh9MVBTgDrxzMRZa/sPaNB1R1/qmOCG6lUKVfVdgd9aFBr242E+CRs3bITCxcuRpeuPTBx0hRkZMgQCmJiFlMdWagyqikjm+b4xfBesZMoyZgcXG3wWblLqxZpmipNVQlopJBbFppjlbsCVZJ4kABQBEhgIjk75NzQOkZwcETEVQlQCFQoXybA4nucLjtM1gxkmtMxaswIDB85FBcvX4TTKf3MsE85HHYpgiPXhACO3B1WsGKhiD7IdiJYkdwe+hNxu2xw2c2IO3caJ3ZuxoXt63F97yYkHdiIA0unYHCzOmhbzQ9f1ghDv8hgDAkOxMSQYMwJCUFMgC+m+1XAoshAzA6siLlBlTDDpxzmBLyAow3ew9W2LXG2/ofI6PMlLKtXwbZnF7RLF+C8cBHaJbKGU+BOI0DJEH5TDCdNku3SNJkA02P1IzqHpz/kJOwxJLhql2Q65/qtj9hfpXt92X5OzQq3boPDYRKEvlOHTvhh7RrYHHIlO2HqIjxX6UM8UrIFChYfgLIvzMX+/S5hDbR5axJmzFyBnbsOCuVJgme1UucKffz48dlR3NWE1bVrV9Dd/5+1qQlU5cffasJU5/7qVNE3pmrz1iPxpnuqbN6ART3jfS43J0bd81ekrDNVRgIWclm48Ryv0bdN+/btbzC19v4+3qu+i8d85tc2Jz04e9XXre6/3T23u+adn/o2+gljmBmWndv8+fOxdOnS7FhZ3s+o7/lDgIUZCSJIQiiIoaBpUltV0jdxTJEp9WnIteUCl1wbuyObSyMWW3ab5LBqNhgu7hQJW+RuM0O3mCSnJiNN0BPSlOw9nbo4FFFJWuNOSYHrGkVVCdBiqYcTL3TjGMVdi7sCLfYytLhLcP58Ao6j+2A/tBv2AzthP7Ab/8/eecBXVWR/HN2/usvqimDHFXvvgIgolrW7uvYuShfBjgVRwYJlbYBdqgURuxTrWlBQpElXQESR3kJNQhJy/p/v3Pwek8sLBMkL7yUz+bzM3ClnzvzmzNxzp2YP/tJWfv6prfz0U1v+/ge2uHNX+6rFdbby8y+cgpVXuMBmrR5fcRQW6hDBkfDwzNcI883cW3LwwQfbYYcd5rZEM7rC78wzz8wIhQVFBbXDHQrGS9PYQhZtJezZvbfVqL6LVanyN3u00/PurAK2kmUz3x8NIETvHae1FL1k3YuWUQYWjSHgRaMgjIS4XzRsGZ3kRINY87H97eAh9sJzL9iM32Y4XUHTIwh/pFj4aXnhkd4tPCiizZu+6OfyLYqvTLQsv2gyJnGeBvwzlM2IgBvhYMgUJSha55HYxro63/Jzixpc3opolT6NbMEiy5873/LnFzWurMVWsGCuW8HPqa0Fi+a6s0bUQKMh1Sw3p/phly72asf7rXu79taz3T32xv0P2Utt77Rnb7rFXrjtNnvu1lvtmZtvsi43tbanb7jOnm7Twp5q3dyeatXUul7f3B646Fxre9zRdl/9I+2+eodau/oH2T0ND7EODQ62B4892N0q26Xe4da93lH27nH17YM6R9m4/5xrS574ry195inLeqijLX3+GVv6/LO2rEc3yxn+g636+efoN/UXy/vjt2gkJYuFfIutIIth4mwryFriRlLMDVujIEZ4uY4T2AtQ9t1T4h+dNApytP5DQpMIXstBx+t37NEz9Y5CyGm8KK0ofFyKWGj33N3Bhv8wwb77foo1atrRdt7jAtt2tza25U4d7LxLx1rfN1e5001f7zPZ/vt4L+vc5Tn76quJDvkbAAAgAElEQVSvrX///sb2c14GHHrGeS4sflXeeonxQmRBfnkY5Z3KvOjPlI9ecsnykwICDooff+n76RTH90uFWwqm6ocRB+rNN3xIsvZQ98f5YX5/LhqEwz+05Rfv+4mzLrz8PHz3n8VFfLDeT1Nb7DbUxZ6E+/woPsdz/OUvf3GzAZyRU9aG8ujPtU0+2NxHW6HlFyl1rrUndvwVfVg6JSfXClFo+GXz44OH3VB50Q93dm40PcXam2XRFFUB62+ylkbrcBYudGvuWGBcsHCe64/daM4SpqTnWsHi2VawkJEc1uHMsPx5cy1/znzLnzXf8mfOs/y5C9y6ujxbZLNXT8x8hSVewQgCguwLM3EQHLZDV68e3buDwsIaFrazYnxhitPclM9OSXEjK0XnDbiL66IV9rxOevbsYzvutK9V3XJPO7thK7vw1JvtXw0utX6vD7JJY6faiO9G2aRxP9nPEyfb5ImT7afxk2zSuPE2cdxYmzR2rI0bNdLGjhhm40b+YONGDLPxI4fZeOwRw2zCyB9szLChNnH0CJswaoRN+nGU/TRmtP3600SbPG6MjRpK2I82dvgImzh6jI0bMdrGjxxjY4b9aD9+P9rZ44aPtfEjx9q4ET/a+JH8RtuY4cNtzPAfonyL8p7440jjN37UcOc/Zvj3NnbEDzZh9CgbM2KEjR81ysYN/8HGfT/Upo0ZbZNHDrefRg13fE6eOM6mTfnZxo4eaSO/+9Z+nTDGpo36zvp1fsQeveISe/XiS+yDCy+zD86/yD48/wL78PzzrP/FF9nb551rr559hr158fn25mUXW6/zzrXXL7rQ+l1+mXU74zR788ILbMDlV1iXo46yR/fbz5468CB75pBDrOtBB9kzBx1gzx1yoD178P7W9aD9rOvB+1rXg/dJ/J49ZB977pD93CjJq4cfYG8ctr/1O2Q/G3RsPfvq/P/Yl5dcaJ9ddJ69f/Zp9vFl59n8ro/ayi8HuC+Olf/73HJGjLK83xh6nemGX/Nnz3QL6fJmzLD8mYygzLb8WXMtf96CaIh3JVuZ6VRW2uqVdDTR+SxOySsamXNKL0oq8u62O0T6pC/fdHDRhJym5fzQ0rmjEUHuJmKEK1pb5Ea7CvJtxoyF1rTFg7brnpfbP2realvu+oht+c+X7dW+q9xhX5z30KP7cOvRY6AtWcaW1WgElRuGOTRSnTqX+vH1qvNFaL/8HnzwQeOsEcyfffkkK6VosaWf0dtNafSyYyRp0KBB7swgKQbqx8QvfOKnZ2zF8ZWhVJYHfpU/oyncGcf6QtavcA8RB9lpVIz6VFyfzzh/ioO/lDXc+IOFHx5PW5bPyke2FCeNspCXyqF8wUNKTSoVFnhiWj9aO6bcOXgvt2hkJvIjDkoL4/KJe8v08cpHpfsVHWrDR4479ykaZS5cRT+DH+fYFK21cQrNqmjK3E1VMR3Or2jKigMomZbOWW5uRyK7Ern12v2k+Kyw1cvoyzj/Kc9WWZbNqgiLbqkU/dZUSVFFFK3ul4AgOAwlc3vp3nvvbaecckranyPiKywsNqQMlFcN4oXnulnNHfe2M+qca43rNrEWR15jlx90ml1y4LF25eH17Moj6lrT+sdby4YnWasTTrIWxx1vTevXt2b1j7Hmxx5jjevVsWvrHmnX1jnCGtc9whrXOdya1DnCmtY50prUPtKuq1/Prj3qSGt6dB1rUre2NatX11rUr2eNjjjCmtata83rHWPXHlXbGtc+2q454mhrecyJ1rxuQ2tW5wRrWruhNTnqOGtW93hrdvRx1rRuA7u2dj27lri161rjunXsmtpH2bV1aluzY+pZ8/r1rXGdunb1EUfZ1UfUtmuOOtqaHH2sXVv3GGtct761OLq+tTz6GLuhQQNrc2x9u+rwQ+waeD/2aLuszhF2Zb06dlXdo+zqIw+1VnUPt1vrRCvYXzvyCHv/sEPsw0MPsv6HHGgfHrK/DTz8IBt05KH23hGH2OuHHmjdD9nPnj94P+tW5zDrUf9I63LYvtb1sH2se51Dre8xta1f3aPs7bq1re8Rh1mvA/ezCVdcaVn33mtZHTta1oMPWFanBy3r4Qcti5X5/HB3esCyHuwYuR/oaFkd77dlPV+z7CHDLXfcZMudONVW/TLd8qZPs7zfOKhtuuXP/sXNG7MToGBRlhUsWeYWxroFdSysc/PPRY15ea6tXkEnEC3Qc6NNLNxlYSJ3B7EXkyH0op0O7M5BnjBMqbkZn9gIC2EoCdE4XjTh5hJswD/m85keY5SFTpAt0ctXrLb33h9izz7/lR1W+26rtlsHq7bXK3b9rdn2wGM5NnVagTucivMxHnn4ZRs44DM3LcdIDzuMeBHceOONibNxWGDLQs2XX37ZvfRYyDl06FAbN25c4lRX2snGGtHQS2fw4MGJoxM2lvaGpPeVC+4G4owg1uzQl6HIseNKL2rx7L/I1W8oT+IonvxSYUu5Uv6Ug3OzHn30UbdTjF16KC1xXvzRIdGAP+j4WPg8q47w89P7cVLphk+/HOJHfbWft8JSqbCQ3xplpDC63FRMsE7I7chSHH2mRG2Wp2hXVNH9YEUfBIny0bSKBtAh6Zoaz27AfM3GAuLzAcOUP+dJMV3sPmjoHzSyz/Q8/u4+BpSefGNhMaM50VqdPFtRmGUzKsoIC6AgxAgMgkDD5TkCsninpS8RRlbQ6jVkl6gIVWia2LxgEn+JKRQuk4vuYOnx7DN2+M417ebjzrRux19sLx14nL16xLHW+7Ajrdehh1qPQw+2boccYD0PO8h6H3Gw9TzsQOt56P7W67AD1vwO3c96H7a/9Spavc2Ok1cOPTj6HXaY9T70EOt9KKu7D7Heh+l3qL16+GHW8+ADrc9RR1rf2nXsjSPr2Fu169sbR9SzvkfWt3fqHm9v1T7W+tU+2vrVqRP9ate1t+vWs3516tmbtY+2N46sa31r17e3jj7O+tVtYH1rH2tvHHWs9Tmyvr1Z53jnfu2Ievb6kcfYW3UaGu436zawz8442z479xwbdO6ZNui8M2zgeWfYxxf9xz658Dwb+O+z7OOzTrev/n26jT73LJt2zr9t6okn2vSTTrAZJzW0qQ3q2dTj6tm0ExrYtFNOtjEnN7SFrVrY0meetuVv9LDl7/S05f1esOVvP2/L337BVnzQx5a/08dWvP+WrXj/HVv+ztuWO2GS5c+cHf3caMesaBcOO3Fms1CNURDmclmY9pvbdshoSf7MOZY/d5Hlz8+y/HmLLX/+YjcH7I6+z86ywuwltppFcCtWFA2/8qXCVki2NOdbYU6erV5JY2bBXfRl4+b+3KLfaIdRYUGurc7PcYueZ8383e677167+JJL1jpkUTJPCyneSkov/FGHFE/NM7uCVtmK7BybvyjH7rynm9XY9UqrutNd9pddXrSqe/S3sy9aZJN+KkhcXc8pmjDy+GNP2euv9rFVuZSB9hztHmndunVi9ETtmxc3L7/XXnut2MhH/OVR+hIlj0m/4r8oy5p+8lyjae5EPRUpYLzwGalAIVF/9vTTT7vpb+GiFyJ0xSt0FO6XpaS8y8JfvPv8yM+nj59GHeAXQxo/nR8/7vZpyi1s4nHL8ll5iHdow7Nw9vPCX7ypXClXWMiTTwc+UIoUC6fEuNEXwvBn1C1a0xdNBUeaCLxGPOsZ/tkEEikf7mOaTRqulUZKC2n4ufdW0QgPuzS5wDU6giC6oJXTrJ0/fZt2WCLfbtofBQaFBsLRosWVhUvsj4owwuILhO+WYESVFA0TSoiwJTB+mnRx+7yvUVjgmXUI0VqEvFzWBOTZ6y8+b0fssL2dVX0H++Dfl9rUa1vb702us8W33W4L2rSx2de1sPltrrcFN1xv89tcZwtuuM4W3XS9Lb65tfsl3DfxfIMtvulGW3zTTbb4Rn632KI2N9vim9ragjY327xWbWzxTbe438I2N9qiNjfZwutvsHmtWtsXx59oPfbex17YvZa9sPue9vIe+9jLtfa1bth77Gkv7bGHvbzn3tZjr4Os9z5HWe996lnPvY+zHns3tB77nOR+3fZqaN33PtG6732Sddv7ZOu+z6nWfZ/TrNtep9rLe51q3fY+07r+80Trts+ZNu6yDpZ1bw9bdM/ztqhDV5t371M2t/3TtuDerjb/7i62qH0Xy7qniy1u39UWt3/eFt/exZa+9JGt/OoXyx76m2UP+dWyv51u2cNmWM6I3yxnzK+2auo0y5sxxfJnT7aCeZOsYOFEW501xQrmT7OCBX9YwULmW+dawcL5VrB4cdF2Qlbaez83AsIWQ/yyoq3DXOq3nHNOltnqZSxkY+qGuV/mgJkTZgpnpTtjhXNW3HkrdNo03tU09lXuHAjkwu1wYrkQy4LyaODRdndkIzt7uRUwDcNxklwoOH2qden8pA0Z8q1bHzBs2DB79tnnbMoU7vGJhs8dzaKORfKPny+DkToTdXiRO9FFKYmzOa6/aHrc5s7Ls08/H2tPP9Pf6h3f2v7Bja97PGhVtvuvNTjlZ+vZM9f++K3AuEuE02tz8zhlFMUk1z4a1N+G//CDvdXvTXc78CeffOI+Lvr27WtMDWF8HvmC1QuDl53aeTHm/uQDtPy8ILOp+g7li+274al79+5uxEVTZOKZF+rw4cMTH2ZcYIiyg5Ei4x5S+I+6kTwJT7Lb0HpKRiPONnGETTxsXc+iva44JYVJwSJccqi4CpNigz/lVtlTqbAICxara7CRkVWnaLizZRhNiZQQtXGUh2jR/Bq5x6/YL5qoddNIOqMGG0XI5Ynt1CC6J52IHSkq9GXR9FO0Kwu3G8nxBxhg1tGKlCDorihcWrEVFglMuttqKNi+W4JN40MT5U4YVM5oJ0q+rUJhsXzr/eLztvs2W1vNzTezT++53/JnckLiTMv7/Q+3/iF/5iz3pc/X/np/xNWoASMBM+dGC59Y/OR+POOvsLmWN32W5f0xz1b0/8xG3fO4TX74JRt333M2/r6XbPJDvW3qI6/ZhAe62fB2z9ivT35gz51ys120zXF28bb/tsuqN7LLqje3i6o3s4u2a2IXVWtkF1S7yq6o0cLOr9bEzt62qZ1d7Xp3Bfx5Ne6w87e/286p3tZOq9bGTtm2uR2/9WXWoOp/rP7fTrNj/nqCNfjbiVb/rw2tYdWT7fi/nWwN/naCnVj1X/avv59u9baqbw8d85B92magvdfkFfuw+Ws2oOWb1v+6vtbrqs72U/fBlvf7UncoU8HiubZ6+RxbvfwPW73sD1u9fOEahaNonjWxAM1fhMbUjJuzzbHoSHtW3C+3wjxOjOXSQYY4GRlh1ITFw4ljW6Nndz6LWw3r6ppD49zOJ7eAVR0L60+KdiqhN6CwoCXQYbjdUAVFIxOF9sjDnez99951nWNe0Vdrp06PWL9+b1sBO52KXr7apaVOK/pyir4SCWNqp2D1qmhY1+3EynVnxUTKM3xxEihdn9mn/xtpHR7oa5dc0dWq79rY/q8619jfb1WqP2yHH/uJPdE512b+sdqWZRU6ZcXdGYIC5rhhyop1L/m2Mjvb+vbraw8/+rDdf//9bvRAnb5/VLzajEueon++giDMUpRVqcgyKgxPlF2YsAiZdT3xEePly5e7qTL5M6r8yCOPJHbklAd+pSpUBY8Ux1n1hsLCtmZ2s6b7ekrKwKGsrOGSQpL802XtyozH99NFbX/tNL4PJ93OTIe7hHymKqMbIZAw+5o3mvmaLwXOJWCaK1Ja+JpelbvSvUh6vfyS7VxtG9tmsyr2xiOPuoOECrI4IdHbb++PAKzTze4S/8eqb//nh+FeEZ3EmLXc8ucvs/z5OZa/oNDy562OfnNXW96M1ZY/Z7Xlz17twnInFdisz/Ns9ud5NmNQnk3vn2e/D8qzOV/k25wv8+3Xj/Js3tf51vn6cXb6Pl3tstr9rMWJn9uVRw+0RvU/s0uP6m9X1x9kjU8YZOcf2dMuqPuiXVzvGbuk/pN2ZcOn7Lza99tF9R6xY3e/yfarepXtW7WRHVi9le23bUvbq2pz22frFrZ31Wtt/22vs/3+cZvt+4/b7eAdbrd6e7W104++1c447no7pUEza3j0FXZC/cvtuLqXWPtbX7IJI1bYrF8KbMLoHJs8scBmTC+wKVMK7OfJBTbt1wKbPKXAJk4qsKm/FNiv0wvst9/zLWcVC97McjmPxKJTNnU6K6dlsv2bM2OYOom+OorGL9jm7Q5tYycYL3HOlYmUFzd86g6cK/qEKWrtnIWzuminVh7bKgvNHu7Uybp07mxLWPtS9InV+Nqm1uf1N6UhREPBbr0JX1arLDc3u0hBjuTSfVlxRg5b1It2ErDVnK8idqNN/WWJOzOFcjdr+aztuucVVnX7prZtzbtssxq32qHHvGb1T/nMajf8yL4ZmmfLlxXa0qxCtxOIG1kZVKEI2TnL3C3NDEmvzFkZHbZnq90Wc65KwKid4F7TNsqn11DenPOkl438UsmBPwqiMrMThbV4jJRwfQTXY6CsfPrpp+4LH74U9/HHH0+MSumrnlEWzj5ROVLJf6BdfDRQeKh+GjVq5HYIbb755sYZP+lmJOPs5OrTp49dc8017vJbRu0WZ2UlFJfSKB3ESfYrTZmzg8JSGpjKJw7DiBo6RJAlJOSOPx0NfvxQWvjq5WwQqr9n9+62Y/XtbIsqVezFJ55cs2CJRUuseUjFj5EE6LoRBWx+BVbI4nNdgqULsHjmEiyecctfN53qJlSudOdSLc9/wbQCe/W5afbfe4da5wdGWZcHRtszncba4/f+YG/3mG3LZq5ec8EWt6iuLLSCosu3hn29wh66Z4C1u/Udu/O29+z+DoPtnnZD7d72Y+ycf79t1XfqZP9X/Xnbepd3bcdan1jVXd62LXd6ybbcsatV3eUZ++tOna3qLp1tq52etC13eMJ22bOb1fjn87ZNzWft77u9YFvu+rxttdsLtkXN56zq7s/ZVrt1tS1rPmf/qPWsbblzR6t1UAe78c737NHO79tzL/W1Ls++aC+89LL1eqWXPfb4Izb991/coXmcA1NgeU5p4WTi6MuD6b8cKyjIMivkZR2dponCgLLqTspkzplhVKe8YKPMMrqSbcuXcTZOoXXt0tmaNWtqM2bQERbaInZoPPOc/frLdNdzuIO3OIF2FdNITMcwjx0tmJWcuTwZVUFhKsyz+QvnW/dXX7Vnu/WxJq0etlr7N7W/73yfbbnLM/aXnZ+1qrv3tOr7vGs1D37LWt0+zcZOLrAlOYW2dGVhdGotSlwech2tuXODQ26Rb3SiLiNB+GHibYF2opduFCP1/9UuGdXBtG/ffq1tuanmwj8sDiUDXOCLm9O5T431K1LqhI92MrVs2dJ+/PHHBItgyLQRLxyVKREYHClHQIpKv3793HUnHHDK6Aq7VrlYkytQdDp7yplZTwZ6D7E+jKsUkD1kBhlDgUG21D7WQ2qjg4PCstEQlj0BBEIdDtQl3NhyS4gkKNygzMF4CDwdl9IpftlzuTbFiG+mJVh+UeiO/SiaweIdqHepWxROnFVcLx5dkWMcpeKeeYlxm2o+5+dEd8b0HzDBau52olXZrJZtvtm+VmWzvW3zzfe3KpvtZf/6Vwv79VfOYGHLejSSwU5dRjW48pxzaHBzrPvKfLPleYXuxbl8VaH9Nmu1Dfo0zz7ov8oGDFhlr72aa+++s8pefX2VHfOvH23rWn2t5kH9bYf93redD+xv2+/3nu20/wCrUrOvVdmpr1WpOciq1PzUqtT8zKrsOsiq7P6pVdn9E6tS8yOrsttAq1LrXdtsl65WpcaNtnm1C6z6zmdajZ2Ot2o7HGvVtj/Wdti5gZ357xutcbNO1uy6x+zyRvdb05ZPWvNWne2aJp3s2yG/WVZWoc2bl2WLFi2zWTOX2owZy2zu3FybP58t+xFmzNZwHI9bn8amn6JD9cCT2aVHH3veevR822bPWWHz5uXYb9MXW7u7HrXRo7hOoUhhKFIcGIDhGnhuS2a2aN6CHJs5e4XNmZtr48bOtttue8oaN+1kp555i21f8wyruv1ZttWOV9hWu7S3Kjv3tir//MQ2232Q/X2vQdb27hwbNiLfFq0odLiDf06B2coi+rNmLbPb297t7pG5+OKL7JPPPnFz3dm5OW5HERLGnTJqC7xgtTYAuVYbKE8ZV3tjRw47kjA+L2u3irLxIQ+VU7bKz/A826xpf+JHuQo7tnlzKSxHxPN1zAFt06dP3yS7aMRbZbKRG8kO5Va9HH300YkDTOm7+XEeC7buqtrUOEnOLrvssoSMURb8aZOMCClOqnkNCkuqEd4I+hLqyZMnu2sFBg4YYH37vGETx0cnREJaX0c9evSw6jVqRApL585uyE2LqjT8thGsFCVNTglhdb+ioT69MN3sQ9Hx2pyum5u9yt3KCTEn4KQr2tafm8P2ujVb/XnR5uZC12zgwK9s938e6A7F26zK363q37a3v/0V5ayqHVP/X/bTlN/diAQvWZSVfG5gZT0FL/Kim1VRXlZxdTmKEtfNM0WDkpPDBWqFtnJZoWUvi9wrlhfanDmrbdGiQpsxY7XNnLnaZs9dbdNmrLYfJxbYw0/n2PlXTbHzG620i5pk27lXZ9v512bbOY2y7awrI/cF12bbuVdm23lXLbTzr55qV7WYZHsc0tX+UuNO23Knh+z/dnjY/rJjJ9usRkf7204P2BY7PmBVaz5lW+7ypG25yxO2WfV2tvUOrW2Pfa+zWntdbHvsc77tue9l9s89LrXtdz7H6h7T2p5/8Qf74uuF9v6Ayfb+wJ/sw0FTbMDH06Jn/AZMsXc++Nla3/SS7b7XOVZz9zPtn3ucbSeefKPVP+46u6/j2zbwo9/sg/5TbODH02zgx7/YBwN+tv4fTbVPv5ppD/33fdtj33Ntl1r/tr33v9p22b2Rbb9rG9tm5062zW4vutGlKts9bgce85ld0XyxXdo42867fIndfGeOjRqdb+CIEomCAtbLsznoMFpA9/NP023RgiU2d/Z8mz1rvi1cuNRef+MtmzVnnqtL1mtFpyDrkDtkL7lR55k8tOx8kVm9dG6//XbjQLBNaVBQpLyID9euil6I9B8K//zzz92alYcffti++eYbd+CezrIhjtKJTrBTi4D6dkZWpKgwHbTVVlslFBbqTPKWWm7WTV2ycf7557v3jZ5JxZoolGXfb93UNi40KCwbh19KUtMRSRHhK+i4445zQr3N1lvbFn/5P/tnzd3syy++cHmzmA7DvUlSWJ56+ulIYXErs1kV4QY9yoDXkinR6bE+grUZ3HAarRSnI4wWa/LycffrsLvJuGeI7dh5Nnjw53b1VZfbSy+96IQfOtH2VaYMmJ4otNmzZ1m/fm/aO++8bS1aNHdYHHtsfXv+xeftmyGD3XH60WFHqyyvIJpaYVIFPtZMr0QjBig07kT9QnMvT7flP8/c2R+52YW2cjln20QjDLxc+TFCk72q0JbmRiMFC5YU2qJlhbZ4WaHNX1xo8xattnmLV9tcRkOWFBrh8xautgWLVtuirEJnZy0rtM+/zLOuL+Ta8y/lWrceudb5uVx7ve8qu/SaqbbN7i/bNnv2tW33ec8237WX7XrAa7bDnp1st33utJ1qNbFqO19m1XZpYtvtep1V26WlbbNTU6tes7lV2/Ua227XK6zaLpfatjtfZjV2u9q22/VKq7brVbbtLlfZTns0s132amU773m9bbtTE9t5j9ZWfddmVqNmU9vhn82s2s5XW/Vdr7TtdrnMtt3pEqtR8wqr7uhdbjvUamTb7Xa1bb97M3dkfq3929nu+//Xtq3Vww6o/Y098liOvfXOKmvXMce+G5ZvSyjr/NXOXrmi0FBCOU+FERt2/+TlF9rKFdwAbXb3Xe3tjdffsP8++ri1aHadtbyutX3x1Tc24KOPbP7Cee6EXXezbWFe0VRVtMUVIdZLuAwEeoNI8PLQC4Rhe9aQYGiv5dFhU27yV148y11SQTQidddddxm7rBjWZ/roxRe5TiPLfemvj0ZJtIN/6RGgrqSkkEpu7rzq3bu3O77/lVdeMT48WYeEm/VF6WAkHx999JE7LV7tD38+pjkXSe0i1fwGhSXVCJeSvoSC6BIIBJZ7jtDAr732Wnf9+tix4+yYY+rbQQcdbD/+OCZBne2MNWow6rCZde7cxfmXpkNLEPhTDikwsosTifIvWo3BglLdKWR5bnHlj2N+sL59e9u33/7P+vTpZZ983N8WL5qXiIdiU7CaCxELLGdVtFaHxg0eTZo0cfP10eFmOuSIL8poix4KE2cOwBkHlrGlT7gyfaSjbPicz2NqKrr7z43QMDKTt9oSNwTj5nXJgDtTGjn50ejM0hWFhiLCyMGK3EJblr3mx6jCEhaWMnKTU+hGcrBXrIiUoiWLo90x2SsLbeHC1fbj2HwbPjLfRo3Jtx8n5Nu4nwtsxNh8mzK9wO6452M78fRHreHpL9mx/+phx5zU3U4443U76aw+duKZr1mDU3tYwzN6W/2Te1jdht2sTsPu1uCU16zO8T3tyAY9rP4pb9pO+zxhW+z0oFWp1t622OE+O+akvnby2e9a3RN6OJonnf2a1TvpRcM++6J3rf7J3a3eSS/bqef1swan9bKjT37eur+x1PEzbFS+TZlW4KarUEweeni89eo91xYvWG2ripQ+MEVZcbcxMKrlRgMKbRVDLYVm97W/z77+YrD9POlnGzrkGxs3frTdfU9ba3dPW5u7YGbRcf6Rkit1239ZI2mqz+JSl9ondcwcLT9kyJDUZuZRj5c1altIdzTKSv/hxxFW8qP/4EoDzB9//OFeMCzW5SWknUMuMPwrFwRULyVlRn1K1mSXFLc8/FGw+H3wwQfuYlFtm2f9FCMs5WWCwlJeSJciH3U6EmbmBrn7qEOHDi51Lp/7ZtajR0/bZ5997eOPP0lQZYSlvBUWfx08DmUAACAASURBVE8+LxUalnj3FbDohcMIzCrLyWVEKN8eefQB6/dWH6cGFBSw02mVTZ8+2Tp2bG8/juHLFWWF+2c4WIidNtFiRxoICstVV12VOEfCTR841SQBR9GX45rnyBWdVVK0otWxxYLTAjQUOOAqBy4KYwFqQZ7lsXvH8mzV6lzLK8x3Nx/l5kejL4zUMAXF2hE3AlM07eHWz+DnrcVxozScMZIT7YZhV4zbxruK47GjER3isNtmRZHys2JVoVtzsyLPLDvPbDkLVrOj35KVkWKUtTxaxIqihHvJikJbRljRD2Vq0ZJCQ7F6t/8qu6vjPOvwyBLr/kqu/T5ztVsAm7UiokFaFsSKDm79lkCf59zCaD0KI00oZ8ujNUhdu3xs7749wnJXFHIkkOXnuiNkHL7uJmxOui2Mpi9WrFjp/G9ofaO1b3evLVvCYmLUwVW2ZNkcG/r9F7Zk2fwihSVSQBOHRxRVZ3HZKvIsJ0t5f/fdd+4LWPJeHtnzwigpP/kTRzzCk05X5WRedhJhCCf+hx9+6JR+3H6a8ihLZctD9SNb5dezbPy1Fikd60QjdvC5KfgLCoskJ01sBFcCe99999lJJ52UuNVU/kwDXXrppW6UgdMuMQzxatEt6bhAjBEadg2UJFj4+2Hk7T+THx0gRg3KT7OuDtQl8v5Fyg3Hs3OYWYF1evgB+7D/e84tv9mz/7AOHe6xUaOGO3/OHomOOVxzzoQUlquvvtoNaZOFz7OXZcLf59l30/gol18Ont10lsvZHadUdMJwNFqTx0gNi4oZdWGkhkWrRQtdfZvRlKLdxS4Oa3H4OT8gZWqqaHmGW/hatGbHLZ4tWmujtTgMSjAlJdstIuY5z9xPC4vdM1NYKE9F01krWEOSEy08Xi53UbgWI5OetD6dYn555pQg1v4M/u4XGzx0ss2cs8qmTF1oM37Pst+nL7BlSwCjqLqwKS8Lrd1CpmhqEGwlw61bt7Ee3XpagRv5op7z7KmnH7Obbr7e5s2fFaHvzn6Jhs9Vx7I1guDXd9ztx1G6ZPIcT8ez4uNGTpROcX3aTmYQBG+on/ii4buVnjDSYXxFX+FxW7SUBp7khy036chP8WTzRczXMQt0MQMHDnSLcP3RFZ9PpZMt+vFyQ4s4iueIF/0Tj0qrOHommuIozE+fLC/kx0/vu30avhuaxPPjKp94PPlj+2FyQwOcZODfj0u8ZPkovuxkcXzaykP56pn0uOXPM+ni9OJ8xMOVTnacnvyxMX56ueN8FEV1FnUXN8RXWsKUp+Lq2Q/z/fAPCksc1U30TEXqp0q66KKL7IILLkjcXoq/GghTIqeeemrilmmmhHSh49Zbb2277babYbMKXReKSTCwlYcvQBIU/AgnXjycOAgeP4zC6Uj0MvIF2XejtGhdymeffWqvv/6aLVmSBRX3+/777+zll1+yWbNmumfiE0YeWtPD3O5mm23mFDad1Akf5K0yxXnUs8JVPvzl52OCH3HgihVAEXfElol8iCOMfDs6ZC3CUDiREv+oTExDrXIHvFG+iHehEL33tYAYBNwvOszWKUooS/xQTNhN5Z45Q44FxtHBuM7tzqRj4fGqyJ9dRPyWL+f4czAril9EDzooOo5mUTr8eCYda38WL82xlTn51q1HL2vd5ga3eHNpog5RUrj9O3oRR2iBUdG9IdSmU2DM3n//fRswYGDRVz/xC9y6puUrllheHkrtGmyFujDWMzb4iiZu4a16pb3I7afD7b8soY1RXJ+m3PH0PPs8UY/xuHoWX4qvZ8lanJbyIp5o4Oe71d5Ek3Dxnyw9SgvpSUd7Utx4HkqrvPxy+X7E88OgI5pxGjwTJp7j8RRftvJRveAvzHATrnIrLv4+Xd9fdGX7ckEa9auSCeKJ1zjdeJholmRDxy8H8VQWd/haUZtQepVBtvwZLVM6/MSzwpOVl7xFh7yUXv2pwqBBej37tEjjP+PWyB3plEZuv6xyy1Ycnx5+6zLimThBYVkXUuUcRiVS+RIARlHOPvvsxNQH4RK066+/3iksWunPyMM222zjpks4MZFpE7bH/eMf/7DzzjvPXdveokULa9y4sXGq4oABAxJCyFAxi7/8A4v69+/v9tcz9cI++zZt2tiZZ57pjv2W8CFI3LaquXHxzWmbzZs3t9atW7sf2+G4IVtD0sBKuoMOOsjYtUCZGGJv2LCh4/Xmm292a3YoI0obF9vpynm2b2tKiA6Yw7JuvfVWo2zNmjVz6eAVN4dlEY4ZO3asMfKkG3z5smThJCM1TZs2delbtWrlsOGMDZ2BwKJndoRwnD2GESvoUjdsDWXBGYc+kR/PXEiHYUHjPffcY1999ZV75t/rr/exq6662po3b2GMMLRo0dKaNm3mnkePXnNGRsf7H7QP+w+w7BxuKTbr0bOXXXrZFXb+BZdas2bXW4sWbaxlyxvsyiub2ODBw9zIDX0ei4XvuquDffbZ4ITf00+/YFddBS6trGnTG9zv4ouvsX79+rtt46RDcbnjjnvto4++TKR75ZU3rWnT1taixY3Wps1t1qrVzXbxJVfaK6/2seUrshN3kjz77LNuoaAWfyM31MV1111nLVu2sCZNGlujRldZp04PFbsskMOnkAsuLkSJ++ijQdao0dXWuvX1dt114NLUySrY+4sPORSN+pGsgjf1Dy3yRGaQWWzFAXuUdhaezpo1KyH35E17QFZJyzoPZJ0D1TCSZ26DnjBhQiId7nvvvdfVOenJi3Ssa0FulI41LsiNXizIHKf1wh95ghNlQXa4rFFm/PjxxhQO8o2hncE7mCCjbEsmDem57FAdOtcV0K55MemFwqWCfNyQljyR1SuvvNKtXVE7Xrp0qZseoo3pRcKFitCHV9JSxnPOOcfeeeedYi/fd999NzHSKT44VoE8rrjiCmvbtq3jmVN1/dEczh+h/UluKCdTVKp3ykh9wDttXv0eO2fAGZ5l3nvvPVcu4tP2+ZF/165dE3lS18iJn45F06o/2i7pyZct6+KLEWz6MfoBGe6tot3TN4EnZYRPfnxEgQPYkh8H+0keoEmfAK7UBT/owAOXeCoe9FhbxLPqA57gjXogPW5s6Ou9gXKCHENL6bhfCz9wRUbvuOMOlx9u3h2Khz/YigcWZ1N/9I9gA6/gTr/ny2rnzp3ddRCUlx/9HbTBBV6pC/gEW+pJMkD7Z/G36pW2As6kJb5+5M9HqkxQWIREGthUOAKjDg4ho5PQSILCYRUhP/fccxOdMgpLtWrV3Mt8v/32c8rFiSee6ASH3QE0Mn508NyKqpcA+SHo5KEOEvqE08nTef7000/uRY+NAqB48EknR3rc2BiOliYPVpCTHjeNQ+mIw8K/KVOmGC84GtQzzzzj4uFHfNKhXPByoCNWWjpSFBYaBJ0PnQPlQiFRGtJxRgb5q+NGgYA2DYZGik1ZxCfpeVFRRtKpIVE+/NWBwTsYkgc2nQP5gxU26cCBPKCjIXjS/frrdBs3Djx/tpEjR9mECZNs0iR4H2cLF0brC4jHIjYOZOKgt/fff8+GDh1igwYNtLPOOsudowGvKjPlAAO9LMhTnTLyQj2CIXxOnDjJpk79xYYPH2ELFix0Z5ywGBkzfvwEx4Oe58yZaxMmTLRffonKSPlGjRptM2fOSnRqpANTXxGlrjigjN+YMT/ahAnjbMyY0TZ9+q+OR+QEbObMmeNeynTgdFL/+c9/nGJKZ0j54Fl1ojokLfSpNzCmfBHv44vyG5OQV8pLOskk9YgMQkOGuqFuyYd8KQt86/A1vTCQHdLpmXx5UaNUIHNgTjp4Vn7kgcxCi3TiFflCNklHnuSPLEneSAevnKSrNPhRZugTl7KpnRAXI5lWfs7TzClo5CP+4JW6pP1JZsgHefPzQ9mjbcCveCUtGEreKCv1IToqA+2CNMgo/PKjTwAP+MQQB2WAZ6WnDyI/MFG7gm94AUMMCidKIeUUv9Qj8chTGIEx7UjpUOIIVxrypF7Jj/r3+xylIw4yRLjav+oSDOETTMiT+iCeZBVeoa0XtMpIXPgQv9ABH/hSHwdW1LewghYYUI/EJb3qVG2dOORNGLKqfo52Bhbwh9JGnfDDj/jwRd74UR/iE5yhpbqAb9UJdY6h/qkz6kO80hegCBKftPAJHfyQVcUjL5RAnsGU+lT5yAcs4QmcfGUxKCwO+vT5RwVKaC688EK3S0gvBDoENQC0eRQSBBETLbqNzmFhegiDIEhAEC7R9f1dxKJ/xFGY0hGE23/20yi+/Pxn0tAY8MOIPnyIFxoXbj+daGFDgzjqCCgbCgujRL4il4w/5Qv9OC/KkzwUjps0Sufz4bsVXzT17Mfx6YCB4iajzUVkGOLwUxy+VjTSAw0MXxuMThEvXgbC8eMn4/MGXdLJRHH96Rt4UCj1tabu8EX+RDt6gUeR8aNufdoRFcKhT77F81mTyxqXn16Y4ef7E1v4KGU8HH+lVxzZ4nND0lA+4a90Q4cOTYz68aIRLsoHeRWfhMmtcN8mbF3hoi3elVZpxJP8sakf/Imj9H543E0c4ifDTWHxNDwnyxs/+YtH4uKWf7Jn0SeO+Fb8eNkVN142xVc4z6o7+clOFpewuL/i+7afL7wlM+J5XfSEieLEbeQI/tX/JcsHP6VLFq46KAmHeBpo8VO6ddGXkkoc6CN3vikJG78vUXw/P/nF7aCwxBHZhM80Av1ggyG1008/PXEZFkKkjogRFobs+DLCMMKyww47uJc50y8yvhBIEP0wCSY2RjaCRlr9lIZwBFPx/DTE9cOJhx9lil5wa7+0CCMORvF9mi7A2+2gNSxMAUiRU3rsOG9KL3tdcQjzywVvPAsLnqG/LhOn4acVbWx+KCpSEOJlh45v1PD58mCYny9kjGj6ceVWmGz5Y/v5oZjw8+OtWrVm7pv4/gvYjxfdAOtpOcUUQKYwGQGiQ18TB1kASxmfNv78KK9fl8LDz1vYig52sjRKG7eVzqfj0xePSgdt1YOfj+gonp7VVvWMLfrERdGJp/HpxsP0DF/Ei5tk/ioDcePuZDTEn3hXGj1DBz7wFz/ig2fSK43C5a94ycqtfImrdIrv8wn+iuvzhJ8fpnoSDZ+mT0/hvu2nTRZX5ZNNWikUvp9PM+4mntIQ5qfz/ePp4Mfnj3DhEXczquSXOx7utzspHvH4pJGfnw/+6zJ+Gfx6oc5kRE9xhQH5KV4c/6CwCL1NbFNJqkBVHMrIIYccYp06dXLcaXTl9ddft/3339/Nc4ptd3Bc9epOYXnuueecN3T4SeDw5Jl8fH/li2DhL4O/wuTn29D1aeNWetxKK5u0hCOMSuuH+WmUj+KpkXKwEmtzmMPV0CRxZHD7DQS3H048GgH5YvudHmHwR5h+orsumzR+48ctHIqnA/fiigG8CQP48Z8HD/7GZs2KFFJN1bB+hnU//uiSyseLQA09WbnhSdiQJs4jC6IZCREPaxYJo2xECgdpxG/xshUfgSEfFttqhIX0cUzJR/iLpmyftjotxVW9EUflwS+eVn7y93knnZ/eD8OtPNf1ciW9aDti3j/xhZdowb/qSlFVJj0ns0kDDdGJx4EHwsQL8SkDBj/fP56WZ3jAUFbiikcfE6XDT7Tlh80LT/nwLHwVJ1kawlQm5an4sn0cxR9hyo88fT59PKGpqRHRU1nFjx8OLT8P0ugZWuJVtGT75cZPz36d4M+0ksKUljg+/0yNEIefeCVv3HGMVAbRFH88yy0aUgriNMRH3CZePK5oKW782Y+v/BUXW+HiGz/RUJgvN75bdILCIiTSyFblsZiVXT4sTmX+EcPcJotf99xzz8RJm/izSGrHHXd0CguLzTCigy2hdgFJ/ik8WVzCFK6kevbjI4jKU41Q4XEa8hefSif6PCP0ykfCi2KmRbf+/L3SySadn4fyET3Zih+PS7jiiDeVSWHrS6P0a/LgZR8pV2uHRf7CEPvWW2+z778fZsuXr7C5c+e5uVwtmBRN7Dgt8enHibvjvBOOghLt6FHZpahEtl8fcXrigbz5RaZ4evIUllF+a8rMM52XwnkhyV1ErMRn5Y3tp5E/6X23noWTHwYPPCtMecsWfZ9XhSmt4uAvLGTH4/h5C1/8RCMZH0ojmnomP9/Ns14cPh2lI1z5xNP68QnzjZ+HH0+0/HL4caHBixM/xZXt08et9i68RMfn3XcrXPSw5Qct+ftplIfPD3n7cXhWWtHz/XBjFEdp9VwUXMxSfoqrwPiz/GUrXHyADUb+shVfda9nbJVZtmiJjp59WtDxn0sqm9LGbT9/uaEp/kRPefAst+LLDgqLkNjENpUUr2g0clZJ84Jmt8+BBx5oNWrUsG233dYd5QzLEjxGHggjLlMGGNGErmhv4mKuM3vxSyT45RnDorr//e9/xg6RW265xY2w1K9f3ylpTJFo5Mkvo09rnZmWUaB49fOl0Ykn2WTnl82PL1YUl86dtRJcWMdKfXYdsAhNNBQfO1n+frjiiDadhdzxeOF5bQSEldobu310NP/asYNPZUNA7U/lTvbCRYbi8fxnwiVn8tez6Oolz7Pfvyi8ottBYUnTGtaQJ7s8WLdRt25dd/7Irrvu6s6wgG2EmXgYds9kusJCOWioaqRqnCwyrVWrllPGtGVb9mmnneZGnUirToIvDzV4XjByO6BS+I+8xDM7DTp27OgUDS2MJmuVTWyUPH2kGGts6lplXONb3EW4yqtRCp79dFJW4AX/OE/FKYYnEBBGql+2eKJMBhMQSIYA8iJZof1JfhRXoyN6lh1vj0rHehS5iVuSW3Qqqh0UljSpWYQbwdYPtnxBZ1sbX9csttRXHi8k5lgx/i6hTBxhiTdAnlVOTuhEUWP0iBtNOTiuatWq7rlBgwZuq6XwcmBswn90LCwG5uwIThNF2erbt6/b4kh9YiiblIY4q36HRXxfLohLR+crH0rvp5Ofb5Mn8sLWQebJMeWpzPm8ZKobjCWTjHaV511CmYpZZeNbbdwvtxQX389vw7RN/1nxSMcHKyPMrFvkmXWNfnzadGUyQWFJw9pGIDHYvtKCUKtBKI460ExXWPxq0EtaZURZYxcUw/DsgOIwJEYvHnzwQXezKecpYEinND5WvtvPpyzd6nA4uAtlhU4Go/Mb4JsDyGTgkzTYvlvhcVtxS+PPqI3kQvnDF/ixaJcDmr788ktHSvnH6YbntREAV30Zcwgh68okq2vHDj6VCQH1y9i0VeTkiSeecNO5aoPgQXvzDc9KqzaOTGE4XO2tt95y9BSHg9i0ds+nU1ncQWFJo5r2Xx6+G2GNCzpCjYDzw3AarO4SysQRFsqgMvpl90cU1BmoyhRfz8nsDZlySZa+tH7kg+HIeXZpaQeTXnAoC3Q+8bqkDNShOiTlR/3yi5dRz3E6pFOHJxqKC2+ciDp8OHc0mX3//ffu4CjJTzxvpQ/22gjoZXLnnXcmTj9eO1bwqawI0Ob4WOAEaBQORlf52PKVDNqb2p5wklzpGTocvqY2rbbMaDMfp+pv1L8oXUW3g8KSJjWslwYCKreEHz/fIKR6mWnBaaavYVGDVDnBwPfzn4UHjVYN3Y+L24/vh4l+Wdvi44033nBHVesESnUsHH3NsK5vfB7xF99+HNwqL3aysvh+ioMf01MYFCgd9U2emKeeeso4AVnGpyG/YK+NgKZguTIgrGFZG5/K6oOSQhviuAGOnPePuSeMqwnYOKD+wMdJo6G+H25/ukftk2UBKMuiI/942or6HBSWNKtZXwDl5iWkF6LY1ctO/pm+S0jlUfkos16uyfw08kIcMGCEidNvmSpiwSuGjgA65WHgh/qik2FbOR0LbjoW7kl64YUXEqcSw4/qFjf8+8/iV8qHnv048TDFkT9x1REyfcHXHrxIXrivJD5FJRrBXhsByaJs/6RbYb52quBTWRCgvdG2uK6Be6ak2GoEhJ1+vhITx0Xx/L6Ae5t00jX0icM9ax06dEisQ4vTqejPQWFJoxqmM9RLSbbvB6v4+2ES9IqwhkUvA14ActOA5ab8woM4GEYOOIOG4VPdW8E9GCwsVZzyfKHAH8O/rLvRLiHu1FA5VHeqS1eIDfgnOkqSjB5+8KHyv/nmm24KiDT6asOPl66fXjSDXTIC4I8iKNx4lrvkVCGkoiOgEQ/WhrEgW6Ob6rsYkWMRvtokeChM2OhZcbiDhzO3WKv3zTffuDu36OfjJ3wrfWWwg8KS4bWsr+hNobDQUaMwqYGVJ5R6SXC4Hg2bF7H8evfu7Ra+at5Y/uXJX3nnpc4OeZCbcqsjZS6dG185JZeFe3ztbYp6K29cyjI/8KoMslSWmFUmWrQ7PpQ4mZxbutUOucSPm6m5ONI36rvxU1yFS844Z+rJJ5907ZapJikrioetuL5fRXUHhSXDa1ZCXx4KixoGHTdfljL4K0x+5WHr5ayvXJ7hA+WF25+59RNTmV7M6vhUR9j48dXHWTa77babO4QQ5YX1TyickqHyqLNMzUO4Ss65TRncJHOZWq7Ad9kggHxINpjGQbnQtBCbIDRN7eemfkmy5Yf5cqW+VqPpxFNefprK4A4KS4bXsl42qVZYaFzKiyvRWQXP9mKuiccka3SpgJaGSl5q7Fw9Dg80avmBBWtGdN5IZWnc8XIKD77Q+vXr57ZYq9Pji+/dd991HR94llf9pUImyoOmXiDCmAXLuni0PPIPeaQ3AvH2IyXD7zcpgfzVj/mlIm6cjsLVlvkYKymO4lZkOygsGV67UiJSrbCokaCssE2PHy9BLQpTeKrg1ItC9NWA+/fv73blcO4JW4mZO54zZ467dwdsiKe4SlsRbcoojKgLyi7lhGkg1qwQR/XENuv33nsvkaYiYlLWZeJlA37CELzxE+5lnV+gl3kIqK+RXEhWKInCcPsyQxz/OR5OW5aiE0ekJP94vIryHBSWDK/JVCssakjYjFpwnw9GjY/TPl988cWE4qL4qYSVvJU/CgpuhuhZ5MrUBxdEYsQL4X7HkUre0oG2OkthxKI9tlQjK8KBeXYpLOAkrNKB/3TkIf5SAUthJkzTke/AU/khoPYmedAHg/yTcYIMxWULP6X10+AvWsrDD68M7qCwZHgtl6fCwjSCTkhVg+JsAc704MoATCobEo3Vpw8PfgPWCyTeCcQ7hAyv8qTsJyujFtxOnDjRKXQ8a/fCqFGj7LfffkvQEnYJj+BIioDkTwpLXCaTJgqeFR4B9UMqqOSEZz4g1D6x/TA/XUmypL62pNEUn4byr6h2UFgyvGbLS2EBJvb/o6Bg9DLk3AGmHLQC3m+MZQ1tsgZN+dVg/XB9jVS2FzF4xOtA+LD1m3MctBhZ2BBf7rKus4pCT/gIS5R08AwmIAACanPYciMzUjaSoRRvd0qnuJI5Pfu25HBdcfz4FcUdFJYMr8lUKyzAo4bEQWOceaJpGMJYG8EBRzrfI1UNyKfrv5T9Rq84vuLih2d4Va+TfZVdkdShYROmcOpJYZUFG2GysTZypxcQW8M5EDCYgIAQUF/Ms/pM3Gp7uNX2fD8/nWj54T49pS8pnvwrqh0UlgyvWQl7Khfd0njUgFho27JlS3cwGutXOIpex9ArToZDGthPEQJx+dBaG7LzlSf5yy+eLkXsrZesr7DccMMN4bbm9SIWIgQEyhaBoLCULZ7lTq08FBYKpZcHLxOuPGdKiK9NngnjF0xAoCQEpHQgr3FZUZgUFZ+Gwny/TeWGb7U37nMZOXKkY0WjWJuKr5BvQKCyIBAUlgyvaXWgqRxhEUR0zHrZ8HLR8CQvlXR6sYjfYKcXAr5C4rslOyW9+CVz6VAa+MbcdNNNYYQlHSok8FCpEAgKS4ZXd3kqLILKV1yCsiJUgl1aBBiZkxIiW0qLaOAf91PYprDFi9obd8N8++23m4KVkGdAoNIiEBSWDK96daCpHmHxlRRBppeKbPkHOyAQR8AfUVGY7yeFwPdTPCk1et5UNjyKl88++yxx0m0ynjcVjyHfgEBFRiAoLBleu+WlsJQEU1BWSkIm+McR8GVFu224Y4XbrLnEUnevaGrIjx+ntSmepVRtirxDngGBgIBZUFgyXArKS2HxXx7kyUsFg79eMBkOZWA/hQj48sOIBIbTibkk7rbbbrM77rjD3U+FnwxpMOmgKIh/f5QFuUfxSgf+hFmwAwIVGYGgsGR47ZaXwpIMJs70UP7JwoNfQMBHAEVFSsjcuXPtww8/tEWLFiWijB8/3rKyshLPONJNGRA/y5cvL6a0F2M6PAQEAgIpQSAoLCmBtfyISmFI9RqW8itRyKkiI6DRFe59GjhwYEKBocxcYPn0008nvQtKisKmxkYKFzddT548eVOzE/IPCFQqBILCkuHVHRSWDK/ASsa+rnRgW/Dnn3/uSo8fCsns2bPtoYcecjdtEyDlIB0g8hWm+BRo/Dkd+A08BAQqIgJBYcnwWg0KS4ZXYCVjn5c7ZsqUKe6ahwULFiQQYHpo+vTpiePvURLSSWlhdIipIPhauXJlWvGWADE4AgIVGIGgsGR45QaFJcMrsBKxzwtfIxUoLpyY3LVrV2vXrp0bWXnsscds5syZCUSkrKTDCIZ4STBX5Eg3pSrOX3gOCFQkBILCkuG1GRSWDK/ASsY+yode/txB9fHHH7vLM7mTauHChQ4NtjdrJEYKTjrABN/ajt27d++whiUdKiXwUKkQCApLhld3MoWFr1YMHSwdvn4ZXtTAfgYjEFc8pLQw6qI1LPHikUbx4mGb6lmLhtu2bWtDhw7dVGyEfAMClRKBoLBkeLUHhSXDK7CSsO9P6/DST6aIsE0efz9uXNHZ1HBphOWuu+6yYcOGOXbgOd343NQ4hfwDAqlAICgsqUC1HGmWRmEpR3ZCVgGBEhHw17D4kZK98JFrKTWy/TSbyi2F5b777rMvv/xyU7ER8g0IVEoEgsKS4dUuhaVXr15Wo0YNq1KlilvISLH0IuDrL3wBqsjoVgAAIABJREFUZnhFB/bXi4BkHFtrYMpa2dGUEOfIjBw5MrSr9dZKiBAQKDsEgsJSdlhuEkrJFJYuXbo4XoLCskmqJGSaJgj4SouUmY1ljWkrzM033xxua95YMEP6gMAGIhAUlg0ELN2iS2EJJ92mW80EfsoTAX+6iWkbf2SlLJQV0ZAS1K9fP3eWTHmWMeQVEKjsCASFJcMlICgsGV6Bgf0yR8BXXnzFZWMy0mglNGhzUmB4RkHynzcmn5A2IBAQKBmBoLCUjE1GhASFJSOqKTBZDgiwPVojIKlQIKAtuihFWs9SDkULWQQEAgJmFhSWDBeDoLBkeAUG9ssEAY2koFT4bikYZZJJERFtvxZNX5GRX7ADAgGBskcgKCxlj2m5UiyNwlKuDIXMAgKbCAGNeGhKSMqKFJiNZQu63CGE+fTTT+3XX3/dWJIhfUAgILABCASFZQPASseoQWFJx1oJPJUnAigmjHL06dMnoUTID1uKy8by5NPxLz/0/Tc2j5A+IBAQKBmBoLCUjE1GhJRGYSnLTjsjQAlMVngEkHuUFAz3EU2cONFeeeUVmzNnjk2YMMG+++47404iTFmNsPh0/GkgeAlKi4M6/AsIpBSBoLCkFN7UEw8KS+oxDjmkBwIoDFJSpDx8/fXX9uSTT9rcuXMTTH7++ef2wgsv2OLFi51fWSsTmnKCeFBWErAHR0Ag5QgEhSXlEKc2g6CwpBbfQD09EEBBkeKB0qL1Kp07d7YhQ4Y4RYY4Ojq/ffv29sUXXyQUnI0thUZUpChB21eSNpZ+SB8QCAisH4GgsKwfo7SOERSWtK6ewFwKEEBp8OX+vffeczc+k5X8b7jhBjcthJ+UjY1hRTSkKHHSbbj8cGMQDWkDAhuOQFBYNhyztEqhDjqcdJtW1RKYSQEC/lQMCgRm6tSp9sADD9i0adPcc1ZWlk2ePNneeust+/333xOjMmXBjq8ocVszIzsYjfyURR6BRkAgIFAyAkFhKRmbjAhJprB07drV8U4HS2eqX0YUKDAZEEiCgKZi/CD5/fTTT3b//fdb8+bNrW3btvbZZ58lRlr8+BvrJj+NsDz44IOJEZaNpRvSBwQCAqVDICgspcMpbWMFhSVtqyYwVoYIaBTDH2WBvPwXLlxoixYtsnnz5iXWscTjbgw7ykcKy6233poYYdkYuiFtQCAgUHoEgsJSeqzSMmZpFJa0ZDwwFRDYQASQdY2qcA6KpoWkTGidCWTlt4FZrDe6FvUykjN48GAXn7xSld96GQoRAgKVCIGgsGR4ZSdTWLp06eJKReeuzjR0qBle0YH9TY6APyXE7qRJkyY5nkLb2uRVExioJAgEhSXDKzooLBlegYH9jELAn2YKikpGVV1gtgIgEBSWDK/EoLBkeAUG9jMCAdqZr6Dg1vQQt0RrqiojChOYDAhkKAJBYcnQihPbQWEREsEOCKQeASktTActX7489RmGHAICAYEEAkFhSUCRmY6gsGRmvQWuMxMBLfTt2LGjDR8+3I26+NNEmVmqwHVAIDMQCApLZtRTiVwGhaVEaEJAQCBlCHBAnaaEUpZJIBwQCAgUQyAoLMXgyLyHoLBkXp0FjjMPgWRrVDQ9lCws80oYOA4IpD8CQWFJ/zpaJ4dBYVknPCEwIFBmCDAdhHIiRQXCvrvMMgqEAgIBgaQIBIUlKSyZ4ymFpVevXlajRg2rUqWKhaP5M6f+AqeZhYDWsIwZM8aYFvIPq8uskgRuAwKZh0BQWDKvzopxnExhCQfHFYMoPAQENhoBjaToaH5ug9ZJt2HR7UbDGwgEBEqFQFBYSgVT+kaSwhJua07fOgqcVQwEmA6SwnLnnXeGu4QqRrWGUmQQAkFhyaDKSsZqUFiSoRL8AgJli0B8hAWF5YcffnBrWBRWtjkGagGBgEAcgaCwxBHJsOegsGRYhQV2MxoBf4RlxIgRay3CzejCBeYDAmmOQFBY0ryC1sdeUFjWh1AIDwiUHQI6e+Xuu++2YcOGlR3hQCkgEBBYLwJBYVkvROkdoTQKS3qXIHAXEEh/BHTWikZYOnTo4E66hfOw6Db96y9wWDEQCApLhtdjUFgyvAID+xmDgH8GS05OTrjwMGNqLjBaURAICkuG12RpFBYWBYaFgRle0YH9tEIgtKe0qo7ATCVBICgsGV7RQWHJ8AoM7GcMAv4hcQsWLHBTQf6oS8YUJDAaEMhQBILCkqEVJ7aDwiIkgh0QSC0CKCe5ubkuk3AOS2qxDtQDAskQCApLMlQyyC8oLBlUWYHVjEdAU0E///yzZWdnu/JoQW7GFy4UICCQ5ggEhSXNK2h97AWFZX0IhfCAQNkg4E//0O6kvJQN9UAlIBAQWB8CQWFZH0JpHp5MYQmXH6Z5pQX2MhoBpoX8URXOZgnKS0ZXaWA+QxAICkuGVFRJbAaFpSRkgn9AoGwRQCmRYjJt2jRbtmxZ2WYQqAUEAgLrRCAoLOuEJ/0DS6OwpH8pAocBgcxAQAfHtWvXLlx+mBlVFrisQAgEhSXDK1MKS69evaxGjRpWpUoVC1NCGV6pgf20RUAKy+23326DBw92fIaTbtO2ugJjFQyBoLBkeIUmU1i6dOniSqVFgv5QdoYXN7AfENikCGhn0D333GPff/99sbUsm5SxkHlAoBIgEBSWDK9kKSw9e/ZMjLAEhSXDKzWwn3YIaO2KRlhuueUW+/bbb9OOz8BQQKAiIxAUlgyv3aCwZHgFBvYzCgFOu8VwWzMjLJgwJeRgCP8CAilHICgsKYc4tRkEhSW1+AbqAQEQ0DZmnXTbpk0b+/rrrxO7hgJKAYGAQOoRCApL6jFOaQ5BYUkpvIF4QKAYApoamjlzpnH+Csa/Y6hY5PAQEAgIlCkCQWEpUzjLn1hpFJby5yrkGBCoeAgwyqKF7BpxqXilDCUKCKQvAkFhSd+6KRVnQWEpFUwhUkBgoxAoaRRFIy4bRTwkDggEBEqFQFBYSgVT+kYqjcIStjWnb/0FzjIDASkmsn///Xd3+WFYcJsZ9Re4rBgIBIUlw+sxKCwZXoGB/YxAQLuDdA4Lu4SGDBnieA8fBBlRhYHJCoBAUFgyvBKDwpLhFRjYz0gE5s+fbzk5OY73kqaLMrJggemAQBojEBSWNK6c0rAWFJbSoBTiBAQ2DgHamRbdbhylkDogEBD4swgEheXPIpcm6YLCkiYVEdioFAhoDQvnsQQFplJUeShkGiEQFJY0qow/w0pQWP4MaiFNQGDDEKCdoaxoO/MTTzxhI0aMcETCwtsNwzLEDgj8WQSCwvJnkUuTdEFhSZOKCGxUeARQWHSXULt27RK3NVf4gocCBgTSBIGgsKRJRfxZNoLC8meRC+kCAqVHQCMrUljuvPNOGzlyZOkJhJgBgYDARiMQFJaNhnDTEpDC0qtXr8RtzV27dnVM0clqy6Xm3jcttyH3gEBmIqD2I4Wlffv2icsPM7NEgeuAQOYhEBSWzKuzYhwnU1i6dOni4gSFpRhU4SEgsFEI+FNCt99+u/3www8bRS8kDggEBDYMgaCwbBheaRdbCkvPnj0TIyxBYUm7agoMVRAENMLywAMP2OjRoytIqUIxAgKZgUBQWDKjnkrkMigsJUITAgICZYqAP8Ly+OOPhxGWMkU3EAsIrB+BoLCsH6O0jhEUlrSunsBcBUFAa1hUHM5h0XH9q1atcmvFFBbsgEBAIDUIBIUlNbiWG9WgsJQb1CGjgIDR3rRjKMAREAgIlC8CQWEpX7zLPLfSKCxlnmkgGBCo5AgsXLgwcSZLUGAquTCE4pcbAkFhKTeoU5NRUFhSg2ugGhBIhoAW3XJb83fffZcsSvALCAQEUoRAUFjKCFi+svSlhc2cd3zeW1n5/oqnNH4c0ZOfbKWn82QuHRN2CQmdYAcEUoeA2t748eNt0aJFqcsoUA4IBATWQiAoLGtB8uc9pHyURAEFREoIdknX0vt0/DSi64fri+/ll1+27bff3qpUqWJhW7OQCnZAoOwQYDTTb3tQ5rmkdlx2OQdKAYGAAAgEhaUM5YCOy1dIUCb0TDZ+uLJVB0g83HHjp1G430mWZkpIecRph+eAQECg9AjQntUGs7Ozi7Xt0lMJMQMCAYE/i0BQWP4scrF0dGS+0lGSkhCPFyPjHpPFwS9u8GNLJSZMCcXRCc8BgbJHQB8Ir732mk2aNKnsMwgUAwIBgRIRCApLidD8+QAUCSkYjJDwi4+2QN2Pp9yS+dFJQkNGoy7ElcLSo0ePcNKtAAp2QKCMEaDN0d40BXvrrbeG25rLGONALiCwPgSCwrI+hDYwnFEWTQPRyfmKhkj5IzHyi9t0jvF48WcUmZycHJc0jLDEEQzPAYGyR0AKS7t27Wzo0KFln0GgGBAICJSIQFBYSoRmwwKkTJQ0QkI4oyEaUhZ1P75oKAybXUBK48dVHCks/m3NYdGt0Al2QKDsEKB9SmFhW/OQIUPKjnigFBAICKwXgaCwrBeiDYsgpQNboytTpkyxDh062JVXXmn9+vVzSgjKB+HE44dBMfHTLVmyxJ577jlr1qyZ3XDDDda6dWu7/vrrrWXLlnbHHXfY5MmTE8yFEZYEFMEREEgJArRNfTwwJRQUlpTAHIgGBEpEICgsJUKzdkB8hIMODD+M78aPZ8zPP/9sp59+uttuvPnmm9tf/vIX69q1qwtLNmWEn77ifvvtNzvhhBNcWtKxZXmLLbZw9nbbbWf/+9//HB3+sYalevXqLuypp55y/vDAT4pRInKKHX75ySqOW4qzr5DkhSF2MuP7x2UxWfzgV3oEwJY2hC2F5a677rJRo0YF2S49jOuMqf6SSL5bfaH8qAcZhfmyr7Bg/3kEhKso+JjLrzxs6lU/5RcUFiHxJ2w1lDioqvB58+Y5ZaVatWpuhISzUs466yxD2WDkROkRCHWIsKHGOWfOHKtdu7bVq1fPxX/00Uft/vvvN+bPmfaZOXNmgutu3bolFJb4lFAiUoodlAHexf9HH31k6tiTZS3chEOyOMFv3QioM/n+++8NRfXee++1CRMmuDpQmC9b66YWQteFAO0aWZ0/f777kLj88stt+PDhiXa8rrQhbMMRAG9+fIx16tTJ2Jm1cuVKR0h9DA/qbzc8h5BCCKgP7tOnjz322GPWuXPnxKGkirMpbfVlQWEpw1rg60uNDLJvvPGG7bDDDm7LMc/a0XPyySfb8ccfbwsWLHC5+43Pjzd79mw79NBD3UsIf9ar6AsPASOdnmnUOjju2WefdXRZ/0I8eKLCiZ+qn16K0Nfpuy1atHAjPk8//bTjB17UMJyH90/lSRV/mU7Xg6qYU/X/5JNPOkWYUbhXXnmlWBweMr385cG/5FO2nyd+6jQ//vhj23nnnZ1sd+zY0ZYvX+7wVjpsP21wr7/fkRz7WOHHtPiOO+7osK5bt657Xku4g3xvtLwhs5jjjjvONttsM6tatWoxrP16SYXbbzvJ3KrzoLAIiVLYqlSiSgFIlkyKCaMLZ5xxhpsWIp5e5Iyu1K9fP7EtkviqJIRBXwyzZs2yAw44wO655x6XjTpMHiQ0issaFiks0MeIpntI8T8pLOS5YsUKl1vbtm1dR/PMM8+45zg/esYOZv0I+HgJM3X01Lnqv3fv3glixENWFD8REBwbhIDfLr/88kurVauWk+0HH3ww8SGyQQRD5GIIJJNP+hQO6Ntzzz0d1g0aNLClS5e6dMQnXP1fMWLhYYMRQL4xp5xyiv3f//2f60vUj/vvnQ0mXEYJxF9QWP4koDQYv5Hpha0XyC+//GL77ruvPfHEEy4H/BWfIeVjjz3Wbr/9dheGvyoEtwSEYf7rrrvOmjdvbtdee601adLEGjdubOedd15i/YqUI6aEttlmG9ewEbo2bdpYo0aN3EJfFvteffXV7hm/VPzgD7rXXHONs8n/sMMOS3Q0LBwW/5SBH2n0U7pU8FYRaIKTMBN+4MmPhdiM2P3tb39zeONu2rRpQmZUNxUBh1SWARn0f35etB/aInJ80kknJdraQQcdZIwkgjfxlV5pSZfqtqe8MtlGjq+44grXXyGv6rPA8+9//7tb+7fLLrsk+gvhrf4jk8ueDryDY6tWrWynnXZy6yS32morJ9PILnWzKXmEB6ZeMUFhcTCU7h/KhJSOZClQNKSwsIOHzoy5VwxhUkT++OMPO/jgg43hZAw0SaevBW1V1gjF1ltv7daynHvuuVanTh3bcsstHW0W/cm88MILiTUsTAvox2JdFvvyzFBfKn/KE1t5YpOnH5bMnUq+KgLtZJjF/SgnsoEdx70iYFDeZfDxlTzDA22KH1hrEXycNz8t7nh4eC7eFwlfbL7wwUwbDbDxkz9h4A6GwjngWRzPDcVDMurb5Ymt8irJ1rrMoLDojV8KW8PCJSktKCQa8Zg2bZpTSh5//HFHGYVECguLcY8++mi31ZlAja5gy00eX3/9tVtky+gJaRT35ptvdg2VRbhScqZOneoUIEZ1aNiMtvz1r391jZovb75SsFP1Y84TxUr0yY8fPCh/+fk26fgpXbCT15FwKgkrvoh4gVLvdOaqC2RBdRCwTY6tj4twjvuBI5iCLzjzww+sWVSPTPtpgnv9WPsYgScy/I9//MNhyTNuKYaEUTeSZ9z48fPpBPeG4R7HS/0G8izMN7Vs03+xHpR348rCpTZj9SSr4t6G4d9aCEg5YXU624y5Vn7s2LFuJwbucePGOT/uFWF3BqMey5YtMxQWpkQeeeQRR9MfYfn111+Ljb6gdFAZykvPYkb+2FJoLrjgAjcNMGPGDBdNisv06dMdT5z98tNPP7kfW6sZ8cFO1U95gQN58Kx8lbfipIqHikx3XdgRRn37uPM8ceJEVw+4VQcVGaNUlU2yDI60d9ovco4/7Zx2rzip4qEy0QVLZBe8+RBT2fFnqh1/MMfGL8j2xvfryDM4gjt4gyv4yl91UF42vPg/rV0KIyzSCkqwNSpCBTZs2NANtW+77bbuq4ovK74COP+Erco1a9Z0Ix8PP/ywoUgceOCBxigIxh9hmTt3rh1++OF23333uTCUEF9hIU8pJnG2NILDupZ//etfxvQSpqT48fR/9llKk8rhK0/i36eNAiXs5C9FTGWFhujKVlzfVjrfrzK6hSd4CP94vfuYxjHyMVad+X7x+OF5DQLCWXjJJobv5tmPS53Fw9dQrTwuYSLbL7n8JN+yhaXCtevRx5P+SM+0C6Xx6VcWt3CIl1f+YBU3wlb+iitb/th++ngdES78426fxsa6g8KyHgRVcVTssGHDbNCgQW53z2effWaffPKJYXOAG27s/v37Oy0VsuwgQMnhqwyjMwSYJsJ/xIgRzl9CQ17KjxXaTAOhWUo4EAgJTaNGjYxRlpK2RjvCKfonHuFHvGOLf8rpCy/+KgMsEVfPxJMbW/RUVvyUX4qKkxFk14WDj5tfGJRb4ak4eham66Lr0wru4ooJ2ArDZNiAs8L9l2qyuJXRD3zibR8cwMrHbl3YlIQrMo2Jy/q6aGV6mMpKOZA75BN8cUsOFaY2rzTCnHDSyODv+5FO2PrxFF/56ll2srgK21A7KCylRCxe8VS2KlwCQQVTOarUN99801jZrm3G+LNNj73uJ554ojuAiuxJo3SixdQSZ7CwQluKjkZX3nvvPTvkkENs4MCBjnvSKl0pi7PB0ZSH+ISA8gQHucFA5cdPYbL9cN/tM0R6pcW/pHh+msrmFt6yKb9wx5bbDxdG1KHqAz/frTjBLo4AGMlIPnlWe0BG/TiE4ZcMf9GpTDZYyPiY+Jjh9jEDWwx4Kx5p/TjyV1yfttqA8q3oNmX3y7++8vrxhSNp9L7BHafnxyOcZ58OfuCudxXPZWmCwrKBaMYrR8lpRGo0slEo2CbGlBHbIVnPwnZmppE46A0jAeAwKrZNfvHFFyLp7h0i/sUXX2y33HKLsdiWM1nwY33Md9995+IyVFoejTPeccA7fhJqafUwBQYqW6JAnsOnVVJ80SgJc49chXeCl4bEfcx9NzjxjGGnmdwCxx/5Ut0gt3IrXrCTIyA5B1sfM78OSKmwILdrcIzLorCkz5BbuMUxXENljUtp1vis7YrnuXaMiukDjvxo2/xkwEzvJvx8vHnWOWGKj630fjq5ZSs+9P16UdqyVF6CwiK0/4QtwVAlUYGqRHVijK7svvvuiS157DLgAkQMFanK5HJDtnQ99NBDLgzaixYtsptuusntSCCMFfLYjLroWH5GbETjTxSh1ElUViXwhZMyE+7jwLMM4fCocD8u/vGOxQ9XGtEK9hoEJGPy8bES/viBsZ59N+n8NKIT7OQIIMfCC6UFN5082PJT2/fjBYzXYCnshInaPdj5/cOaFNELU7jyAhQNH2/F92n4bqVRvIpoCyPKVtrySqFYl6ICPdUTdEVbtsL9Zx3LQZjPF88ba4LCsgEIUnE0lLihsuIvD+IpLjt3XnzxReOG1wEDBrivX9GQMHz77bcu3L/QUOlZJ8OZLYyucN4Ki3YxSks8X2BEu6xt5cEuqNGjR9vChQtdGX0+5GbdDnfbMKrEIuR3333X7Z6CJ+jwo1PBMKrE/RXEv/vuu+3HH390/ip/eZXPZZqG/4QDBwmyLoqF3BzFD67c+XHnnXfaV199lZA31cHgwYMd/sQhHeur1JmAv16sqtc0LHpasSS55VRpMKUe+Kk9Ck8xLVxlyz/YEQKS67ffftsdsElfgZyqL+DeNH2YkULxmRJnHSDxOOdqzJgxJfZ/lanv8OVMsio/3jsffvhhAkPJoMJ55gRn+hQ+msEXnMFPuNOvKD53DtFfE/e///2v282FAiQFRX2Q8ikrOygsG4ikBMFPhp86KyrKryxVtl+ZqnQJgGxfOIiPP37Ex1Yeft64k/EUj1MWz9LE6aQ5TZctcBgJqcrKlsNjjjnG7eNnrQ07qBgZ6t69u4svvHjgJbrbbru58L322stNn3HE/Oeff16MtnuopP/0JcSJqtxNxYgdO9L22GMPd9YPZyfQcaMAqg5QGNmlxhkG4Mt5C9SBcJUM+mkqKbylKrYUPTpysARXzjwCe25UZ/stRu22VEQrUSTJJUVWv4aNOfPMM93oMTKNzNIPINvc18RUud+/8QzmnM9CHNx77723O7NKcEq2Zcu/otvqhymn8MYGB+5hOv/8890aSj8ceSWcDSDIMztgsbfaaisn4/4SBeHHJZTgz1k4//znP93ZRPvtt5/b7q842Kpf8eKH/Vl3UFhKiZwqnkpQRVDZvpD4z7wI/LBSZlOscaqiseUWHYQMPsqjUSpv9uVzGzAdNrucOJcGQ7mJo/JyzDMvR0YBMG+99ZbrWDjSXOfG6J4KTYUxegRm3J/EgmTW/Xz66acuPbTLo5wuszT7J1njK5KOmXuCwILdY+DFlODixYsd9sJ/5MiRrjNn0TZuzEsvveQ6mauuuipxqZlop1mR044d8EYGwZwF88g/uwUxvEC5nI/rEBhJjRu9EOL+lfEZHP12DDYYFD6O2ud2evxYa8WFkuCt+OCPP8e0cxouX/cokZzLcuSRR7q7nb755ptisPppiwVUggeVfciQIe5qF/pjdpYKcyAAU8wPP/zgPoI4mZ1zhcD1+eefdziz/IA+Roadq2eddZZTMDnMjT7k9ddfd898nNJPYUS7rPuYoLCoJiqRjTDrR7Fx87KTkGFL0GSjgXMtAILPj68ihBtDfNEj/r///W83AuMP57JjivU7aOcyHMDH1xRKi9YCEMbLlTxoLEw/YaCf6UY4Uw46DuENZipf3K0OhlOPWcDNsC5GmOMmDc8oMJg77rjD4adbuwnH6EZnfTWpzlxg+FciAlIEmdZlhIvpTb8uufcGedVCep+Q6tX3q4xu4SAbTPUiRAnkHiH/1mswEu6k4cdBnYwA8NFEu5BcMzUE/mxK0Cgw6RVeWfD2+xPKzOg1o1CMBrL+kY8VYer3PyiL4Ed/ofohPdNDjKRICcGPjSScQvzqq68m+hs+MrnkFxpM6Ql39UdliX9QWMoSzTSnhbBKqGX7DT8Z+xLw2bNnG2soUEL4yqGT0TA4tPRiRTNHsSEuhjB1InQ0J598sjulkrDLLrvM/fyzZBB2Rgzq1avndlbxlYXxG5LzyLB/lCteBp7lB856Vt1QROE/dOhQp9wx38/aIabjmPaRQkdc1QEXxvG1xNcnhrzVeTD6dfrppyfWBogv8eEShH8JBFQnWVlZblgdpU84a5qIeuD48pdffjmRLjiSI8DIqmRNso088tHCCBUnqSLbCqPvkJt47LbUtltkGvldsmSJ7bPPPm6Dgvoa5U54ZTDClLLKTb+qPpspehQW9QN+PPoEroqh38XQ/6gPuuiii4wf6VAwGUXp0KFDIpx45MeFvowAt2/fPhEmPhzRMvoXFJYyAjLdydDoJYS41ZB9hQU/dQ64FV9udQY33nij1a9fPzEEjjCrE7/rrrvsqKOOcl9DYEKYOna0b074lTJDI6GxqBGRn/g69dRT3Y2tmjqSf7rjvD7+hGlpG7PKzSJPTla+9NJL3RyzLn5jyzvTE3TiwpEvpgYNGtjvv//u2CEvhXGzM8oMx15j4IdfaflZX/kqWrjqixOlGSHkyxKjNgRuKJCsuwoKS8m1jxz7MkafwDNKCi86LoPlK32rojuD2rVr5zYqgLvaAKMFTB2rP1E9YPNCpl+SMiNOlFbPFd32cVbbpsz0EygePnaqDz5AmeJXH0F84da6dWs74IAD3PQcfTxtgIsISav0sllbRx/Ps94V0FIbKgvsg8JSFihmAA29lBDE0giQL5CKL+WBM2EYYeFOFQzhagh0KCgiGkYkPykzLFjk/BhODMYwisKXlRoHeUph4muKOVflqUbhEmbwP9WDiuCXC5yENW49Y7NGgiFXFsSxQp+FzU8//bRb9Ib/K6+8kkjL4lwUFq0xAlNoYDjrB9y5IwRDmM+D8wz/EgioPlD+mA5ivl5hSVbjAAAgAElEQVQG3JBd1l6w5oqpTJmAqZAobquty2YBP4s3kWFGYFlP0aZNG6cA4scicfUtLOwkjqaOoKyXLKO6yLammYS/6q84FxXvqaR2rPKfd955du655yb6AfwVxpQm17xI2aNuwI9fq1at3EcmdcCPKaJnnnnGhSm96nLPPfd0u4bkD8rqd8oK8aCwlBWSGUAHQVJDxkbIJVwIndx+UXzhldbctm1bp5QwfIuh01DHgcLC6AvzzRjyUDq2v/F174+w8HKVUJOXhJ9dSGj+6pzEtyOagf987H32k5VLftj8wI/tg3Q6KHvQEt6c6UOHz0I4LWhu3LixqwMpLH58vpjYMeBP5/n8BHdxBNQmGAngCz+usFA/DIfXqFEjKCzFoVvrSVgSoHbNkQ2XXHKJ2yYuxYRw8EbpZvpBHy3sILr99tsT/QnxlAaFhb4krrCoLa3FTAX3oE/1+/dzzjnHLrzwwkRfS/GFjRQW9Sl+GMoj/QU4M8XEgnNGEv26lJtRMupLfTh0FFZWcAeFpayQTHM6CKeEh3MkuDyRRWoIJIfT8WO0A7/bbrvNhXfr1i2xo4T0EmhGWFjZ74+wKIwOhc5DW57JU2Gcs8CKft2hxChNy5YtE43IV1hOO+00N/2hNSziPc1hXid7PoZM8TB1A9bgST2APfUAJiiFdMAsUo53wmQCLXXW//nPf9wXKruxMCgs/i4uP1+GzelYNCUE5oQHkxwByR2yjlLSq1evRETCwI4DHhl9ob0EUzIC65IzXq4ywhysa9WqlRgpZJ0KU86sWcGQRun4SGI0QMqNaK0rT8WpKLbk0S+z8GFLM1NC+jikzMTjx0g2/bn6acKkdNAf8ZHJ6AtTn5zSzmGo6pP8uEwdcaGv6i8VuAaFJRWopiFNCScCzA4fhlu32GILZ7NNkJXf2PjrRF12++g2aNLpBcmLlTljLeqEtr6Y6FCOOOIItyBUwqyGwPAvnQ6H5GFQbFhTIQGHjvJgPpuGpEWlhGW6oQx0GHQGmuIBa61HAX+GXP26YZEhCz5lSC+81KmcffbZLo0UFhbdsjVcu7SIp46KERbWGAWFRYiu2xbWmvZht5sMuBLOYsWwhkWolGwj//F2HH8mtfoApthQEiXH9B28ECXL2HIj0yj9mtaATjLaJXNX8UIov/BBYWGERaPdPj70s0wJCXfiSO75sK1du7YLQ0mhf/J3ExFPOGvKTmnJWwpTWaEbFJayQjLN6SBUEqz333/fWNTGYWNMNXCKLqdKPvDAA+6ZkRBOnGW6QYoIxZNWzdc/9xlxLgsGAZWQsv32/9s771A5qv6Na2Ivrxp77GLHXhAbRgXF3kssKKKCPfbeMIgVo4mxJia2YI8tKpgYYoPYRRG7xt47/vOD8+NzfJ99v3fYvdncu3d3dvc5MHdmzpz6mblznv2eMlhO9EsUsUK+vEhQ+FgVMKHjyJ9ZQ+o+UvqMr2ARKUyV+sWk9HPENvwj/uxp6Bi8ycv32muvzQPVYAF//Lgn+DM9ma+AswIlLwkGtOnlLRFInz+/QnmpsPowDhFIN5FWTSY/8oUllit+NXWSEBzIxwFuPHu8eHnh8wLXbAq9jPk/QXQWLSzEtfuXgFiw1zGWKWZd0cVAY6lr4s1UZ6yFEuxYb3lfaDC53gl8KJaPzGI9VKOrtMid578bHXzECCssXW8SMBLbcOE9y+KSjIuTgx/TlRnvRjePnnUG7+633355EK7SJg7vKRbx4x1F2HhNaTZib8HSCIpdkoYaST4xgIUgChYecL0YUPNYCbSQE6KH2S1YcVhCHkd4frUyCJeZQ7LWcI2l5omPkNKDT/hOdtQz1pFz8UTQMZ0QJpMmTcoY9EuSX5X4M51cv54YK4QfHBWOxoGF+1jLhWm4OLHtZK6NqJvuAwKQmVpx8T3Sl7VMX0832+rU4/MtpggSrFMscIbDnx8usEYEspaI/OmSoGGl+4cfPXp+GWzL885zrwaZvHQ95psT66I/YoAVlvey+Igpe96z8OMHkt7xsGbsCs87S1rIIQ5ZuZwxMfoxy48mwpFGtL4oTiP5W7CIqvezJSBrB7/Q6RIqDtyUCsdSwMOLRQWBgrqff/75eyyspX8MZg4Rln8OFuRCoTP+gm4nBt7h9E832wJ2QABe2PoHZ8/GC5xFy7A6YRbnVynfBsFKRt8zAlJWK35hkgbjkWDOr9IpU6YkpokjGGOXhrgqvw7AN2BV0PPKr1SeV8YXYakcPnx4tjYy1VMWwlgI2Ipz9O/WYzhGJgy6xTrCOjaM5WJhRJY64FnnR46shmLIOh8shMbzPHny5NzY8i7CCqBB5t3Ktlq9xQ2BgWiRYMFf9wILFtYsuqex7vINIbqIsJjwPTKlofc7liy6hhBA3AOs5lh4sQrrB5LyqVam/vhZsPSHXpfF1UPICoj8A8gqwoMcGz1e3Pxi4h+Eh55f9Swpj+PhZ6NRZUPJM02XgaAM6KIxYLpudDHt6N9Jx6ojex3DiWO9MBhPxIuakfq85HnBxFkr8CC8zOK8WJhuy68f7gHCRS4KI/l5X5sAvHBYp5hai1UAttwHfmHK8T+i+4dfPFaYbt0XWeicAfqIbp5RuDKAme+OiTnvF71jEOYM+mSFbMa3IMrpflZDCVvFE2flo/Nu2uvdgSBBZMsKKwbiinjBUsW7gu7koUOH5tmcXI8Otox/w6KLqERoMqNTP5hi2IE4tmAZCKodmqb+8fk6Lf2bnPNA8xCz6Z9D4Zjhg6ghfPElIkTyR7jwCwmrDS8f0mUjTaWrOJ24p47iFusHn+jPDAn68GHFix5WhBErhSc9hCNTnZnhwv2S4CT9mGY8jnn7uCeB+CwyzgoLIFM9GQ8Ew+I95NzufwT0nGnPFVkE8aPrgeeVdwDseLZjWJ5fWboIyzPN+0WzhkiP/wM58xeJlPgGkFYUh1F8FxCK9wa8GCPHPYAvfjjCcx+KPAnL51lkeefeRP7Koxjvf6Wa8yMLljln1pUxeBD1ABcB8DDHFwsPqB7yeA1/Hmo9wFzjXI1sTEN56B9J592whwOMxIN90W92HBSXcPGYc/HmOOYzuzS7+bpexPH55YVcZFuNkf4Xql3rFr8iJ4SK3gMwKF6fHZcYtxbfGGZ26XXLdT3Hsb5iL4ER3/PRcqU4cOX/QK6YZvwfIUwj74MFi6h7P8cEeBD1sHPMA6+HM17TQ6uwRRES4/Hw88ArbDGdOS5kG0WIdaX+YhCrIL/IrMgXhroPMVw8Jg7h8FOaMR8f1yYQBZ9C6SUf2Zur6Py755kUp3iFbgpYwY59MRzPKE7c4/8J/nrWY5qRfTyOYbrpWFyLLOQfGYp3DMu9wWlfZKd7WM2/6NefcwuW/tDrsrgICb00eJjZ4ktGD3h8ocgPVMTVP0a1tCJOujP0j0MeihfDdPpx5NgbA90TMY73Bj84Rn66Ln69pa0w3v/LUc8zzHGwlZ8Z1SYQnz8aN/1vF2OIpfbxevx/wF9p8vzG8xinN/9iuG4559kVs1hn3snyJ4ye8Rgm3rcYNobhWNc4rnYvi+HrPbdgqZeUw82WgB7M4otFEav5F/1i46r0FL+T96ore72Iq9U38orHiq84Oi/uuS4/jnmxxHPF9746AViJV3EfWfKy1/XqKXWfLzyqNYJFEvHXuv4XIsvINvrHY9Isnhfz6aZzsYhCIooPWIi19pFh9Iv+RYb1hivGq/fcgqVeUg5nAiZgAiZgAibQMgIWLC1D74xNwARMwARMwATqJWDBUi8phzMBEzABEzABE2gZAQuWlqF3xiZgAiZgAiZgAvUSsGCpl5TDmYAJmIAJmIAJtIyABUvL0DtjEzABEzABEzCBeglYsNRLyuFMwARMwARMwARaRsCCpWXonbEJmIAJmIAJmEC9BCxY6iXlcCZgAm1NoLioFZWJfiyupcXftMBZXKSsnStPPWJdqYsWE4v+LCYmf8KIRzvX3WXvHAIWLJ1zL10TEzCBGgS0wqdW91TDrO9W6bxa9E4RLaobAgVREoWKrhX3nVb3Yv183l4ELFja6365tCZgAv0gQCNdbIQRLWq8ES5//fVX5bxTLAxxuXu+0xXrK4uKvu9VrLOu9wO7o5pAQwhYsDQEoxMxARNoJwJRpFDuopApnrdT3WqVNQoRCZZaYe1vAmUkYMFSxrviMpmACTSUQK0uEIRLUbzQsKtBJ15v3UUNLeQAJ6Y6xWyoe7SgcI4Fys4EykjAgqWMd8VlMgETaDgBNcxqkCVi5E9XkK4pc13TeTvvqYvqgwjDIc5U5yheqombdq67y94ZBCxYOuM+uhYmYAK9EKBRprFWQ33mmWemDTbYoLJtttlmabXVVktjx47NYQivsLErpZcsSn8JQYL75JNP0o477phWWGGFtMkmm6SNN944rb/++mmbbbZJb7zxRo96iFsPT5+YQIsIWLC0CLyzNQETaC4BhIca7WHDhqW55porHXzwwemss85K5557bjruuOPSc889V+kOonSdYmmgHrKufPXVV+n8889PiLYRI0akU089NS2zzDKZx4wZM5p7U5ybCcwBAQuWOYDloCbQrQTU2NHw/f333+nbb79NNHyff/55+uKLL9KXX36Zt1mzZqVvvvkm++uY619//XUOxzHx2HOdY6599NFH6bvvvst+pIk/aXINodFfR/nZlNaee+6ZG+jHHnusv0m3TXzdw1hgLChsWFkQcK+88kq8XBE5PTx9YgItImDB0iLwztYE2omAfqH/8ssv6dhjj83dCUOGDMn7lVZaKS211FJ5W3LJJRP+yy23XN4WX3zxtPLKK6fll18+d7msscYaaejQoWmxxRZLSy+9dFpiiSVy+GWXXTYfE4/jFVdcMYejq4YuDFy1BrdehkXBsscee+QGevLkyfUm0fbhqvFDrCDiLFja/vZ2RQUsWLriNruSJtA/Aqzjgbv//vuzMOHX+KKLLpoGDRqUx0PceeedadKkSfk6YcaNG5fuu+++dOmll2YhQvjBgwenhRdeOF1//fXpwQcfTHfffXd64IEHKmHHjx+fEDTzzDNPmnfeebOgWH311dPHH3+c867W4NZbq1qC5ZFHHqk3ibYPV+THOYKFbjILlra/vV1RAQuWrrjNrqQJ9I8ADRsOocFgTQTITTfdlLt+/vjjj/wrXQ2iGkLCv/jii9laQvi555477bzzzrmbh2uEw3LDprEldAF99tln6YQTTkjzzTdfFkcffPBBzlvp55M+/lGXkCws3SRYish0nxCjtQRLMY7PTaCVBCxYWknfeZtAmxBQQ3/XXXdlETFy5Mg8loVGrygkEDespopjTATdO1hiECxYYaIjXcVnVo7y+fDDD9Oaa66Zu40aYWFRnkpfY1gsWP4v/fPPPxYsekC8LzUBC5ZS3x4XzgRaT0CihF/iBxxwQEKssGaJHBYSnMa5cCxh8MQTT+QxKepCevnll3NYRI2ESoyrtBh0iyXniiuuyMIoR2rAH5Vrr732ylaihx9+uAGptkcSkTcl5pz7YAtLe9w/lzIlCxY/BSZgAr0SUCN/2223paOPPjrP5CEC/uoqUgLR79dff0277bZbtqwgWE455ZRE9xFOjaeEC+exa4iBtgy+xaLTSKe1VSxYLFga+Vw5reYQsGBpDmfnYgJtSQAhIcGyxRZbpH333TcxUwgna4jEh/b4I0SwwhAHscKGZUZdRcSXWBEY4ksAMW6F2UcTJkzQ5X7vSV9jZbpZsOg+iTdMNtpoo3yPitOa+w3dCZhAAwlYsDQQppMygU4jIIsEwmHBBRdM5513Xu5CoLGTYKHOOsZfcU488cQ8Kwixst5666VPP/0041GDyUkULdE6895776Xtt98+0aXUSCfxVRzDQvlVh1gm5a36quykIz+FkdjSNfxjugqnPdcUp1ae1fyJXyyH0pQ/41J0rGvay5896ffWJaSwiuu9CbSSgAVLK+k7bxMoOQFZJC644II8CPb999/PJZYoiY2zGjfFYRVZBtsiWLbbbru8GByRJQxU9ZiGLDAvvPBCuvrqq/NicoRT2orT1z154YqCRelVExCxfFxX+VUmFtLDDybiQnoxHudRfMR0lDd7xAPpxrCkiZ/y5ZrqQRyuwVzlUTiuVRMuCsd10iL9WrOEYljC25lAKwlYsLSSvvM2gZITUMPIGinMqKFBlaMxU4OmBpMGEvfQQw9VpjMjWFgAjtVtccShkYwNq9KR35tvvpkef/zx9OOPP1bi5IN+/lF9agkWiYNq2UQBQj1VVsLS8OPkV42N6lhMW/5KI+YjP/YKF6+Le8ybsKon/sRTOjFv/AlnC0uk4uMyE7BgKfPdcdlMoCQEaNTUGBeLhL82WUiwjiy00EJpgQUWyBaWzTffvCJYYuNLPDXEamh1rn0xv/6cqyEvChYEiBp1WYimT5+ebrjhhnTttdemm2++OY0aNSqxQN6ff/6ZiyAeTz75ZBozZkwaPXp0XhTvxhtvzGNvNMCYwOInkfDoo49mC9I111yTP7jIgGbyi4IQlsojcpJgEWumil933XU5Hcp5xx13VMqI9YdF/JgmXnSUhTpTd1tYinR8XkYCFixlvCsukwmUkIAaXRpPNe6xmPhjocBdeeWVWbBgXWHbYYcd8iJzXItChDQ5jw1yTBPxwLVGuVqChfRVBoW56KKL8icF+OwAi9ixjgyfDqDxp/5YjJgWjRjDn08NsLGaL6v18vVjlv6XACKPl156KZ100kl5RV8+V8CnDEif8HyugFlRDFaOFhxZfchT7H7//fc0derUPGuL9WrIn2ngfMRwlVVWSbvsskuaOHFieu211/J9YEXh6FRXCZZag26VX4zrYxNoFQELllaRd74m0EYE9KueBkyNmPZUQw0gAoSGfMMNN8xChYG6WFmeffbZXFuFi3EjBuWjcPFaI44lRooWligGJLoQBXzk8fvvv88r9CIqmGr9008/ZWsLYgOLy88//5y7rn744Yc8CwqRwicGEGoICH0LCdFw2mmnpddffz3HITwr+yJQEHgIHVgdcsghlZlY4kHdYUI5EUBHHHFEFkdYT+g2++2333I6lJXyzJw5M8/Q0leYWaE4OvGdnWCJcXxsAq0mYMHS6jvg/E2gzQioEY2iAz8aPxwr06rBnn/++XMjzBL9OAmGfPLfP0oHoaA0FJZr+ClMjNeXY+VfFCykJUEQ85J1ZP/9988ChFV76WY566yz0mWXXZZFAnGJQ/nVpYOgQOAgWugievXVV9MGG2yQrR4qtzgq3qabbprDb7311lkkKV3qr41uIKaWky6DmhFVOMpOWSmH6vjGG2+kddddN4et9lVqwpIuZa5lYVFZvTeBMhCwYCnDXXAZTKDNCNDYsUVHg0nDyRoqdFPQqLLRuMeVcdVQx7gxrShQZAmIYftzrMa8mmAhXdWLfHEar6J1WxBiCBU+3BjHqKhMivfOO+9URNuwYcOyZYUp2hp3EhmoTIw/+c9//pNnVt1+++0V8aMywXfWrFn569dw1arByjvuZSVCKPKRSllY8C+yhrfGsPSWZkzfxybQCgIWLK2g7jxNoAMJqOHFwsJXlhmTQcN61VVXVSwnsbFsBQKVUYKl1tL8EgnF8KrT2LFjszijDrFOHCMAsMJgUWHcCwz4ajXjUqo5wuOefvrpymcMEEWy1nCNdBFDCBbGqjD+5csvv8zxJJLySRjgS7p0OTFG5t5779XligWG69QPISQLS1GwxLpVEvCBCbSIgAVLi8A7WxPoJAI0fjScNH4XX3xxWnzxxXNDzS/3d999tzRVLQqQegWLvu6M+Nh2222zFYlKUefYqHMOCywzLJZHeLZLLrmkhwCJQAiP602wUG7CRQsLM4xkASI+YVQWpcmXr9daa62cdsyTcqqsWL805siCJVLycdkIWLCU7Y64PCbQhgRo/CQGmBGkhnr48OF5kCpVUmPayuqpjHNqYdl9993T4MGDc72OPfbYSncQdaLuchIBdBets846FQ79FSzKgxlKq666ak6XMS/PP/98zlpihXAKqz2De7H44OTHMWVH2HBNFpbi0vxluGe54P5jAskfP/RDYAIm0AACWFZwLPbGFFsJFj5++N133+VrZWj8ioKFxfCqOcrKpvAaw0K9Dj300MosHgRArBfHiACsFhrwShy6hGIXT8xT1pApU6bU7BLSNOfPP/+8MjZm3nnnzTOL9tlnn3Tuuecmxs1IuJC/xAn5qozF8pIucTbZZJN8zyxY4p3xcdkI2MJStjvi8phAGxKQYBkxYkQet6EF4+hKYaotTo1mK6snASILSy3BojIqPDNzNB7lwAMPTHyJGqfrCh8FS+wS6o9gETfyQtwwduX444+vLMqncq222mppyy23TAzyXX/99fPYIaZUK74EDOnIj0G4nGvQrQWL7qT3ZSRgwVLGu+IymUAbEVBDyPokWCJoQFlojY3VYWtZFlpRRQmMORUsWIqYoi0LiwSL6q66cI6oYGxJ7BLqj2AhbQkM0lYdjjrqqDwDiDIxhRru2nOMaGTxulqfNyBN0sPKUkuwqF7em0AZCFiwlOEuuAwm0MYEaPRwjKdgBosaUKbTvv322/maGtxWV1ONvbp46rWwsHIsAoy6MS5HIoD6UH/VT4KlOIalUYJF/MiPKdLPPfdc5s5gWRacY5VbNha1Q7Qw+BmLC/Wk7sQrlhVBacEist6XmYAFS5nvjstmAm1AQCLgmWeeqawRQsOOFeObb77JNVAj2erqqKxzKlj23nvvLFao1+GHH14ZSFzLwoJgaeQYlsgvHosn5cBSwiq3WH8OOOCAvJ4Lq+cyWHjttdeujCWSwCQux2wWLCLpfZkJWLCU+e64bCZQUgI0kGo4NX6F7+SsvPLKlYYdASNH2Ni4c674CtOMvQRLvV1CqhtdQpoldNBBB1UG3cY6qI7Uk6XyWYcFgcPGLKG40BxhZZmRgHjqqacqg24vv/zyyrotXBc71rhh6X9NZ1ZcsVN56J5joToWoxsyZEhei4U1WXCEUTisNDCRYPG0ZpH0vowELFjKeFdcJhMoIQG6Dmg41dBSRAZtqlGfMGFCpcGlkZw2bVrVWsT4BKDBVANaNUIDPXsTLCqDVoMlLMc4uoQGDRqUxQfL7scuIeov4cCeOFg69HkCBAsCRJzIRyxJG8sILs4SGjlyZGVVXK6pHO+//34Whfo2U4743z/kTZlJW+Vh0O1KK62Uu4ZYk0WO65SDPaJF05otWETI+zISsGAp411xmUyg5ARoQBEvNHpsv/zyS9p+++17WBRooAmjcFRJDWXxuFnV7U2wcI264FRmhY8Lx/ENH+qLi8JDTIjLN36YqSMLy4UXXlhZCyVHDEJN4gKL1NChQ3OcosChXPBEdDBt/I477lAyuczkiVP52VN2Pt5Imowt0vRyhSU8eVNuCRbPEqpg9UEJCViwlPCmuEgmUDYCasyj4KCMavz4Jb/55ptXGujrr7++YhVQI0qXiAQAjaT8JWyaUWflX+wSwl91weKgY8qJ22+//SrTmhnPQpcLTnVgTxxtCBbGjUiwxIXjFIf48ET04BAsfA26aJFR2YjHFHHExxZbbNFjujjX2Cgvm8rPui100/GNotglpLJj3aEMXocl3wL/KTkBC5aS3yAXzwTKQkCNYGxwadxxrL+iMR5bbbVVtgTgT9iiyOnNPyc2gH9qCRZlGRt7wqq7Ztddd63Ujy4hfSWZ+hFOTIjPOXsEi6ZC87kCseKawosP+bM0/zLLLJMFC7OKih+MJMx7772X+GI0oqbYLaQ0Cad0saogcJgtpG8PKZzCUC6NYbGFRU+C92UkYMFSxrviMplACQnQSGNZYKl3ZqLoFzsNrb7OjGhh+u/o0aPzOA66TrAK0HAyrkMCoFXVqyVYEFUSZCob9aWeWIY06JZ1TljfhAGt1AUexGVjiXvqiz8fL1xiiSUq417OO++8PGMqWm/IRzyJhxVnkUUWyWIEiwfigcG7jJchfSxRX331Vf42EIKFheIeeuihHuWmDAgRWW3OPvvsXN7ixxSpqwQLwqhWl5BYeG8CZSBgwVKGu+AymECJCaiR5xs6fCWYX+yMo2DjfMEFF6x0l9Cgs2Q8DSpdEfyyZ10Qvn9Dd4dmDtGo0wg326kuxS4hyqHyaFE4lrunjqxpQr2okzaEBfVClCDYcKeeemrmQRyt9MtaKIi4hRZaKKfF156Z5YNgQIAw44jwXCcPwhKHfOBKHnyYUANmESwwx8pywQUX5PEp999/fwUj6aqOJ510Uk6H8TBYdXBcQ6iwEVZCqJaFpZKwD0ygBAQsWEpwE1wEEygzARo23NSpU9ONN96YxowZky0ot912W96PHTs23X777Wn8+PF5f8MNNySu3Xrrremmm25KXGfj+NNPP61UlUaz2U6NeVGwqBGnPKrv9OnT07hx43K5qQ8bg12p5y233JI36q2ulpkzZ+aVfakrYblGePbUnTiwe+uttyqi4rHHHstx8CcMzIhDWPImLfZYp3Cvv/56Ouyww9I999yTmDE0ceLExFebzzjjjHTyySenc845J5122mnpoosuyvcKgYgwwlXjjZBhs2DJiPyn5AQsWEp+g1w8EzCBxhGoJVgal8PApYTgkMCQ+JC4evXVV9OMGTPyRlcSg6DVLYQVReFj6fBnw9pVS7BUixfT8LEJNJOABUszaTsvEzCBlhJoZ8ECOAREUUQUzyViZgfagmV2hHy9bAQsWMp2R1weEzCBASPQ7oKlFpiiSJGw0b5aPAuWalTsV2YCFixlvjsumwmYQEMJdJJgKVpW5hQUImd2XUJzmqbDm8BAErBgGUi6TtsETKBUBDpJsFQDG0UMx4iS6BfjSLAw1qXWGJYY3scm0GoCFiytvgPO3wRMoGkEOlWwFLuE6gFqwVIPJYcpEwELljLdDZfFBExgQAl0qmCpZUXpDaYFS290fK2MBCxYynhXXLEWH/wAAALySURBVCYTMIEBIdCpgkWwEC6MS4kCppb1xYJF1LxvFwIWLO1yp1xOEzCBPhOgAWfTiq+77757XgV2ypQpPdJUOHnWaux1vd33EnCbbbZZ5lH8llC718/l7ywCFiyddT9dGxMwgV4ISLDwMUOWv99pp53yyrF80JBl8idNmlRZcE3JRGuF/Nptj/BSPb799tt0zDHHpAMPPDAdeeSRafjw4ZWPLrIAHY6wnS7W2u0eurwpWbD4KTABE+gKAjTCWBRoiHfccccsWBAtfLtH3z86/fTTK19JVgPfKXBUn3fffbciUAYNGpQ56Evb06ZN65Tquh4dSMCCpQNvqqtkAibQkwBCRYKFK3xtme/38K0evn3E93rY850fwqlxV7yeqbXnmerE16f5ZhH1pf4c872jUaNG5a9DUzuF5bg4JqY9a+9SdwIBC5ZOuIuugwmYQF0E1BCzpyHGsQ5J7DKJDXQnCZYiIOoc60p3GVzYdFyM43MTaCUBC5ZW0nfeJmACTSMgsaJuoXoz7oSxHKq7RFqtuhcFWlHU1IpnfxNoBgELlmZQdh4mYAItJ1BNeNCA00jLKYwaavm3+16CRfWgzlG86Ljor/Dem0AZCFiwlOEuuAwmYAJNIRCFSL3dHsXGvikFHYBMJMxivREqqh/XOY6ibQCK4SRNoM8ELFj6jM4RTcAETMAETMAEmkXAgqVZpJ2PCZiACZiACZhAnwlYsPQZnSOagAmYgAmYgAk0i4AFS7NIOx8TMAETMAETMIE+E7Bg6TM6RzQBEzABEzABE2gWAQuWZpF2PiZgAiZgAiZgAn0mYMHSZ3SOaAImYAImYAIm0CwCFizNIu18TMAETMAETMAE+kzAgqXP6BzRBEzABEzABEygWQQsWJpF2vmYgAmYgAmYgAn0mYAFS5/ROaIJmIAJmIAJmECzCFiwNIu08zEBEzABEzABE+gzAQuWPqNzRBMwARMwARMwgWYRsGBpFmnnYwImYAImYAIm0GcCEiz/D8RpVM0IU+loAAAAAElFTkSuQmCC" + } + }, + "cell_type": "markdown", + "id": "lined-voluntary", + "metadata": {}, + "source": [ + "
\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "primary-spending", + "metadata": {}, + "source": [ + "References\n", + "----------\n", + "\n", + "[1] Bi G, Poo M (1998) Synaptic modifications in cultured hippocampal neurons: dependence on spike timing, synaptic strength, and postsynaptic cell type. J Neurosci 18:10464–10472.\n", + "\n", + "[2] Wang HX, Gerkin RC, Nauen DW, Bi GQ (2005) Coactivation and timing-dependent integration of synaptic potentiation and depression. Nat Neurosci 8:187–193.\n", + "\n", + "[3] Sjöström P, Turrigiano G, Nelson S (2001) Rate, timing, and cooperativity jointly determine cortical synaptic plasticity. Neuron 32:1149–1164.CrossRefPubMedGoogle Scholar\n", + "\n", + "[4] J.P. Pfister, W. Gerstner Triplets of spikes in a model of spike-timing-dependent plasticity\n", + "J. Neurosci., 26 (2006), pp. 9673-9682" + ] + }, + { + "cell_type": "markdown", + "id": "shared-spice", + "metadata": {}, + "source": [ + "Acknowledgements\n", + "----------------\n", + "\n", + "This software was developed in part or in whole in the Human Brain Project, funded from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under Specific Grant Agreements No. 720270 and No. 785907 (Human Brain Project SGA1 and SGA2).\n", + "\n", + "License\n", + "-------\n", + "\n", + "This notebook (and associated files) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.\n", + "\n", + "This notebook (and associated files) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dutch-duration", + "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.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/tutorials_list.rst b/doc/tutorials/tutorials_list.rst new file mode 100644 index 000000000..0310b9dd3 --- /dev/null +++ b/doc/tutorials/tutorials_list.rst @@ -0,0 +1,30 @@ +Creating neuron models +---------------------- + +* :doc:`Izhikevich tutorial ` + + Learn how to write the Izhikevich spiking neuron model in NESTML. + +* :doc:`Active dendrite tutorial ` + + Learn how to model a dendritic action potential in an existing NESTML neuron. + +* :doc:`Ornstein-Uhlenbeck noise ` + + Implement the Ornstein-Uhlenbeck process in NESTML and use it to inject a noise current into a neuron. + + +Creating synapse models +----------------------- + +* :doc:`STDP windows ` + + An STDP window describes how the strength of the synapse changes as a function of the relative timing of pre- and postsynaptic spikes. Several different STDP model variants with different window functions are implemented. + +* :doc:`Triplet STDP synapse ` + + A triplet STDP rule is sensitive to third-order correlations of pre- and postsynaptic spike times, and accounts better for experimentally seen dependence on timing and frequency. + +* :doc:`Dopamine-modulated STDP synapse ` + + Adding dopamine modulation to the weight update rule of an STDP synapse allows it to be used in reinforcement learning tasks. This allows a network to learn which of the many cues and actions preceding a reward should be credited for the reward. diff --git a/extras/codeanalysis/check_copyright_headers.py b/extras/codeanalysis/check_copyright_headers.py old mode 100755 new mode 100644 index b90b8f27b..3efa598e5 --- a/extras/codeanalysis/check_copyright_headers.py +++ b/extras/codeanalysis/check_copyright_headers.py @@ -42,7 +42,7 @@ EXIT_SUCCESS = 0 EXIT_BAD_HEADER = 1 -source_dir = "/home/travis/build/nest/nestml" +source_dir = os.getcwd() exclude_dirs = [ '.git', diff --git a/extras/convert_cm_default_to_template.py b/extras/convert_cm_default_to_template.py new file mode 100644 index 000000000..d4e00929c --- /dev/null +++ b/extras/convert_cm_default_to_template.py @@ -0,0 +1,125 @@ +import os +import argparse + + +def get_replacement_patterns(): + repl_patterns = { + # include guards + 'CM_DEFAULT_H' : 'CM_{cm_unique_suffix | upper }}_H', + 'CM_TREE_H' : 'CM_TREE_{{cm_unique_suffix | upper }}_H', + # file names + 'cm_default' : '{{neuronSpecificFileNamesCmSyns[\"main\"]}}', + 'cm_tree' : '{{neuronSpecificFileNamesCmSyns[\"tree\"]}}', + 'cm_compartmentcurrents': '{{neuronSpecificFileNamesCmSyns[\"compartmentcurrents\"]}}', + # class names + 'CompTree' : 'CompTree{{cm_unique_suffix}}', + 'Compartment' : 'Compartment{{cm_unique_suffix}}', + 'CompartmentCurrents' : 'CompartmentCurrents{{cm_unique_suffix}}', + } + return repl_patterns + + +def get_trailing_characters(): + trailing_characters = [ + ' ', # declarations + '::', # function definition + '(', # constructor, destructor,... + '*', # pointer declarations + '&', # references + '.h', # includes + ] + return trailing_characters + +def get_leading_characters(): + leading_characters = [ + 'class ', + ] + return leading_characters + +def get_excluded_substrings(): + excluded_substrings = { + 'UnknownCompartment': '#' + } + return excluded_substrings + + +def get_replacement_filenames(): + repl_fnames = { + 'cm_default.h': '@NEURON_NAME@.h.jinja2', + 'cm_default.cpp': '@NEURON_NAME@.cpp.jinja2', + 'cm_tree.h': 'cm_tree_@NEURON_NAME@.h.jinja2', + 'cm_tree.cpp': 'cm_tree_@NEURON_NAME@.cpp.jinja2' + } + return repl_fnames + + +def replace_with_exclusion(source_string, target_string, line): + if len([substr for substr in get_excluded_substrings() if substr in line]) > 0: + + line.replace(source_string, target_string) + + for exclstr in get_excluded_substrings(): + line.replace('#'*len(exclstr), exclstr) + + else: + line.replace(source_string, target_string) + + +def parse_command_line(): + parser = argparse.ArgumentParser() + + parser.add_argument('-s', '--source-path', dest='source_path', + action='store', type=str, + default='', + help='Path to the nest-simulator source code') + + parser.add_argument('-t', '--target-path', dest='target_path', + action='store', type=str, + default='../pynestml/codegeneration/resources_nest/cm_templates', + help='Path to the nest-simulator source code') + + return parser.parse_args() + + +def replace_in_file(source_path, target_path, source_name, target_name): + + with open(os.path.join(source_path, source_name), "rt") as fin: + with open(os.path.join(target_path, target_name), "wt") as fout: + for line in fin: + + for cm_default_str, jinja_templ_str in get_replacement_patterns().items(): + # we safeguard excluded substrings for replacement by + # temporarily chaning there name into a pattern that does + # not occur in the replacement patterns + for excl_str, repl_char in get_excluded_substrings().items(): + line = line.replace(excl_str, repl_char*len(excl_str)) + + for trail_chr in get_trailing_characters(): + line = line.replace( + cm_default_str + trail_chr, + jinja_templ_str + trail_chr + ) + + for lead_chr in get_leading_characters(): + line = line.replace( + lead_chr + cm_default_str, + lead_chr + jinja_templ_str + ) + + for excl_str, repl_char in get_excluded_substrings().items(): + line = line.replace(repl_char*len(excl_str), excl_str) + + fout.write(line) + + +def convert_cm_default_to_templates(source_path, target_path): + source_path = os.path.join(source_path, "models/") + + for source_name, target_name in get_replacement_filenames().items(): + replace_in_file(source_path, target_path, source_name, target_name) + + +if __name__ == "__main__": + cl_args = parse_command_line() + convert_cm_default_to_templates(cl_args.source_path, cl_args.target_path) + diff --git a/extras/models_library_generator.py b/extras/models_library_generator.py deleted file mode 100644 index a64b9f296..000000000 --- a/extras/models_library_generator.py +++ /dev/null @@ -1,119 +0,0 @@ -# -# models_library_generator.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -import nest -import numpy as np -import unittest - -try: - import matplotlib - import matplotlib.pyplot as plt - TEST_PLOTS = True -except ImportError: - TEST_PLOTS = False - - -class NestModelsLibraryGenerator(unittest.TestCase): - - def test_generate_models_library(self): - nest.set_verbosity("M_ALL") - nest.Install("nestmlmodule") - - models = list() - models.append(("iaf_chxk_2008", "iaf_chxk_2008_nestml", 1.e-3, 0.001)) - models.append(("iaf_chxk_2008", "iaf_chxk_2008_implicit_nestml", 1.e-3, 0.001)) - models.append(("aeif_cond_alpha", "aeif_cond_alpha_implicit_nestml", 1.e-3, 0.001)) - models.append(("aeif_cond_alpha", "aeif_cond_alpha_nestml", 1.e-3, 0.001)) - models.append(("aeif_cond_exp", "aeif_cond_exp_implicit_nestml", 1.e-3, 0.001)) - models.append(("aeif_cond_exp", "aeif_cond_exp_nestml", 1.e-3, 0.001)) - models.append(("hh_cond_exp_traub", "hh_cond_exp_traub_implicit_nestml", 1.e-3, 0.001)) - models.append(("hh_cond_exp_traub", "hh_cond_exp_traub_nestml", 1.e-3, 0.001)) - models.append(("hh_psc_alpha", "hh_psc_alpha_implicit_nestml", 1.e-3, 0.001)) - models.append(("hh_psc_alpha", "hh_psc_alpha_nestml", 1.e-3, 0.001)) - models.append(("iaf_cond_alpha", "iaf_cond_alpha_nestml", 1E-3, 1E-3)) - models.append(("iaf_cond_alpha", "iaf_cond_alpha_implicit_nestml", 1E-3, 1E-3)) - models.append(("iaf_cond_exp", "iaf_cond_exp_nestml", 1.e-3, 0.001)) - models.append(("iaf_cond_exp", "iaf_cond_exp_implicit_nestml", 1.e-3, 0.001)) - models.append(("iaf_cond_exp_sfa_rr", "iaf_cond_exp_sfa_rr_nestml", 1.e-3, 0.001)) - models.append(("iaf_cond_exp_sfa_rr", "iaf_cond_exp_sfa_rr_implicit_nestml", 1.e-3, 0.001)) - models.append(("iaf_psc_alpha", "iaf_psc_alpha_nestml", None, 0.001)) - models.append(("iaf_psc_delta", "iaf_psc_delta_nestml", None, 0.001)) - models.append(("iaf_psc_exp", "iaf_psc_exp_nestml", None, 0.01)) - models.append(("iaf_tum_2000", "iaf_tum_2000_nestml", None, 0.01)) - models.append(("izhikevich", "izhikevich_nestml", 1.e-3, 0.5)) - models.append(("mat2_psc_exp", "mat2_psc_exp_nestml", None, 0.1)) - - for reference, testant, gsl_error_tol, tollerance in models: - self._test_model(reference, testant, gsl_error_tol, tollerance) - - def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001): - spike_times = [100.0, 200.0] - spike_weights = [1., -1.] - - nest.ResetKernel() - neuron1 = nest.Create(referenceModel) - neuron2 = nest.Create(testant) - - if gsl_error_tol is not None: - nest.SetStatus(neuron2, {"gsl_error_tol": gsl_error_tol}) - - spikegenerator = nest.Create('spike_generator', - params={'spike_times': spike_times, 'spike_weights': spike_weights}) - - nest.Connect(spikegenerator, neuron1) - nest.Connect(spikegenerator, neuron2) - - multimeter1 = nest.Create('multimeter') - multimeter2 = nest.Create('multimeter') - - V_m_specifier = 'V_m' # 'delta_V_m' - nest.SetStatus(multimeter1, {"withtime": True, "record_from": [V_m_specifier]}) - nest.SetStatus(multimeter2, {"withtime": True, "record_from": [V_m_specifier]}) - - nest.Connect(multimeter1, neuron1) - nest.Connect(multimeter2, neuron2) - - nest.Simulate(400.0) - dmm1 = nest.GetStatus(multimeter1)[0] - Vms1 = dmm1["events"][V_m_specifier] - ts1 = dmm1["events"]["times"] - - dmm2 = nest.GetStatus(multimeter2)[0] - Vms2 = dmm2["events"][V_m_specifier] - ts2 = dmm2["events"]["times"] - - if TEST_PLOTS: - fig, ax = plt.subplots(2, 1) - ax[0].plot(ts1, Vms1, label="Reference " + referenceModel) - ax[1].plot(ts2, Vms2, label="Testant " + testant) - for _ax in ax: - _ax.legend(loc='upper right') - _ax.grid() - plt.savefig("/tmp/nestml_nest_integration_test_[" + referenceModel + "]_[" + testant + "].png") - - for index in range(0, len(Vms1)): - if abs(Vms1[index] - Vms2[index]) > tolerance \ - or np.isnan(Vms1[index]) \ - or np.isnan(Vms2[index]): - print(str(Vms1[index]) + " differs from " + str(Vms2[index]) - + " at iteration: " + str(index) + " of overall iterations: " + str(len(Vms1))) - raise Exception(testant + ": TEST FAILED") - - print(testant + " PASSED") diff --git a/extras/nestml-release-checklist.md b/extras/nestml-release-checklist.md index 28c9ff13d..f42f2f8f8 100644 --- a/extras/nestml-release-checklist.md +++ b/extras/nestml-release-checklist.md @@ -1,25 +1,25 @@ Release checklist ----------------- -Follow this checklist to successfully perform a NESTML release. Let's say that 3.0 is the currently-out release, and we want to publish 3.1. +Follow this checklist to successfully perform a NESTML release. Let's say that 5.0.0 is the currently-out release, and we want to publish 5.0.1. - Find out authors who contributed since the last release. ```bash - git log v3.0..HEAD | grep Author\: | sort | uniq + git log v5.0.0..HEAD | grep Author\: | sort | uniq ``` - Ensure copyright transferal agreement is obtained from each author (contact: @heplesser). Obtain affiliation one-liner for each author. -- Edit `setup.py` and enter the right version number. Edit `pynestml/__init__.py` and enter the right version number. Push to a new branch called `release-v3.1`. +- Edit `setup.py` and enter the right version number. Edit `pynestml/__init__.py` and enter the right version number. Push to a new branch called `release-v5.0.1`. - Log in to Zenodo, and create a new upload. Press the "Reserve DOI" button. - Go back to GitHub and create a new release from the web interface. - - Select the right branch, e.g. `release-v3.1` - - Under version tag, enter the new version number. Since v3.0 we're adding the "v" prefix (e.g. "v3.1"). - - For release title, use "NESTML" + version number, e.g. "NESTML 3.1". - - For release notes, write something starting with "\[NESTML 3.1\](https://dx.doi.org/10.5281/zenodo.3697733)" so that the Zenodo publication is linked. Look at the previous release note for further inspiration. + - Select the right branch, e.g. `release-v5.0.1` + - Under version tag, enter the new version number. Since v3.0.0 we're adding the "v" prefix (e.g. "v5.0.1"). + - For release title, use "NESTML" + version number, e.g. "NESTML 5.0.0". + - For release notes, write something starting with "\[NESTML 5.0.0\](https://dx.doi.org/10.5281/zenodo.3697733)" so that the Zenodo publication is linked. Look at the previous release note for further inspiration. - Download the generated .tar.gz file. - Extract the tarball locally and double-check that everything looks OK! E.g. no `.git` directory, version numbers. Sanity check the filesize. @@ -27,24 +27,24 @@ Follow this checklist to successfully perform a NESTML release. Let's say that 3 - Go back to Zenodo and enter remaining information. - Upload the .tar.gz file from GitHub - Upload type: software - - For title: "NESTML 3.1" + - For title: "NESTML 5.0.0" - Enter authors - For description: copy release notes from GitHub, but remove hyperlink to doi.org. Append "For further information, please visit https://github.com/nest/nestml" - Select "Open Access" - Enter "GNU GPL v2.0 only" as a licence - - Under "Related/alternate identifiers", enter a reference to the Zenodo entry of the previous NESTML version (here, v3.0) by entering the DOI of the v3.0 entry. + - Under "Related/alternate identifiers", enter a reference to the Zenodo entry of the previous NESTML version (here, v5.0.0) by entering the DOI of the v5.0.0 entry. - Click Save, then click Publish -- Go to the Zenodo entry of the previous NESTML version (here, v3.0), and add a reference to the Zenodo entry of the NESTML version currently being released, under "Related/alternate identifiers". Use the DOI of the new Zenodo entry. +- Go to the Zenodo entry of the previous NESTML version (here, v5.0.0), and add a reference to the Zenodo entry of the NESTML version currently being released, under "Related/alternate identifiers". Use the DOI of the new Zenodo entry. -- Perform a corresponding release on PyPi. From the `release-v3.1` branch: +- Perform a corresponding release on PyPi. From the `release-v5.0.1` branch: ```bash python setup.py bdist_wheel twine upload dist/* ``` -- Update version number on master branch: edit `setup.py` and add suffix to version number, e.g. `version='3.1-post-dev'`, to distinguish master branch version from release version. Do the same for `pynestml/__init__.py`. +- Update version number on master branch: edit `setup.py` and add suffix to version number, e.g. `version='5.0.1-post-dev'`, to distinguish master branch version from release version. Do the same for `pynestml/__init__.py`. ```bash git add setup.py @@ -52,4 +52,5 @@ Follow this checklist to successfully perform a NESTML release. Let's say that 3 git push -u origin master ``` -- Delete the release branch (in this example, `release-v3.1`). +- Delete the release branch (in this example, `release-v5.0.1`). +- Add the new tag ("v5.0.0") as an _active version_ in ReadTheDocs, and then change the _default version_ to this tag. diff --git a/extras/syntax-highlighting/KatePart/nestml-highlight.xml b/extras/syntax-highlighting/KatePart/nestml-highlight.xml index 66a6262f3..4b6da1d03 100644 --- a/extras/syntax-highlighting/KatePart/nestml-highlight.xml +++ b/extras/syntax-highlighting/KatePart/nestml-highlight.xml @@ -47,7 +47,6 @@ state parameters internals - initial_values update equations input @@ -3335,12 +3334,8 @@ - - - - @@ -3348,14 +3343,6 @@ - - - - - - - - @@ -3384,9 +3371,7 @@ - - diff --git a/extras/syntax-highlighting/geany/filetypes.NestML.conf b/extras/syntax-highlighting/geany/filetypes.NestML.conf index fa743898d..fe06c289a 100644 --- a/extras/syntax-highlighting/geany/filetypes.NestML.conf +++ b/extras/syntax-highlighting/geany/filetypes.NestML.conf @@ -6,7 +6,7 @@ commentblock=string [keywords] # all items must be in one line -primary=if elif else neuron equations internals input update parameters state output end function kernel for initial_values bounded_min min max and bounded_max +primary=if elif else neuron equations internals input update parameters state output end function kernel for bounded_min min max and bounded_max # additional keywords, will be highlighted with style "word2" identifiers=pA pF mV nS ms real integer mmol L integrate_odes inhibitory excitatory spike current emit_spike get_sum steps convolve @@ -20,8 +20,8 @@ wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' # if only single comment char is supported like # in this file, leave comment_close blank comment_single=# -comment_open=/* -comment_close=*/ +comment_open=""" +comment_close=""" # set to false if a comment character/string should start at column 0 of a line, true uses any # indentation of the line, e.g. setting to true causes the following on pressing CTRL+d diff --git a/extras/syntax-highlighting/pygments/pygments_nestml.py b/extras/syntax-highlighting/pygments/pygments_nestml.py index fceaa981f..0f24f97b2 100644 --- a/extras/syntax-highlighting/pygments/pygments_nestml.py +++ b/extras/syntax-highlighting/pygments/pygments_nestml.py @@ -44,7 +44,8 @@ def innerstring_rules(ttype): ], 'keywords': [ (words(( - "recordable", "kernel", "neuron", "state", "parameters", "internals", "initial_values", "update", "equations", "input", "output", "current", "spike", "inhibitory", "excitatory", "end", "function", "return", "if", "elif", "else", "for", "while", "in", "step", "and", "or", "not"), suffix=r'\b'), + "recordable", "kernel", "neuron", "synapse", "state", "parameters", "internals", "update", "equations", "input", + "output", "current", "spike", "inhibitory", "excitatory", "end", "inline", "onReceive", "function", "return", "if", "elif", "else", "for", "while", "in", "step", "and", "or", "not"), suffix=r'\b'), Keyword), ], 'types': [ diff --git a/extras/syntax-highlighting/visual-code/nestml/language-configuration.json b/extras/syntax-highlighting/visual-code/nestml/language-configuration.json index 1a18fe48b..5c292a088 100644 --- a/extras/syntax-highlighting/visual-code/nestml/language-configuration.json +++ b/extras/syntax-highlighting/visual-code/nestml/language-configuration.json @@ -19,7 +19,7 @@ ["{", "}"], ["[", "]"], ["(", ")"], - ["\"", "\""], + ["\"", "\""] ], "folding": { "offSide": true, diff --git a/extras/syntax-highlighting/visual-code/nestml/syntaxes/nestml.tmLanguage.json b/extras/syntax-highlighting/visual-code/nestml/syntaxes/nestml.tmLanguage.json index 32ca1f1a3..daf39bbd4 100644 --- a/extras/syntax-highlighting/visual-code/nestml/syntaxes/nestml.tmLanguage.json +++ b/extras/syntax-highlighting/visual-code/nestml/syntaxes/nestml.tmLanguage.json @@ -336,7 +336,7 @@ }, { "name": "keyword.control.block.nestml", - "match": "(?x)\n \\b(? 0: # refractory - r -= 1 # decrement refractory ticks count - V_m = V_reset # clamp potential - elif V_m >= V_peak: # threshold crossing detection - r = RefractoryCounts + 1 - V_m = V_reset # clamp potential - w += b - emit_spike() - end - - end - -end diff --git a/models/cm_default.nestml b/models/cm_default.nestml new file mode 100644 index 000000000..47a3cc374 --- /dev/null +++ b/models/cm_default.nestml @@ -0,0 +1,196 @@ +""" +Example compartmental model for NESTML + +Description ++++++++++++ +Corresponds to standard compartmental model implemented in NEST. + +References +++++++++++ + + +See also +++++++++ + + +Author +++++++ +Willem Wybo +""" +neuron cm_default: + + state: + + # the presence of the state variable [v_comp] + # triggers compartment model context + v_comp real = 0 + + ### ion channels ### + # initial values state variables sodium channel + m_Na real = 0.0 + h_Na real = 0.0 + + # initial values state variables potassium channel + n_K real = 0.0 + + end + + + parameters: + ### ion channels ### + # default parameters sodium channel + e_Na real = 50.0 + gbar_Na real = 0.0 + + # default parameters potassium channel + e_K real = -85.0 + gbar_K real = 0.0 + + ### synapses ### + e_AMPA real = 0 mV # Excitatory reversal Potential + tau_r_AMPA real = 0.2 ms # Synaptic Time Constant Excitatory Synapse + tau_d_AMPA real = 3.0 ms # Synaptic Time Constant Excitatory Synapse + + e_GABA real = -80. mV # Inhibitory reversal Potential + tau_r_GABA real = 0.2 ms # Synaptic Time Constant Inhibitory Synapse + tau_d_GABA real = 10.0 ms # Synaptic Time Constant Inhibitory Synapse + + e_NMDA real = 0 mV # NMDA reversal Potential + tau_r_NMDA real = 0.2 ms # Synaptic Time Constant NMDA Synapse + tau_d_NMDA real = 43.0 ms # Synaptic Time Constant NMDA Synapse + + e_AN_AMPA real = 0 mV # Excitatory reversal Potential + tau_r_AN_AMPA real = 0.2 ms # Synaptic Time Constant Excitatory Synapse + tau_d_AN_AMPA real = 3.0 ms # Synaptic Time Constant Excitatory Synapse + e_AN_NMDA real = 0 mV # NMDA reversal Potential + tau_r_AN_NMDA real = 0.2 ms # Synaptic Time Constant NMDA Synapse + tau_d_AN_NMDA real = 43.0 ms # Synaptic Time Constant NMDA Synapse + NMDA_ratio real = 2.0 # NMDA_ratio + end + + equations: + """ + Here, we define the currents that are present in the model. Currents may, + or may not depend on [v_comp]. Each variable in the equation for the currents + must correspond either to a parameter (e.g. [gbar_Na], [e_Na], e_[NMDA], etc...) + or to a state variable (e.g [m_Na], [n_K], [g_r_AMPA], etc...). + + When it is a parameter, it must be configurable from Python, by adding it as + a key: value pair to the dictionary argument of `nest.AddCompartment` for an + ion channel or of `nest.AddReceptor` for a synapse. + + State variables must reoccur in the initial values block and have an associated + equation in the equations block. + + Internally, the model must compute the pair of values (g_val, i_val) for the + integration algorithm. To do so, we need both the equation for current, and + its voltage derivative + + i_X + d(i_X)/dv + + Which we should be able to obtain from sympy trough symbolic differentiation. + Then, + + g_val = d(i_X)/d(v_comp) / 2. + i_val = i_X - d(i_X)/d(v_comp) / 2. + + """ + ### ion channels, recognized by lack of convolutions ### + inline Na real = gbar_Na * m_Na**3 * h_Na**1 * (e_Na - v_comp) + inline K real = gbar_K * n_K * (e_K - v_comp) + + ### synapses, characterized by convolution(s) with spike input ### + kernel g_AMPA = g_norm_AMPA * ( - exp(-t / tau_r_AMPA) + exp(-t / tau_d_AMPA) ) + inline AMPA real = convolve(g_AMPA, spikes_AMPA) * (e_AMPA - v_comp) + + kernel g_GABA = g_norm_GABA * ( - exp(-t / tau_r_GABA) + exp(-t / tau_d_GABA) ) + inline GABA real = convolve(g_GABA, spikes_GABA) * (e_GABA - v_comp ) + + kernel g_NMDA = g_norm_NMDA * ( - exp(-t / tau_r_NMDA) + exp(-t / tau_d_NMDA) ) + inline NMDA real = convolve(g_NMDA, spikes_NMDA) * (e_NMDA - v_comp ) / (1. + 0.3 * exp( -.1 * v_comp )) + + kernel g_AN_AMPA = g_norm_AN_AMPA * ( - exp(-t / tau_r_AN_AMPA) + exp(-t / tau_d_AN_AMPA) ) + kernel g_AN_NMDA = g_norm_AN_NMDA * ( - exp(-t / tau_r_AN_NMDA) + exp(-t / tau_d_AN_NMDA) ) + inline AMPA_NMDA real = convolve(g_AN_AMPA, spikes_AN) * (e_AN_AMPA - v_comp) + NMDA_ratio * \ + convolve(g_AN_NMDA, spikes_AN) * (e_AN_NMDA - v_comp) / (1. + 0.3 * exp( -.1 * v_comp )) + end + + # #sodium + # function m_inf_Na(v_comp real) real: + # return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + # end + + # function tau_m_Na(v_comp real) real: + # return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + # end + + # function h_inf_Na(v_comp real) real: + # return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + # end + + # function tau_h_Na(v_comp real) real: + # return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + # end + + # #potassium + # function n_inf_K(v_comp real) real: + # return 0.02*(v_comp - 25.0)/((1.0 - exp((25.0 - v_comp)/9.0))*((-0.002)*(v_comp - 25.0)/(1.0 - exp((v_comp - 25.0)/9.0)) + 0.02*(v_comp - 25.0)/(1.0 - exp((25.0 - v_comp)/9.0)))) + # end + + # function tau_n_K(v_comp real) real: + # return 0.3115264797507788/((-0.002)*(v_comp - 25.0)/(1.0 - exp((v_comp - 25.0)/9.0)) + 0.02*(v_comp - 25.0)/(1.0 - exp((25.0 - v_comp)/9.0))) + # end + + # functions K + function n_inf_K (v_comp real) real: + return 0.02*(1.0 - exp(0.111111111111111*(25.0 - v_comp)))**(-1)*(-0.002*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(-25.0 + v_comp)))**(-1) + 0.02*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(25.0 - v_comp)))**(-1))**(-1)*(-25.0 + v_comp) + end + function tau_n_K (v_comp real) real: + return 0.311526479750779*(-0.002*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(-25.0 + v_comp)))**(-1) + 0.02*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(25.0 - v_comp)))**(-1))**(-1) + end + + # functions Na + function m_inf_Na (v_comp real) real: + return (1.0 - 0.020438532058318*exp(-0.111111111111111*v_comp))**(-1)*((1.0 - 0.020438532058318*exp(-0.111111111111111*v_comp))**(-1)*(6.372366 + 0.182*v_comp) + (1.0 - 48.9271928701465*exp(0.111111111111111*v_comp))**(-1)*(-4.341612 - 0.124*v_comp))**(-1)*(6.372366 + 0.182*v_comp) + end + function tau_m_Na (v_comp real) real: + return 0.311526479750779*((1.0 - 0.020438532058318*exp(-0.111111111111111*v_comp))**(-1)*(6.372366 + 0.182*v_comp) + (1.0 - 48.9271928701465*exp(0.111111111111111*v_comp))**(-1)*(-4.341612 - 0.124*v_comp))**(-1) + end + function h_inf_Na (v_comp real) real: + return 1.0*(1.0 + 35734.4671267926*exp(0.161290322580645*v_comp))**(-1) + end + function tau_h_Na (v_comp real) real: + return 0.311526479750779*((1.0 - 4.52820432639598e-5*exp(-0.2*v_comp))**(-1)*(1.200312 + 0.024*v_comp) + (1.0 - 3277527.87650153*exp(0.2*v_comp))**(-1)*(-0.6826183 - 0.0091*v_comp))**(-1) + end + + internals: + tp_AMPA real = (tau_r_AMPA * tau_d_AMPA) / (tau_d_AMPA - tau_r_AMPA) * ln( tau_d_AMPA / tau_r_AMPA ) + g_norm_AMPA real = 1. / ( -exp( -tp_AMPA / tau_r_AMPA ) + exp( -tp_AMPA / tau_d_AMPA ) ) + + tp_GABA real = (tau_r_GABA * tau_d_GABA) / (tau_d_GABA - tau_r_GABA) * ln( tau_d_GABA / tau_r_GABA ) + g_norm_GABA real = 1. / ( -exp( -tp_GABA / tau_r_GABA ) + exp( -tp_GABA / tau_d_GABA ) ) + + tp_NMDA real = (tau_r_NMDA * tau_d_NMDA) / (tau_d_NMDA - tau_r_NMDA) * ln( tau_d_NMDA / tau_r_NMDA ) + g_norm_NMDA real = 1. / ( -exp( -tp_NMDA / tau_r_NMDA ) + exp( -tp_NMDA / tau_d_NMDA ) ) + + tp_AN_AMPA real = (tau_r_AN_AMPA * tau_d_AN_AMPA) / (tau_d_AN_AMPA - tau_r_AN_AMPA) * ln( tau_d_AN_AMPA / tau_r_AN_AMPA ) + g_norm_AN_AMPA real = 1. / ( -exp( -tp_AN_AMPA / tau_r_AN_AMPA ) + exp( -tp_AN_AMPA / tau_d_AN_AMPA ) ) + + tp_AN_NMDA real = (tau_r_AN_NMDA * tau_d_AN_NMDA) / (tau_d_AN_NMDA - tau_r_AN_NMDA) * ln( tau_d_AN_NMDA / tau_r_AN_NMDA ) + g_norm_AN_NMDA real = 1. / ( -exp( -tp_AN_NMDA / tau_r_AN_NMDA ) + exp( -tp_AN_NMDA / tau_d_AN_NMDA ) ) + end + + input: + spikes_AMPA uS <- spike + spikes_GABA uS <- spike + spikes_NMDA uS <- spike + spikes_AN uS <- spike + end + + output: spike + + update: + end + +end \ No newline at end of file diff --git a/models/lorenz_attractor.nestml b/models/lorenz_attractor.nestml deleted file mode 100644 index 661877161..000000000 --- a/models/lorenz_attractor.nestml +++ /dev/null @@ -1,25 +0,0 @@ -neuron lorenz_attractor: - -initial_values: - x real = 1 - y real = 1 - z real = 1 -end - -equations: - x' = sigma * (y - x) / s - y' = (x * (rho - z) - y) / s - z' = (x * y - beta * z) / s -end - -update: - integrate_odes() -end - -parameters: - sigma real = 10 - beta real = 8/3 - rho real = 28 -end - -end diff --git a/models/aeif_cond_alpha.nestml b/models/neurons/aeif_cond_alpha.nestml similarity index 52% rename from models/aeif_cond_alpha.nestml rename to models/neurons/aeif_cond_alpha.nestml index a9bc23724..53cf685d3 100644 --- a/models/aeif_cond_alpha.nestml +++ b/models/neurons/aeif_cond_alpha.nestml @@ -5,24 +5,24 @@ aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model Description +++++++++++ -aeif_cond_alpha is the adaptive exponential integrate and fire neuron according -to Brette and Gerstner (2005). -Synaptic conductances are modelled as alpha-functions. +aeif_cond_alpha is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of a bi-exponential ("alpha") function. The membrane potential is given by the following differential equation: .. math:: - C_m \frac{dV}{dt} = - -g_L(V-E_L)+g_L\Delta_T\exp\left(\frac{V-V_{th}}{\Delta_T}\right) - - g_e(t)(V-E_e) \\ - -g_i(t)(V-E_i)-w +I_e + C_m \frac{dV_m}{dt} = + -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - + g_e(t)(V_m-E_e) \\ + -g_i(t)(V_m-E_i)-w + I_e and .. math:: - \tau_w \frac{dw}{dt} = a(V-E_L) - w + \tau_w \frac{dw}{dt} = a(V_m-E_L) - w + +Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. References @@ -33,6 +33,7 @@ References activity. Journal of Neurophysiology. 943637-3642 DOI: https://doi.org/10.1152/jn.00686.2005 + See also ++++++++ @@ -40,29 +41,29 @@ iaf_cond_alpha, aeif_cond_exp """ neuron aeif_cond_alpha: - initial_values: - V_m mV = E_L # Membrane potential + state: + V_m mV = E_L # Membrane potential w pA = 0 pA # Spike-adaptation current end equations: inline V_bounded mV = min(V_m, V_peak) # prevent exponential divergence - kernel g_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - kernel g_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + kernel g_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel g_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) # Add inlines to simplify the equation definition of V_m - inline exp_arg real = (V_bounded-V_th)/Delta_T - inline I_spike pA = g_L*Delta_T*exp(exp_arg) - inline I_syn_exc pA = convolve(g_ex, spikesExc) * ( V_bounded - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikesInh) * ( V_bounded - E_in ) + inline exp_arg real = (V_bounded - V_th) / Delta_T + inline I_spike pA = g_L * Delta_T * exp(exp_arg) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * (V_bounded - E_exc) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * (V_bounded - E_inh) - V_m' = ( -g_L*( V_bounded - E_L ) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim ) / C_m - w' = (a*(V_m - E_L) - w)/tau_w + V_m' = (-g_L * (V_bounded - E_L) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim) / C_m + w' = (a * (V_bounded - E_L) - w) / tau_w end parameters: # membrane parameters - C_m pF = 281.0 pF # Membrane Capacitance + C_m pF = 281.0 pF # Membrane Capacitance t_ref ms = 0.0 ms # Refractory period V_reset mV = -60.0 mV # Reset Potential g_L nS = 30.0 nS # Leak Conductance @@ -70,30 +71,28 @@ neuron aeif_cond_alpha: # spike adaptation parameters a nS = 4 nS # Subthreshold adaptation - b pA = 80.5 pA # pike-triggered adaptation + b pA = 80.5 pA # Spike-triggered adaptation Delta_T mV = 2.0 mV # Slope factor tau_w ms = 144.0 ms # Adaptation time constant V_th mV = -50.4 mV # Threshold Potential V_peak mV = 0 mV # Spike detection threshold # synaptic parameters - E_ex mV = 0 mV # Excitatory reversal Potential - tau_syn_ex ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse - E_in mV = -85.0 mV # Inhibitory reversal Potential - tau_syn_in ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse + E_exc mV = 0 mV # Excitatory reversal Potential + tau_syn_exc ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse + E_inh mV = -85.0 mV # Inhibitory reversal Potential + tau_syn_inh ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse # constant external input current I_e pA = 0 pA end internals: - # Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude - # conductance excursion. - PSConInit_E nS/ms = nS * e / tau_syn_ex + # Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude conductance excursion + PSConInit_E nS/ms = nS * e / tau_syn_exc - # Impulse to add to DG_INH on spike arrival to evoke unit-amplitude - # conductance excursion. - PSConInit_I nS/ms = nS * e / tau_syn_in + # Impulse to add to DG_INH on spike arrival to evoke unit-amplitude conductance excursion + PSConInit_I nS/ms = nS * e / tau_syn_inh # refractory time in steps RefractoryCounts integer = steps(t_ref) @@ -102,9 +101,9 @@ neuron aeif_cond_alpha: end input: - spikesInh nS <- inhibitory spike - spikesExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike @@ -113,8 +112,8 @@ neuron aeif_cond_alpha: integrate_odes() if r > 0: # refractory - r = r - 1 # decrement refractory ticks count - V_m = V_reset + r -= 1 # decrement refractory ticks count + V_m = V_reset # clamp potential elif V_m >= V_peak: # threshold crossing detection r = RefractoryCounts V_m = V_reset # clamp potential diff --git a/models/neurons/aeif_cond_exp.nestml b/models/neurons/aeif_cond_exp.nestml new file mode 100644 index 000000000..b7cf36ff9 --- /dev/null +++ b/models/neurons/aeif_cond_exp.nestml @@ -0,0 +1,121 @@ +""" +aeif_cond_exp - Conductance based exponential integrate-and-fire neuron model +############################################################################# + +Description ++++++++++++ + +aeif_cond_exp is the adaptive exponential integrate and fire neuron +according to Brette and Gerstner (2005), with post-synaptic +conductances in the form of truncated exponentials. + +The membrane potential is given by the following differential equation: + +.. math:: + + C_m \frac{dV_m}{dt} = + -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - g_e(t)(V_m-E_e) \\ + -g_i(t)(V_m-E_i)-w +I_e + +and + +.. math:: + + \tau_w \frac{dw}{dt} = a(V_m-E_L) - w + +Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. + + +References +++++++++++ + +.. [1] Brette R and Gerstner W (2005). Adaptive exponential + integrate-and-fire model as an effective description of neuronal + activity. Journal of Neurophysiology. 943637-3642 + DOI: https://doi.org/10.1152/jn.00686.2005 + + +See also +++++++++ + +iaf_cond_exp, aeif_cond_alpha +""" +neuron aeif_cond_exp: + + state: + V_m mV = E_L # Membrane potential + w pA = 0 pA # Spike-adaptation current + end + + equations: + inline V_bounded mV = min(V_m, V_peak) # prevent exponential divergence + kernel g_inh = exp(-t / tau_syn_inh) + kernel g_exc = exp(-t / tau_syn_exc) + + # Add inlines to simplify the equation definition of V_m + inline exp_arg real = (V_bounded - V_th) / Delta_T + inline I_spike pA = g_L * Delta_T * exp(exp_arg) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * (V_bounded - E_exc) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * (V_bounded - E_inh) + + V_m' = (-g_L * (V_bounded - E_L) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim) / C_m + w' = (a * (V_bounded - E_L) - w) / tau_w + end + + parameters: + # membrane parameters + C_m pF = 281.0 pF # Membrane Capacitance + t_ref ms = 0.0 ms # Refractory period + V_reset mV = -60.0 mV # Reset Potential + g_L nS = 30.0 nS # Leak Conductance + E_L mV = -70.6 mV # Leak reversal Potential (aka resting potential) + + # spike adaptation parameters + a nS = 4 nS # Subthreshold adaptation + b pA = 80.5 pA # Spike-triggered adaptation + Delta_T mV = 2.0 mV # Slope factor + tau_w ms = 144.0 ms # Adaptation time constant + V_th mV = -50.4 mV # Threshold Potential + V_peak mV = 0 mV # Spike detection threshold + + # synaptic parameters + E_exc mV = 0 mV # Excitatory reversal Potential + tau_syn_exc ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse + E_inh mV = -85.0 mV # Inhibitory reversal Potential + tau_syn_inh ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse + + # constant external input current + I_e pA = 0 pA + end + + internals: + # refractory time in steps + RefractoryCounts integer = steps(t_ref) + # counts number of tick during the refractory period + r integer + end + + input: + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous + end + + output: spike + + update: + integrate_odes() + + if r > 0: # refractory + r -= 1 # decrement refractory ticks count + V_m = V_reset # clamp potential + elif V_m >= V_peak: # threshold crossing detection + r = RefractoryCounts + 1 + V_m = V_reset # clamp potential + w += b + emit_spike() + end + + end + +end diff --git a/models/hh_cond_exp_destexhe.nestml b/models/neurons/hh_cond_exp_destexhe.nestml similarity index 65% rename from models/hh_cond_exp_destexhe.nestml rename to models/neurons/hh_cond_exp_destexhe.nestml index 991dc4475..436733c2e 100644 --- a/models/hh_cond_exp_destexhe.nestml +++ b/models/neurons/hh_cond_exp_destexhe.nestml @@ -25,12 +25,6 @@ References .. [4] Z. Mainen, J. Joerges, J. R. Huguenard and T. J. Sejnowski (1995) A Model of Spike Initiation in Neocortical Pyramidal Neurons. Neuron -Author -++++++ - -Tobias Schulte to Brinke - - See also ++++++++ @@ -39,25 +33,23 @@ hh_cond_exp_traub neuron hh_cond_exp_destexhe: state: - r integer # counts number of tick during the refractory period - g_noise_ex uS = g_noise_ex0 - g_noise_in uS = g_noise_in0 - end + r integer = 0 # counts number of tick during the refractory period + g_noise_exc uS = g_noise_exc0 + g_noise_inh uS = g_noise_inh0 - initial_values: V_m mV = E_L # Membrane potential Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) Act_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) Inact_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) - + Noninact_p real = alpha_p_init / ( alpha_p_init + beta_p_init ) end equations: # synapses: exponential conductance - kernel g_in = exp(-1/tau_syn_in*t) - kernel g_ex = exp(-1/tau_syn_ex*t) + kernel g_inh = exp(-t/tau_syn_inh) + kernel g_exc = exp(-t/tau_syn_exc) # Add aliases to simplify the equation definition of V_m inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * ( V_m - E_Na ) @@ -65,10 +57,10 @@ neuron hh_cond_exp_destexhe: inline I_L pA = g_L * ( V_m - E_L ) inline I_M pA = g_M * Noninact_p * (V_m - E_K) - inline I_noise pA = (g_noise_ex * (V_m - E_ex) + g_noise_in * (V_m - E_in)) + inline I_noise pA = (g_noise_exc * (V_m - E_exc) + g_noise_inh * (V_m - E_inh)) - inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) V_m' =( -I_Na - I_K - I_M - I_L - I_syn_exc - I_syn_inh + I_e + I_stim - I_noise) / C_m @@ -92,27 +84,27 @@ neuron hh_cond_exp_destexhe: end parameters: - g_Na nS = 17318.0nS # Na Conductance - g_K nS = 3463.6nS # K Conductance - g_L nS = 15.5862nS # Leak Conductance - C_m pF = 346.36pF # Membrane Capacitance - E_Na mV = 60mV # Reversal potentials - E_K mV = -90.mV # Potassium reversal potential - E_L mV = -80.mV # Leak reversal Potential (aka resting potential) - V_T mV = -58.0mV # Voltage offset that controls dynamics. For default - # parameters, V_T = -63mV results in a threshold around -50mV. - tau_syn_ex ms = 2.7ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 10.5ms # Synaptic Time Constant for Inhibitory Synapse - E_ex mV = 0.0 mV # Excitatory synaptic reversal potential - E_in mV = -75.0mV # Inhibitory synaptic reversal potential + g_Na nS = 17318.0nS # Na Conductance + g_K nS = 3463.6nS # K Conductance + g_L nS = 15.5862nS # Leak Conductance + C_m pF = 346.36pF # Membrane Capacitance + E_Na mV = 60mV # Reversal potentials + E_K mV = -90.mV # Potassium reversal potential + E_L mV = -80.mV # Leak reversal Potential (aka resting potential) + V_T mV = -58.0mV # Voltage offset that controls dynamics. For default + # parameters, V_T = -63mV results in a threshold around -50mV. + tau_syn_exc ms = 2.7ms # Synaptic Time Constant Excitatory Synapse + tau_syn_inh ms = 10.5ms # Synaptic Time Constant for Inhibitory Synapse + E_exc mV = 0.0 mV # Excitatory synaptic reversal potential + E_inh mV = -75.0mV # Inhibitory synaptic reversal potential g_M nS = 173.18 nS # Conductance of non-inactivating K+ channel # Conductance OU noise - g_noise_ex0 uS = 0.012 uS # Mean of the excitatory noise conductance - g_noise_in0 uS = 0.057 uS # Mean of the inhibitory noise conductance - sigma_noise_ex uS = 0.003 uS # Standard deviation of the excitatory noise conductance - sigma_noise_in uS = 0.0066 uS # Standard deviation of the inhibitory noise conductance + g_noise_exc0 uS = 0.012 uS # Mean of the excitatory noise conductance + g_noise_inh0 uS = 0.057 uS # Mean of the inhibitory noise conductance + sigma_noise_exc uS = 0.003 uS # Standard deviation of the excitatory noise conductance + sigma_noise_inh uS = 0.0066 uS # Standard deviation of the inhibitory noise conductance alpha_n_init 1/ms = 0.032/(ms* mV ) * ( 15. mV - V_m) / ( exp( ( 15. mV - V_m) / 5. mV ) - 1. ) beta_n_init 1/ms = 0.5 /ms * exp( ( 10. mV - V_m ) / 40. mV ) @@ -130,16 +122,16 @@ neuron hh_cond_exp_destexhe: internals: RefractoryCounts integer = 20 - D_ex uS**2/ms = 2 * sigma_noise_ex**2 / tau_syn_ex - D_in uS**2/ms = 2 * sigma_noise_in**2 / tau_syn_in - A_ex uS = ((D_ex * tau_syn_ex / 2) * (1 - exp(-2 * resolution() / tau_syn_ex )))**.5 - A_in uS = ((D_in * tau_syn_in / 2) * (1 - exp(-2 * resolution() / tau_syn_in )))**.5 + D_exc uS**2/ms = 2 * sigma_noise_exc**2 / tau_syn_exc + D_inh uS**2/ms = 2 * sigma_noise_inh**2 / tau_syn_inh + A_exc uS = ((D_exc * tau_syn_exc / 2) * (1 - exp(-2 * resolution() / tau_syn_exc )))**.5 + A_inh uS = ((D_inh * tau_syn_inh / 2) * (1 - exp(-2 * resolution() / tau_syn_inh )))**.5 end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike @@ -148,8 +140,8 @@ neuron hh_cond_exp_destexhe: U_old mV = V_m integrate_odes() - g_noise_ex = g_noise_ex0 + (g_noise_ex - g_noise_ex0) * exp(-resolution() / tau_syn_ex) + A_ex * random_normal(0, 1) - g_noise_in = g_noise_in0 + (g_noise_in - g_noise_in0) * exp(-resolution() / tau_syn_in) + A_in * random_normal(0, 1) + g_noise_exc = g_noise_exc0 + (g_noise_exc - g_noise_exc0) * exp(-resolution() / tau_syn_exc) + A_exc * random_normal(0, 1) + g_noise_inh = g_noise_inh0 + (g_noise_inh - g_noise_inh0) * exp(-resolution() / tau_syn_inh) + A_inh * random_normal(0, 1) # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: diff --git a/models/hh_cond_exp_traub.nestml b/models/neurons/hh_cond_exp_traub.nestml similarity index 73% rename from models/hh_cond_exp_traub.nestml rename to models/neurons/hh_cond_exp_traub.nestml index 2f443f69b..c2ff8ce56 100644 --- a/models/hh_cond_exp_traub.nestml +++ b/models/neurons/hh_cond_exp_traub.nestml @@ -46,38 +46,30 @@ See also ++++++++ hh_psc_alpha - - -Author -++++++ - -Schrader """ neuron hh_cond_exp_traub: state: - r integer # counts number of tick during the refractory period - end + r integer = 0 # counts number of tick during the refractory period - initial_values: - V_m mV = E_L # Membrane potential + V_m mV = E_L # Membrane potential - Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) + Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) Act_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) - Inact_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) + Inact_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) end equations: # synapses: exponential conductance - kernel g_in = exp(-1/tau_syn_in*t) - kernel g_ex = exp(-1/tau_syn_ex*t) + kernel g_inh = exp(-t/tau_syn_inh) + kernel g_exc = exp(-t/tau_syn_exc) # Add aliases to simplify the equation definition of V_m inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * ( V_m - E_Na ) inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) - inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) V_m' = ( -I_Na - I_K - I_L - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m @@ -96,20 +88,20 @@ neuron hh_cond_exp_traub: end parameters: - g_Na nS = 20000.0 nS # Na Conductance - g_K nS = 6000.0 nS # K Conductance - g_L nS = 10 nS # Leak Conductance - C_m pF = 200.0 pF # Membrane Capacitance - E_Na mV = 50 mV # Reversal potentials - E_K mV = -90. mV # Potassium reversal potential - E_L mV = -60. mV # Leak reversal Potential (aka resting potential) - V_T mV = -63.0 mV # Voltage offset that controls dynamics. For default - # parameters, V_T = -63 mV results in a threshold around -50 mV. - tau_syn_ex ms = 5.0 ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 10.0 ms # Synaptic Time Constant for Inhibitory Synapse - t_ref ms = 2.0 ms # Refractory period - E_ex mV = 0.0 mV # Excitatory synaptic reversal potential - E_in mV = -80.0 mV # Inhibitory synaptic reversal potential + g_Na nS = 20000 nS # Na Conductance + g_K nS = 6000 nS # K Conductance + g_L nS = 10 nS # Leak Conductance + C_m pF = 200 pF # Membrane Capacitance + E_Na mV = 50 mV # Reversal potentials + E_K mV = -90 mV # Potassium reversal potential + E_L mV = -60 mV # Leak reversal potential (aka resting potential) + V_T mV = -63 mV # Voltage offset that controls dynamics. For default + # parameters, V_T = -63 mV results in a threshold around -50 mV. + tau_syn_exc ms = 5 ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 10 ms # Synaptic time constant of inhibitory synapse + t_ref ms = 2 ms # Refractory period + E_exc mV = 0 mV # Excitatory synaptic reversal potential + E_inh mV = -80 mV # Inhibitory synaptic reversal potential alpha_n_init 1/ms = 0.032/(ms* mV ) * ( 15. mV - E_L) / ( exp( ( 15. mV - E_L) / 5. mV ) - 1. ) beta_n_init 1/ms = 0.5 /ms * exp( ( 10. mV - E_L ) / 40. mV ) @@ -127,9 +119,9 @@ neuron hh_cond_exp_traub: end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/hh_psc_alpha.nestml b/models/neurons/hh_psc_alpha.nestml similarity index 74% rename from models/hh_psc_alpha.nestml rename to models/neurons/hh_psc_alpha.nestml index cbebf9d9c..97afe2663 100644 --- a/models/hh_psc_alpha.nestml +++ b/models/neurons/hh_psc_alpha.nestml @@ -45,10 +45,8 @@ hh_cond_exp_traub """ neuron hh_psc_alpha: state: - r integer # number of steps in the current refractory phase - end + r integer = 0 # number of steps in the current refractory phase - initial_values: V_m mV = V_m_init # Membrane potential Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m for Na @@ -58,13 +56,13 @@ neuron hh_psc_alpha: equations: # synapses: alpha functions - kernel I_syn_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - kernel I_syn_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + kernel K_syn_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + kernel K_syn_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) - inline I_syn_exc pA = convolve(I_syn_ex, spikeExc) - inline I_syn_inh pA = convolve(I_syn_in, spikeInh) + inline I_syn_exc pA = convolve(K_syn_exc, exc_spikes) + inline I_syn_inh pA = convolve(K_syn_inh, inh_spikes) inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * ( V_m - E_Na ) - inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * ( V_m - E_K ) + inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) # Act_n @@ -82,21 +80,21 @@ neuron hh_psc_alpha: inline beta_h real = 1. / ( 1. + exp( -( V_m / mV + 35. ) / 10. ) ) Inact_h' = ( alpha_h * ( 1 - Inact_h ) - beta_h * Inact_h ) / ms # h-variable - V_m' =( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_inh + I_syn_exc ) / C_m + V_m' = ( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_exc - I_syn_inh ) / C_m end parameters: - t_ref ms = 2.0 ms # Refractory period - g_Na nS = 12000.0 nS # Sodium peak conductance - g_K nS = 3600.0 nS # Potassium peak conductance - g_L nS = 30 nS # Leak conductance - C_m pF = 100.0 pF # Membrane Capacitance - E_Na mV = 50 mV # Sodium reversal potential - E_K mV = -77. mV # Potassium reversal potentia - E_L mV = -54.402 mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 0.2 ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 2.0 ms # Rise time of the inhibitory synaptic alpha function - V_m_init mV = -65. mV # Initial membrane potential + t_ref ms = 2 ms # Refractory period + g_Na nS = 12000 nS # Sodium peak conductance + g_K nS = 3600 nS # Potassium peak conductance + g_L nS = 30 nS # Leak conductance + C_m pF = 100 pF # Membrane Capacitance + E_Na mV = 50 mV # Sodium reversal potential + E_K mV = -77 mV # Potassium reversal potential + E_L mV = -54.402 mV # Leak reversal Potential (aka resting potential) + tau_syn_exc ms = 0.2 ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 2 ms # Rise time of the inhibitory synaptic alpha function + V_m_init mV = -65 mV # Initial membrane potential alpha_n_init real = ( 0.01 * ( V_m_init / mV + 55. ) ) / ( 1. - exp( -( V_m_init / mV + 55. ) / 10. ) ) beta_n_init real = 0.125 * exp( -( V_m_init / mV + 65. ) / 80. ) alpha_m_init real = ( 0.1 * ( V_m_init / mV + 40. ) ) / ( 1. - exp( -( V_m_init / mV + 40. ) / 10. ) ) @@ -113,9 +111,9 @@ neuron hh_psc_alpha: end input: - spikeInh pA <- inhibitory spike - spikeExc pA <- excitatory spike - I_stim pA <- current + inh_spikes pA <- inhibitory spike + exc_spikes pA <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/hill_tononi.nestml b/models/neurons/hill_tononi.nestml similarity index 98% rename from models/hill_tononi.nestml rename to models/neurons/hill_tononi.nestml index 956b5fae9..862f77353 100644 --- a/models/hill_tononi.nestml +++ b/models/neurons/hill_tononi.nestml @@ -33,19 +33,12 @@ References unblock of NMDA receptors limits their contribution to spike generation in cortical pyramidal neurons. Journal of Neurophysiology 89:2778-2783. DOI: https://doi.org/10.1152/jn.01038.2002 - -Author -++++++ - -Hans Ekkehard Plesser """ neuron hill_tononi: state: - r_potassium integer + r_potassium integer = 0 g_spike boolean = false - end - initial_values: V_m mV = ( g_NaL * E_Na + g_KL * E_K ) / ( g_NaL + g_KL ) # membrane potential Theta mV = Theta_eq # Threshold IKNa_D, IT_m, IT_h, Ih_m nS = 0.0 nS @@ -197,7 +190,7 @@ neuron hill_tononi: NMDA nS <- spike GABA_A nS <- spike GABA_B nS <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike diff --git a/models/iaf_chxk_2008.nestml b/models/neurons/iaf_chxk_2008.nestml similarity index 78% rename from models/iaf_chxk_2008.nestml rename to models/neurons/iaf_chxk_2008.nestml index 507095363..bfcdd7786 100644 --- a/models/iaf_chxk_2008.nestml +++ b/models/neurons/iaf_chxk_2008.nestml @@ -35,19 +35,19 @@ iaf_cond_alpha """ neuron iaf_chxk_2008: - initial_values: + state: V_m mV = E_L # membrane potential g_ahp nS = 0 nS # AHP conductance g_ahp' nS/ms = 0 nS/ms # AHP conductance end equations: - kernel g_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - kernel g_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + kernel g_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + kernel g_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) g_ahp'' = -2 * g_ahp' / tau_ahp - g_ahp / tau_ahp**2 - inline I_syn_exc pA = convolve(g_ex, spikesExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikesInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) inline I_ahp pA = g_ahp * ( V_m - E_ahp ) inline I_leak pA = g_L * ( V_m - E_L ) @@ -55,14 +55,14 @@ neuron iaf_chxk_2008: end parameters: - V_th mV = -45.0 mV # Threshold Potential - E_ex mV = 20 mV # Excitatory reversal potential - E_in mV = -90 mV # Inhibitory reversal potential - g_L nS = 100 nS # Leak Conductance - C_m pF = 1000.0 pF # Membrane Capacitance + V_th mV = -45.0 mV # Threshold potential + E_exc mV = 20 mV # Excitatory reversal potential + E_inh mV = -90 mV # Inhibitory reversal potential + g_L nS = 100 nS # Leak conductance + C_m pF = 1000.0 pF # Membrane capacitance E_L mV = -60.0 mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 1 ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 1 ms # Synaptic Time Constant for Inhibitory Synapse + tau_syn_exc ms = 1 ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 1 ms # Synaptic time constant of inhibitory synapse tau_ahp ms = 0.5 ms # Afterhyperpolarization (AHP) time constant G_ahp nS = 443.8 nS # AHP conductance E_ahp mV = -95 mV # AHP potential @@ -74,18 +74,18 @@ neuron iaf_chxk_2008: internals: # Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude conductance excursion. - PSConInit_E nS/ms = nS * e / tau_syn_ex + PSConInit_E nS/ms = nS * e / tau_syn_exc # Impulse to add to DG_INH on spike arrival to evoke unit-amplitude conductance excursion. - PSConInit_I nS/ms = nS * e / tau_syn_in + PSConInit_I nS/ms = nS * e / tau_syn_inh PSConInit_AHP real = G_ahp * e / tau_ahp * (ms/nS) end input: - spikesInh nS <- inhibitory spike - spikesExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/iaf_cond_alpha.nestml b/models/neurons/iaf_cond_alpha.nestml similarity index 66% rename from models/iaf_cond_alpha.nestml rename to models/neurons/iaf_cond_alpha.nestml index 3565a731a..5bb9ae3a4 100644 --- a/models/iaf_cond_alpha.nestml +++ b/models/neurons/iaf_cond_alpha.nestml @@ -34,45 +34,36 @@ See also ++++++++ iaf_cond_exp - - -Authors -+++++++ - -Schrader, Plesser """ neuron iaf_cond_alpha: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # membrane potential end equations: - kernel g_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - kernel g_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + kernel g_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + kernel g_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) - inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) inline I_leak pA = g_L * ( V_m - E_L ) V_m' = ( -I_leak - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m end parameters: - V_th mV = -55.0 mV # Threshold Potential - V_reset mV = -60.0 mV # Reset Potential - t_ref ms = 2. ms # Refractory period - g_L nS = 16.6667 nS # Leak Conductance - C_m pF = 250.0 pF # Membrane Capacitance - E_ex mV = 0 mV # Excitatory reversal Potential - E_in mV = -85.0 mV # Inhibitory reversal Potential - E_L mV = -70.0 mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse + V_th mV = -55 mV # Threshold potential + V_reset mV = -60 mV # Reset potential + t_ref ms = 2 ms # Refractory period + g_L nS = 16.6667 nS # Leak conductance + C_m pF = 250 pF # Membrane capacitance + E_exc mV = 0 mV # Excitatory reversal potential + E_inh mV = -85 mV # Inhibitory reversal potential + E_L mV = -70 mV # Leak reversal potential (aka resting potential) + tau_syn_exc ms = 0.2 ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 2 ms # Synaptic time constant of inhibitory synapse # constant external input current I_e pA = 0 pA @@ -83,9 +74,9 @@ neuron iaf_cond_alpha: end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/iaf_cond_beta.nestml b/models/neurons/iaf_cond_beta.nestml similarity index 66% rename from models/iaf_cond_beta.nestml rename to models/neurons/iaf_cond_beta.nestml index ae330ae14..375f4cf6f 100644 --- a/models/iaf_cond_beta.nestml +++ b/models/neurons/iaf_cond_beta.nestml @@ -45,10 +45,8 @@ iaf_cond_exp, iaf_cond_alpha """ neuron iaf_cond_beta: state: - r integer # counts number of tick during the refractory period - end + r integer = 0 # counts number of tick during the refractory period - initial_values: V_m mV = E_L # membrane potential # inputs from the inhibitory conductance @@ -61,33 +59,33 @@ neuron iaf_cond_beta: end equations: - kernel g_in' = g_in$ - g_in / tau_syn_rise_I, - g_in$' = -g_in$ / tau_syn_decay_I + kernel g_in' = g_in$ - g_in / tau_syn_rise_I, + g_in$' = -g_in$ / tau_syn_decay_I - kernel g_ex' = g_ex$ - g_ex / tau_syn_rise_E, - g_ex$' = -g_ex$ / tau_syn_decay_E + kernel g_ex' = g_ex$ - g_ex / tau_syn_rise_E, + g_ex$' = -g_ex$ / tau_syn_decay_E - inline I_syn_exc pA = (F_E + convolve(g_ex, spikeExc)) * (V_m - E_ex) - inline I_syn_inh pA = (F_I + convolve(g_in, spikeInh)) * (V_m - E_in) - inline I_leak pA = g_L * (V_m - E_L) # pA = nS * mV - V_m' = (-I_leak - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m + inline I_syn_exc pA = (F_E + convolve(g_ex, exc_spikes)) * (V_m - E_ex) + inline I_syn_inh pA = (F_I + convolve(g_in, inh_spikes)) * (V_m - E_in) + inline I_leak pA = g_L * (V_m - E_L) # pA = nS * mV + V_m' = (-I_leak - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m end parameters: - E_L mV = -70. mV # Leak reversal potential (aka resting potential) - C_m pF = 250. pF # Capacitance of the membrane - t_ref ms = 2. ms # Refractory period - V_th mV = -55. mV # Threshold potential - V_reset mV = -60. mV # Reset potential - E_ex mV = 0 mV # Excitatory reversal potential - E_in mV = -85. mV # Inhibitory reversal potential - g_L nS = 16.6667 nS # Leak conductance - tau_syn_rise_I ms = .2 ms # Synaptic time constant excitatory synapse - tau_syn_decay_I ms = 2. ms # Synaptic time constant for inhibitory synapse - tau_syn_rise_E ms = .2 ms # Synaptic time constant excitatory synapse - tau_syn_decay_E ms = 2. ms # Synaptic time constant for inhibitory synapse - F_E nS = 0 nS # Constant external input conductance (excitatory). - F_I nS = 0 nS # Constant external input conductance (inhibitory). + E_L mV = -70 mV # Leak reversal potential (aka resting potential) + C_m pF = 250 pF # Capacitance of the membrane + t_ref ms = 2 ms # Refractory period + V_th mV = -55 mV # Threshold potential + V_reset mV = -60 mV # Reset potential + E_ex mV = 0 mV # Excitatory reversal potential + E_in mV = -85 mV # Inhibitory reversal potential + g_L nS = 16.6667 nS # Leak conductance + tau_syn_rise_I ms = .2 ms # Synaptic time constant excitatory synapse + tau_syn_decay_I ms = 2 ms # Synaptic time constant for inhibitory synapse + tau_syn_rise_E ms = .2 ms # Synaptic time constant excitatory synapse + tau_syn_decay_E ms = 2 ms # Synaptic time constant for inhibitory synapse + F_E nS = 0 nS # Constant external input conductance (excitatory). + F_I nS = 0 nS # Constant external input conductance (inhibitory). # constant external input current I_e pA = 0 pA @@ -106,9 +104,9 @@ neuron iaf_cond_beta: end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/iaf_cond_exp.nestml b/models/neurons/iaf_cond_exp.nestml similarity index 59% rename from models/iaf_cond_exp.nestml rename to models/neurons/iaf_cond_exp.nestml index c42bbbbcc..e25c8f0a2 100644 --- a/models/iaf_cond_exp.nestml +++ b/models/neurons/iaf_cond_exp.nestml @@ -24,43 +24,35 @@ See also ++++++++ iaf_psc_delta, iaf_psc_exp, iaf_cond_exp - -Author -++++++ - -Sven Schrader """ neuron iaf_cond_exp: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_m mV = E_L # membrane potential end equations: - kernel g_in = exp(-t/tau_syn_in) # inputs from the inh conductance - kernel g_ex = exp(-t/tau_syn_ex) # inputs from the exc conductance + kernel g_inh = exp(-t/tau_syn_inh) # inputs from the inh conductance + kernel g_exc = exp(-t/tau_syn_exc) # inputs from the exc conductance - inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) inline I_leak pA = g_L * ( V_m - E_L ) V_m' = ( -I_leak - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m end parameters: - V_th mV = -55.0 mV # Threshold Potential - V_reset mV = -60.0 mV # Reset Potential - t_ref ms = 2.0 ms # Refractory period - g_L nS = 16.6667 nS # Leak Conductance - C_m pF = 250.0 pF # Membrane Capacitance - E_ex mV = 0 mV # Excitatory reversal Potential - E_in mV = -85.0 mV # Inhibitory reversal Potential - E_L mV = -70.0 mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse + V_th mV = -55 mV # Threshold potential + V_reset mV = -60 mV # Reset potential + t_ref ms = 2 ms # Refractory period + g_L nS = 16.6667 nS # Leak conductance + C_m pF = 250 pF # Membrane capacitance + E_exc mV = 0 mV # Excitatory reversal potential + E_inh mV = -85 mV # Inhibitory reversal potential + E_L mV = -70 mV # Leak reversal potential (aka resting potential) + tau_syn_exc ms = 0.2 ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 2 ms # Synaptic time constant of inhibitory synapse # constant external input current I_e pA = 0 pA @@ -71,9 +63,9 @@ neuron iaf_cond_exp: end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/iaf_cond_exp_sfa_rr.nestml b/models/neurons/iaf_cond_exp_sfa_rr.nestml similarity index 61% rename from models/iaf_cond_exp_sfa_rr.nestml rename to models/neurons/iaf_cond_exp_sfa_rr.nestml index dc8a1fb2d..8eca46b58 100644 --- a/models/iaf_cond_exp_sfa_rr.nestml +++ b/models/neurons/iaf_cond_exp_sfa_rr.nestml @@ -36,24 +36,22 @@ aeif_cond_alpha, aeif_cond_exp, iaf_chxk_2008 neuron iaf_cond_exp_sfa_rr: state: - r integer # counts number of tick during the refractory period - end + r integer = 0 # counts number of tick during the refractory period - initial_values: V_m mV = E_L # membrane potential g_sfa nS = 0 nS # inputs from the sfa conductance g_rr nS = 0 nS # inputs from the rr conductance end equations: - kernel g_in = exp(-t/tau_syn_in) # inputs from the inh conductance - kernel g_ex = exp(-t/tau_syn_ex) # inputs from the exc conductance + kernel g_inh = exp(-t/tau_syn_inh) # inputs from the inh conductance + kernel g_exc = exp(-t/tau_syn_exc) # inputs from the exc conductance g_sfa' = -g_sfa / tau_sfa g_rr' = -g_rr / tau_rr - inline I_syn_exc pA = convolve(g_ex, spikesExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikesInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) inline I_L pA = g_L * ( V_m - E_L ) inline I_sfa pA = g_sfa * ( V_m - E_sfa ) inline I_rr pA = g_rr * ( V_m - E_rr ) @@ -62,22 +60,22 @@ neuron iaf_cond_exp_sfa_rr: end parameters: - V_th mV = -57.0 mV # Threshold Potential - V_reset mV = -70.0 mV # Reset Potential - t_ref ms = 0.5 ms # Refractory period - g_L nS = 28.95 nS # Leak Conductance - C_m pF = 289.5 pF # Membrane Capacitance - E_ex mV = 0 mV # Excitatory reversal Potential - E_in mV = -75.0 mV # Inhibitory reversal Potential - E_L mV = -70.0 mV # Leak reversal Potential (aka resting potential) - tau_syn_ex ms = 1.5 ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 10.0 ms # Synaptic Time Constant for Inhibitory Synapse - q_sfa nS = 14.48 nS # Outgoing spike activated quantal spike-frequency adaptation conductance increase - q_rr nS = 3214.0 nS # Outgoing spike activated quantal relative refractory conductance increase. - tau_sfa ms = 110.0 ms # Time constant of spike-frequency adaptation. - tau_rr ms = 1.97 ms # Time constant of the relative refractory mechanism. - E_sfa mV = -70.0 mV # spike-frequency adaptation conductance reversal potential - E_rr mV = -70.0 mV # relative refractory mechanism conductance reversal potential + V_th mV = -57.0 mV # Threshold potential + V_reset mV = -70.0 mV # Reset potential + t_ref ms = 0.5 ms # Refractory period + g_L nS = 28.95 nS # Leak conductance + C_m pF = 289.5 pF # Membrane capacitance + E_exc mV = 0 mV # Excitatory reversal potential + E_inh mV = -75.0 mV # Inhibitory reversal potential + E_L mV = -70.0 mV # Leak reversal potential (aka resting potential) + tau_syn_exc ms = 1.5 ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 10.0 ms # Synaptic time constant of inhibitory synapse + q_sfa nS = 14.48 nS # Outgoing spike activated quantal spike-frequency adaptation conductance increase + q_rr nS = 3214.0 nS # Outgoing spike activated quantal relative refractory conductance increase + tau_sfa ms = 110.0 ms # Time constant of spike-frequency adaptation + tau_rr ms = 1.97 ms # Time constant of the relative refractory mechanism + E_sfa mV = -70.0 mV # spike-frequency adaptation conductance reversal potential + E_rr mV = -70.0 mV # relative refractory mechanism conductance reversal potential # constant external input current I_e pA = 0 pA @@ -88,9 +86,9 @@ neuron iaf_cond_exp_sfa_rr: end input: - spikesInh nS <- inhibitory spike - spikesExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/iaf_psc_alpha.nestml b/models/neurons/iaf_psc_alpha.nestml similarity index 60% rename from models/iaf_psc_alpha.nestml rename to models/neurons/iaf_psc_alpha.nestml index 597ba6c6b..af90787dd 100644 --- a/models/iaf_psc_alpha.nestml +++ b/models/neurons/iaf_psc_alpha.nestml @@ -26,7 +26,7 @@ enough to exhibit non-trivial dynamics and simple enough compute relevant measures analytically. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -34,26 +34,6 @@ relevant measures analytically. the NEST source code (``docs/model_details``). -Parameters -++++++++++ - -The following parameters can be set in the status dictionary. - -=========== ====== ========================================================== - V_m mV Membrane potential - E_L mV Resting membrane potential - C_m pF Capacity of the membrane - tau_m ms Membrane time constant - t_ref ms Duration of refractory period - V_th mV Spike threshold - V_reset mV Reset potential of the membrane - tau_syn_ex ms Rise time of the excitatory synaptic alpha function - tau_syn_in ms Rise time of the inhibitory synaptic alpha function - I_e pA Constant input current - V_min mV Absolute lower value for the membrane potenial -=========== ====== ========================================================== - - References ++++++++++ @@ -75,53 +55,44 @@ See also ++++++++ iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha - - -Authors -+++++++ - -Diesmann, Gewaltig """ neuron iaf_psc_alpha: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0 mV end equations: - kernel I_kernel_in = (e / tau_syn_in) * t * exp(-t / tau_syn_in) - kernel I_kernel_ex = (e / tau_syn_ex) * t * exp(-t / tau_syn_ex) - recordable inline V_m mV = V_abs + E_L # Membrane potential. - inline I pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + I_e + I_stim - V_abs' = -V_abs/tau_m + I/C_m + kernel I_kernel_inh = (e / tau_syn_inh) * t * exp(-t / tau_syn_inh) + kernel I_kernel_exc = (e / tau_syn_exc) * t * exp(-t / tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential + inline I pA = convolve(I_kernel_exc, exc_spikes) - convolve(I_kernel_inh, inh_spikes) + I_e + I_stim + V_abs' = -V_abs / tau_m + I / C_m end parameters: - C_m pF = 250 pF # Capacitance of the membrane - tau_m ms = 10 ms # Membrane time constant - tau_syn_in ms = 2 ms # Time constant of synaptic current - tau_syn_ex ms = 2 ms # Time constant of synaptic current - t_ref ms = 2 ms # Duration of refractory period - E_L mV = -70 mV # Resting potential + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of synaptic current + tau_syn_exc ms = 2 ms # Time constant of synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential V_reset mV = -70 mV - E_L # Reset potential of the membrane - V_th mV = -55 mV - E_L # Spike threshold + V_th mV = -55 mV - E_L # Spike threshold # constant external input current I_e pA = 0 pA end internals: - RefractoryCounts integer = steps(t_ref) # refractory time in steps + RefractoryCounts integer = steps(t_ref) # refractory time in steps end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end output: spike diff --git a/models/iaf_psc_delta.nestml b/models/neurons/iaf_psc_delta.nestml similarity index 95% rename from models/iaf_psc_delta.nestml rename to models/neurons/iaf_psc_delta.nestml index 4109acfd1..58c60ac79 100644 --- a/models/iaf_psc_delta.nestml +++ b/models/neurons/iaf_psc_delta.nestml @@ -48,21 +48,12 @@ See also ++++++++ iaf_psc_alpha, iaf_psc_exp - - -Authors -+++++++ - -Diesmann, Gewaltig (September 1999) """ neuron iaf_psc_delta: state: refr_spikes_buffer mV = 0 mV - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0 mV end @@ -94,7 +85,7 @@ neuron iaf_psc_delta: input: spikes pA <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike diff --git a/models/neurons/iaf_psc_exp.nestml b/models/neurons/iaf_psc_exp.nestml new file mode 100644 index 000000000..c58847967 --- /dev/null +++ b/models/neurons/iaf_psc_exp.nestml @@ -0,0 +1,95 @@ +""" +iaf_psc_exp - Leaky integrate-and-fire neuron model with exponential PSCs +######################################################################### + +Description ++++++++++++ + +iaf_psc_exp is an implementation of a leaky integrate-and-fire model +with exponential-kernel postsynaptic currents (PSCs) according to [1]_. +Thus, postsynaptic currents have an infinitely short rise time. + +The threshold crossing is followed by an absolute refractory period (t_ref) +during which the membrane potential is clamped to the resting potential +and spiking is prohibited. + +.. note:: + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems + may arise due to singularities in the propagator matrics. If this is + the case, replace equal-valued parameters by a single parameter. + + For details, please see ``IAF_neurons_singularity.ipynb`` in + the NEST source code (``docs/model_details``). + + +References +++++++++++ + +.. [1] Tsodyks M, Uziel A, Markram H (2000). Synchrony generation in recurrent + networks with frequency-dependent synapses. The Journal of Neuroscience, + 20,RC50:1-5. URL: https://infoscience.epfl.ch/record/183402 + + +See also +++++++++ + +iaf_cond_exp +""" +neuron iaf_psc_exp: + + state: + r integer = 0 # counts number of tick during the refractory period + V_abs mV = 0 mV + end + + equations: + kernel I_kernel_inh = exp(-t / tau_syn_inh) + kernel I_kernel_exc = exp(-t / tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential + inline I_syn pA = convolve(I_kernel_exc, exc_spikes) - convolve(I_kernel_inh, inh_spikes) + V_abs' = -V_abs / tau_m + (I_syn + I_e + I_stim) / C_m + end + + parameters: + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of inhibitory synaptic current + tau_syn_exc ms = 2 ms # Time constant of excitatory synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential + V_reset mV = -70 mV - E_L # Reset value of the membrane potential + Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!) + # I.e. the real threshold is (E_L + Theta) + + # constant external input current + I_e pA = 0 pA + end + + internals: + RefractoryCounts integer = steps(t_ref) # refractory time in steps + end + + input: + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous + end + + output: spike + + update: + if r == 0: # neuron not refractory, so evolve V + integrate_odes() + else: + r = r - 1 # neuron is absolute refractory + end + + if V_abs >= Theta: # threshold crossing + r = RefractoryCounts + V_abs = V_reset + emit_spike() + end + + end + +end diff --git a/models/iaf_psc_exp.nestml b/models/neurons/iaf_psc_exp_dend.nestml similarity index 62% rename from models/iaf_psc_exp.nestml rename to models/neurons/iaf_psc_exp_dend.nestml index 4178ab261..6bfb7cbf7 100644 --- a/models/iaf_psc_exp.nestml +++ b/models/neurons/iaf_psc_exp_dend.nestml @@ -1,5 +1,5 @@ """ -iaf_psc_exp - Leaky integrate-and-fire neuron model with exponential PSCs +iaf_psc_exp_dend - Leaky integrate-and-fire neuron model with exponential PSCs ######################################################################### Description @@ -34,41 +34,33 @@ See also ++++++++ iaf_cond_exp - - -Author -++++++ - -Moritz Helias """ -neuron iaf_psc_exp: +neuron iaf_psc_exp_dend: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0 mV + I_dend pA = 0 pA # third factor, to be read out by synapse during weight update end equations: - kernel I_kernel_in = exp(-1/tau_syn_in*t) - kernel I_kernel_ex = exp(-1/tau_syn_ex*t) + kernel I_kernel_inh = exp(-t/tau_syn_inh) + kernel I_kernel_exc = exp(-t/tau_syn_exc) recordable inline V_m mV = V_abs + E_L # Membrane potential. - inline I_syn pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + I_e + I_stim - V_abs' = -V_abs / tau_m + I_syn / C_m + inline I_syn pA = convolve(I_kernel_exc, exc_spikes) - convolve(I_kernel_inh, inh_spikes) + V_abs' = -V_abs / tau_m + (I_syn + I_e + I_stim) / C_m end parameters: - C_m pF = 250 pF # Capacity of the membrane - tau_m ms = 10 ms # Membrane time constant - tau_syn_in ms = 2 ms # Time constant of synaptic current - tau_syn_ex ms = 2 ms # Time constant of synaptic current - t_ref ms = 2 ms # Duration of refractory period - E_L mV = -70 mV # Resting potential + C_m pF = 250 pF # Capacity of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of inhibitory synaptic current + tau_syn_exc ms = 2 ms # Time constant of excitatory synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential V_reset mV = -70 mV - E_L # reset value of the membrane potential Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!). - # I.e. the real threshold is (E_L_+V_th_) + # I.e. the real threshold is (E_L_+V_th_) # constant external input current I_e pA = 0 pA @@ -79,14 +71,16 @@ neuron iaf_psc_exp: end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end output: spike update: + I_dend *= .95 + if r == 0: # neuron not refractory, so evolve V integrate_odes() else: diff --git a/models/iaf_psc_exp_htum.nestml b/models/neurons/iaf_psc_exp_htum.nestml similarity index 79% rename from models/iaf_psc_exp_htum.nestml rename to models/neurons/iaf_psc_exp_htum.nestml index 8c4f780af..f5b715fbc 100644 --- a/models/iaf_psc_exp_htum.nestml +++ b/models/neurons/iaf_psc_exp_htum.nestml @@ -20,7 +20,7 @@ larger or equal to the absolute refractory time. If equal, the refractoriness of the model if equivalent to the other models of NEST. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -45,44 +45,37 @@ References space analysis of synchronous spiking in cortical neural networks. Neurocomputing 38-40:565-571. DOI: https://doi.org/10.1016/S0925-2312(01)00409-X - -Author -++++++ - -Moritz Helias (March 2006) """ neuron iaf_psc_exp_htum: state: r_tot integer = 0 r_abs integer = 0 - end - initial_values: V_m mV = 0.0 mV # Membrane potential end equations: - kernel I_kernel_in = exp(-1/tau_syn_in*t) - kernel I_kernel_ex = exp(-1/tau_syn_ex*t) - inline I_syn pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + kernel I_kernel_inh = exp(-t / tau_syn_inh) + kernel I_kernel_exc = exp(-t / tau_syn_exc) + inline I_syn pA = convolve(I_kernel_exc, exc_spikes) - convolve(I_kernel_inh, inh_spikes) V_m' = -V_m / tau_m + (I_syn + I_e + I_stim) / C_m end parameters: - C_m pF = 250 pF # Capacity of the membrane - tau_m ms = 10 ms # Membrane time constant. - tau_syn_in ms = 2 ms # Time constant of synaptic current. - tau_syn_ex ms = 2 ms # Time constant of synaptic current. - t_ref_abs ms = 2 ms # absolute refractory period. - # total refractory period - t_ref_tot ms = 2 ms [[t_ref_tot >= t_ref_abs]] # if t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_exp - E_L mV = -70 mV # Resting potential. + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of inhibitory synaptic current + tau_syn_exc ms = 2 ms # Time constant of excitatory synaptic current + t_ref_abs ms = 2 ms # Absolute refractory period + t_ref_tot ms = 2 ms [[t_ref_tot >= t_ref_abs]] # total refractory period + # if t_ref_abs == t_ref_tot iaf_psc_exp_htum equivalent to iaf_psc_exp + E_L mV = -70 mV # Resting potential V_reset mV = -70.0 mV - E_L # Reset value of the membrane potential - # RELATIVE TO RESTING POTENTIAL(!). + # RELATIVE TO RESTING POTENTIAL(!) # I.e. the real threshold is (V_reset + E_L). - V_th mV = -55.0 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL(!). - # I.e. the real threshold is (E_L+V_th). + V_th mV = -55.0 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL(!) + # I.e. the real threshold is (E_L + V_th) # constant external input current I_e pA = 0 pA @@ -110,9 +103,9 @@ neuron iaf_psc_exp_htum: end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end output: spike diff --git a/models/izhikevich.nestml b/models/neurons/izhikevich.nestml similarity index 93% rename from models/izhikevich.nestml rename to models/neurons/izhikevich.nestml index 8052b55c2..c6ed6b744 100644 --- a/models/izhikevich.nestml +++ b/models/neurons/izhikevich.nestml @@ -21,6 +21,8 @@ Implementation of the simple spiking neuron model introduced by Izhikevich [1]_. & \, \\ &v \text{ jumps on each spike arrival by the weight of the spike} +Incoming spikes cause an instantaneous jump in the membrane potential proportional to the strength of the synapse. + As published in [1]_, the numerics differs from the standard forward Euler technique in two ways: 1) the new value of :math:`u` is calculated based on the new value of :math:`v`, rather than the previous value @@ -29,12 +31,6 @@ As published in [1]_, the numerics differs from the standard forward Euler techn This model will instead be simulated using the numerical solver that is recommended by ODE-toolbox during code generation. -Authors -+++++++ - -Hanuschkin, Morrison, Kunkel - - References ++++++++++ @@ -42,7 +38,7 @@ References """ neuron izhikevich: - initial_values: + state: V_m mV = V_m_init # Membrane potential U_m real = b * V_m_init # Membrane potential recovery variable end @@ -66,7 +62,7 @@ neuron izhikevich: input: spikes mV <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike diff --git a/models/izhikevich_psc_alpha.nestml b/models/neurons/izhikevich_psc_alpha.nestml similarity index 58% rename from models/izhikevich_psc_alpha.nestml rename to models/neurons/izhikevich_psc_alpha.nestml index 8043aad36..a9dfbce63 100644 --- a/models/izhikevich_psc_alpha.nestml +++ b/models/neurons/izhikevich_psc_alpha.nestml @@ -35,50 +35,41 @@ References ++++++++++ .. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 - - -Authors -+++++++ - -Hanuschkin, Morrison, Kunkel """ neuron izhikevich_psc_alpha: state: - r integer # number of steps in the current refractory phase - end - - initial_values: + r integer = 0 # Number of steps in the current refractory phase V_m mV = -65 mV # Membrane potential U_m pA = 0 pA # Membrane potential recovery variable end equations: # synapses: alpha functions - kernel I_syn_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - kernel I_syn_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + kernel K_syn_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + kernel K_syn_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) - inline I_syn_exc pA = convolve(I_syn_ex, spikesExc) - inline I_syn_inh pA = convolve(I_syn_in, spikesInh) + inline I_syn_exc pA = convolve(K_syn_exc, exc_spikes) + inline I_syn_inh pA = convolve(K_syn_inh, inh_spikes) - V_m' = ( k * (V_m - V_r) * (V_m - V_t) - U_m + I_e + I_stim + I_syn_inh + I_syn_exc ) / C_m + V_m' = ( k * (V_m - V_r) * (V_m - V_t) - U_m + I_e + I_stim + I_syn_exc - I_syn_inh ) / C_m U_m' = a * ( b*(V_m - V_r) - U_m ) end parameters: - C_m pF = 200. pF # Membrane capacitance - k pF/mV/ms = 8. pF/mV/ms # Spiking slope - V_r mV = -65. mV # resting potential - V_t mV = -45. mV # threshold potential - a 1/ms = 0.01 /ms # describes time scale of recovery variable - b nS = 9. nS # sensitivity of recovery variable - c mV = -65 mV # after-spike reset value of V_m - d pA = 60. pA # after-spike reset value of U_m - V_peak mV = 0. mV # Spike detection threashold (reset condition) - tau_syn_ex ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse - tau_syn_in ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse - t_ref ms = 2.0 ms # Refractory period + C_m pF = 200 pF # Membrane capacitance + k pF/mV/ms = 8 pF/mV/ms # Spiking slope + V_r mV = -65 mV # Resting potential + V_t mV = -45 mV # Threshold potential + a 1/ms = 0.01 /ms # Time scale of recovery variable + b nS = 9 nS # Sensitivity of recovery variable + c mV = -65 mV # After-spike reset value of V_m + d pA = 60 pA # After-spike reset value of U_m + V_peak mV = 0 mV # Spike detection threshold (reset condition) + tau_syn_exc ms = 0.2 ms # Synaptic time constant of excitatory synapse + tau_syn_inh ms = 2 ms # Synaptic time constant of inhibitory synapse + t_ref ms = 2 ms # Refractory period # constant external input current I_e pA = 0 pA @@ -89,9 +80,9 @@ neuron izhikevich_psc_alpha: end input: - spikesInh pA <- inhibitory spike - spikesExc pA <- excitatory spike - I_stim pA <- current + inh_spikes pA <- inhibitory spike + exc_spikes pA <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/mat2_psc_exp.nestml b/models/neurons/mat2_psc_exp.nestml similarity index 64% rename from models/mat2_psc_exp.nestml rename to models/neurons/mat2_psc_exp.nestml index d11a9e5fc..b35f9418c 100644 --- a/models/mat2_psc_exp.nestml +++ b/models/neurons/mat2_psc_exp.nestml @@ -18,7 +18,7 @@ potential exceeds the threshold. The membrane potential is NOT reset, but continuously integrated. .. note:: - If tau_m is very close to tau_syn_ex or tau_syn_in, numerical problems + If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems may arise due to singularities in the propagator matrics. If this is the case, replace equal-valued parameters by a single parameter. @@ -41,49 +41,39 @@ References spiking neuron model equipped with a multi-timescale adaptive threshold. Frontiers in Computuational Neuroscience 3:9. DOI: https://doi.org/10.3389/neuro.10.009.2009 - -Author -++++++ - -Thomas Pfeil (modified iaf_psc_exp model of Moritz Helias) """ neuron mat2_psc_exp: state: - V_th_alpha_1 mV # Two-timescale adaptive threshold - V_th_alpha_2 mV # Two-timescale adaptive threshold - - r integer # counts number of tick during the refractory period - end + V_th_alpha_1 mV = 0 mV # Two-timescale adaptive threshold + V_th_alpha_2 mV = 0 mV # Two-timescale adaptive threshold - initial_values: - V_abs mV = 0 mV # Membrane potential + r integer = 0 # counts number of tick during the refractory period + V_abs mV = 0 mV # Membrane potential V_m mV = V_abs + E_L # Relative membrane potential. # I.e. the real threshold is (V_m-E_L). end equations: - kernel I_kernel_in = exp(-1/tau_syn_in*t) - kernel I_kernel_ex = exp(-1/tau_syn_ex*t) + kernel I_kernel_inh = exp(-t/tau_syn_inh) + kernel I_kernel_exc = exp(-t/tau_syn_exc) - # V_th_alpha_1' = -V_th_alpha_1/tau_1 - # V_th_alpha_2' = -V_th_alpha_2/tau_2 - inline I_syn pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + inline I_syn pA = convolve(I_kernel_exc, exc_spikes) - convolve(I_kernel_inh, inh_spikes) V_abs' = -V_abs / tau_m + (I_syn + I_e + I_stim) / C_m end parameters: - tau_m ms = 5 ms # Membrane time constant - C_m pF = 100 pF # Capacity of the membrane - t_ref ms = 2 ms # Duration of absolute refractory period (no spiking) - E_L mV = -70.0 mV # Resting potential - tau_syn_ex ms = 1 ms # Time constant of postsynaptic excitatory currents - tau_syn_in ms = 3 ms # Time constant of postsynaptic inhibitory currents - tau_1 ms = 10 ms # Short time constant of adaptive threshold - tau_2 ms = 200 ms # Long time constant of adaptive threshold - alpha_1 mV = 37.0 mV # Amplitude of short time threshold adaption [3] - alpha_2 mV = 2.0 mV # Amplitude of long time threshold adaption [3] - omega mV = 19.0 mV # Resting spike threshold (absolute value, not relative to E_L) + tau_m ms = 5 ms # Membrane time constant + C_m pF = 100 pF # Capacitance of the membrane + t_ref ms = 2 ms # Duration of absolute refractory period (no spiking) + E_L mV = -70 mV # Resting potential + tau_syn_exc ms = 1 ms # Time constant of postsynaptic excitatory currents + tau_syn_inh ms = 3 ms # Time constant of postsynaptic inhibitory currents + tau_1 ms = 10 ms # Short time constant of adaptive threshold + tau_2 ms = 200 ms # Long time constant of adaptive threshold + alpha_1 mV = 37 mV # Amplitude of short time threshold adaption [3] + alpha_2 mV = 2 mV # Amplitude of long time threshold adaption [3] + omega mV = 19 mV # Resting spike threshold (absolute value, not relative to E_L) # constant external input current I_e pA = 0 pA @@ -98,9 +88,9 @@ neuron mat2_psc_exp: end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end output: spike diff --git a/models/terub_gpe.nestml b/models/neurons/terub_gpe.nestml similarity index 72% rename from models/terub_gpe.nestml rename to models/neurons/terub_gpe.nestml index d0e49dcb9..be0a70eff 100644 --- a/models/terub_gpe.nestml +++ b/models/neurons/terub_gpe.nestml @@ -27,18 +27,11 @@ References High Frequency Stimulation of the Subthalamic Nucleus Eliminates Pathological Thalamic Rhythmicity in a Computational Model Journal of Computational Neuroscience, 16, 211-235 (2004) - -Author -++++++ - -Martin Ebert """ neuron terub_gpe: state: - r integer # counts number of tick during the refractory period - end + r integer = 0 # counts number of ticks during the refractory period - initial_values: V_m mV = E_L # Membrane potential gate_h real = 0.0 # gating variable h @@ -84,8 +77,8 @@ neuron terub_gpe: inline g_k_Ca real = 15.0 #Report:15, Terman Rubin 2002: 20.0 inline g_k1 real = 30.0 - inline I_ex_mod real = -convolve(g_ex, spikeExc) * V_m - inline I_in_mod real = convolve(g_in, spikeInh) * (V_m-E_gg) + inline I_exc_mod real = -convolve(g_exc, exc_spikes) * V_m + inline I_inh_mod real = convolve(g_inh, inh_spikes) * (V_m-E_gg) inline tau_n real = g_tau_n_0 + g_tau_n_1 / (1. + exp(-(V_m-g_theta_n_tau)/g_sigma_n_tau)) inline tau_h real = g_tau_h_0 + g_tau_h_1 / (1. + exp(-(V_m-g_theta_h_tau)/g_sigma_h_tau)) @@ -106,39 +99,39 @@ neuron terub_gpe: inline I_ahp real = g_ahp * (Ca_con / (Ca_con + g_k1)) * (V_m - E_K ) # synapses: alpha functions - ## alpha function for the g_in - kernel g_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - ## alpha function for the g_ex - kernel g_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + ## alpha function for the g_inh + kernel g_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + ## alpha function for the g_exc + kernel g_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) # V dot -- synaptic input are currents, inhib current is negative - V_m' = ( -(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) * pA + I_e + I_stim + I_ex_mod * pA + I_in_mod * pA) / C_m + V_m' = ( -(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) * pA + I_e + I_stim + I_exc_mod * pA + I_inh_mod * pA) / C_m # channel dynamics - gate_h' = g_phi_h *((h_inf-gate_h) / tau_h) / ms # h-variable - gate_n' = g_phi_n *((n_inf-gate_n) / tau_n) / ms # n-variable - gate_r' = g_phi_r *((r_inf-gate_r) / tau_r) / ms # r-variable + gate_h' = g_phi_h * ((h_inf - gate_h) / tau_h) / ms # h-variable + gate_n' = g_phi_n * ((n_inf - gate_n) / tau_n) / ms # n-variable + gate_r' = g_phi_r * ((r_inf - gate_r) / tau_r) / ms # r-variable # Calcium concentration Ca_con' = g_epsilon*(-I_Ca - I_T - g_k_Ca * Ca_con) end parameters: - E_L mV = -55 mV # Resting membrane potential. - g_L nS = 0.1 nS # Leak conductance. - C_m pF = 1.0 pF # Capacity of the membrane. - E_Na mV = 55 mV # Sodium reversal potential. - g_Na nS = 120 nS # Sodium peak conductance. - E_K mV = -80.0 mV# Potassium reversal potential. - g_K nS = 30.0 nS # Potassium peak conductance. - E_Ca mV = 120 mV # Calcium reversal potential. - g_Ca nS = 0.15 nS # Calcium peak conductance. - g_T nS = 0.5 nS # T-type Calcium channel peak conductance. - g_ahp nS = 30 nS # afterpolarization current peak conductance. - tau_syn_ex ms = 1.0 ms # Rise time of the excitatory synaptic alpha function. - tau_syn_in ms = 12.5 ms # Rise time of the inhibitory synaptic alpha function. - E_gg mV = -100 mV # reversal potential for inhibitory input (from GPe) - t_ref ms = 2 ms # refractory time + E_L mV = -55 mV # Resting membrane potential + g_L nS = 0.1 nS # Leak conductance + C_m pF = 1 pF # Capacitance of the membrane + E_Na mV = 55 mV # Sodium reversal potential + g_Na nS = 120 nS # Sodium peak conductance + E_K mV = -80.0 mV # Potassium reversal potential + g_K nS = 30.0 nS # Potassium peak conductance + E_Ca mV = 120 mV # Calcium reversal potential + g_Ca nS = 0.15 nS # Calcium peak conductance + g_T nS = 0.5 nS # T-type Calcium channel peak conductance + g_ahp nS = 30 nS # Afterpolarization current peak conductance + tau_syn_exc ms = 1 ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 12.5 ms # Rise time of the inhibitory synaptic alpha function + E_gg mV = -100 mV # Reversal potential for inhibitory input (from GPe) + t_ref ms = 2 ms # Refractory time # constant external input current I_e pA = 0 pA @@ -149,9 +142,9 @@ neuron terub_gpe: end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/terub_stn.nestml b/models/neurons/terub_stn.nestml similarity index 76% rename from models/terub_stn.nestml rename to models/neurons/terub_stn.nestml index 16e8c4b2f..2d1df218e 100644 --- a/models/terub_stn.nestml +++ b/models/neurons/terub_stn.nestml @@ -24,19 +24,11 @@ References .. [2] Rubin, J.E. and Terman, D. High Frequency Stimulation of the Subthalamic Nucleus Eliminates Pathological Thalamic Rhythmicity in a Computational Model Journal of Computational Neuroscience, 16, 211-235 (2004) - - -Author -++++++ - -Martin Ebert """ neuron terub_stn: state: - r integer # counts number of tick during the refractory period - end + r integer = 0 # counts number of tick during the refractory period - initial_values: V_m mV = E_L # Membrane potential gate_h real = 0.0 # gating variable h gate_n real = 0.0 # gating variable n @@ -90,8 +82,8 @@ neuron terub_stn: inline k_Ca real = 22.5 inline k1 real = 15.0 - inline I_ex_mod pA = -convolve(g_ex, spikeExc) * V_m - inline I_in_mod pA = convolve(g_in, spikeInh) * (V_m - E_gs) + inline I_exc_mod pA = -convolve(g_exc, exc_spikes) * V_m + inline I_inh_mod pA = convolve(g_inh, inh_spikes) * (V_m - E_gs) inline tau_n ms = tau_n_0 + tau_n_1 / (1. + exp(-(V_m-theta_n_tau)/sigma_n_tau)) inline tau_h ms = tau_h_0 + tau_h_1 / (1. + exp(-(V_m-theta_h_tau)/sigma_h_tau)) @@ -113,7 +105,7 @@ neuron terub_stn: inline I_ahp pA = g_ahp * (Ca_con / (Ca_con + k1)) * (V_m - E_K ) # V dot -- synaptic input are currents, inhib current is negative - V_m' = ( -(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) + I_e + I_stim + I_ex_mod + I_in_mod) / C_m + V_m' = ( -(I_Na + I_K + I_L + I_T + I_Ca + I_ahp) + I_e + I_stim + I_exc_mod + I_inh_mod) / C_m #channel dynamics gate_h' = phi_h *((h_inf-gate_h) / tau_h) # h-variable @@ -124,28 +116,28 @@ neuron terub_stn: Ca_con' = epsilon*( (-I_Ca - I_T ) / pA - k_Ca * Ca_con) # synapses: alpha functions - ## alpha function for the g_in - kernel g_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - ## alpha function for the g_ex - kernel g_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + ## alpha function for the g_inh + kernel g_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + ## alpha function for the g_exc + kernel g_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) end parameters: - E_L mV = -60 mV # Resting membrane potential. - g_L nS = 2.25 nS # Leak conductance. - C_m pF = 1.0 pF # Capacity of the membrane. - E_Na mV = 55 mV # Sodium reversal potential. - g_Na nS = 37.5 nS # Sodium peak conductance. - E_K mV = -80.0 mV# Potassium reversal potential. - g_K nS = 45.0 nS # Potassium peak conductance. - E_Ca mV = 140 mV # Calcium reversal potential. - g_Ca nS = 0.5 nS # Calcium peak conductance. - g_T nS = 0.5 nS # T-type Calcium channel peak conductance. - g_ahp nS = 9 nS # afterpolarization current peak conductance. - tau_syn_ex ms = 1.0 ms # Rise time of the excitatory synaptic alpha function. - tau_syn_in ms = 0.08 ms # Rise time of the inhibitory synaptic alpha function. - E_gs mV = -85.0 mV# reversal potential for inhibitory input (from GPe) - t_ref ms = 2 ms # refractory time + E_L mV = -60 mV # Resting membrane potential + g_L nS = 2.25 nS # Leak conductance + C_m pF = 1 pF # Capacity of the membrane + E_Na mV = 55 mV # Sodium reversal potential + g_Na nS = 37.5 nS # Sodium peak conductance + E_K mV = -80 mV # Potassium reversal potential + g_K nS = 45 nS # Potassium peak conductance + E_Ca mV = 140 mV # Calcium reversal potential + g_Ca nS = 0.5 nS # Calcium peak conductance + g_T nS = 0.5 nS # T-type Calcium channel peak conductance + g_ahp nS = 9 nS # Afterpolarization current peak conductance + tau_syn_exc ms = 1 ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 0.08 ms # Rise time of the inhibitory synaptic alpha function + E_gs mV = -85 mV # Reversal potential for inhibitory input (from GPe) + t_ref ms = 2 ms # Refractory time # constant external input current I_e pA = 0 pA @@ -156,9 +148,9 @@ neuron terub_stn: end input: - spikeInh pA <- inhibitory spike - spikeExc pA <- excitatory spike - I_stim pA <- current + inh_spikes pA <- inhibitory spike + exc_spikes pA <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/traub_cond_multisyn.nestml b/models/neurons/traub_cond_multisyn.nestml similarity index 82% rename from models/traub_cond_multisyn.nestml rename to models/neurons/traub_cond_multisyn.nestml index f59caf09f..4a4c31f30 100644 --- a/models/traub_cond_multisyn.nestml +++ b/models/neurons/traub_cond_multisyn.nestml @@ -1,40 +1,39 @@ """ -Name: traub_cond_multisyn - Traub model according to Borgers 2017. +traub_cond_multisyn - Traub model according to Borgers 2017 +########################################################### -Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus[1]. -parameters got from reference [2] chapter 5. +Description ++++++++++++ +Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. +parameters got from reference [2]_ chapter 5. -Spike Detection - Spike detection is done by a combined threshold-and-local-maximum search: if - there is a local maximum above a certain threshold of the membrane potential, - it is considered a spike. +AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with +beta-function (difference of two exponentials) time course corresponding +to "hill_tononi" model. -- AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with - beta-function (difference of two exponentials) time course corresponding - to "hill_tononi" model. +References +++++++++++ -References: +.. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. +.. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. -[1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. -[2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. +See also +++++++++ -SeeAlso: hh_cond_exp_traub +hh_cond_exp_traub """ - neuron traub_cond_multisyn: state: - r integer # number of steps in the current refractory phase - end + r integer = 0 # number of steps in the current refractory phase - initial_values: V_m mV = -70. mV # Membrane potential - Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m for Na + Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m for Na Inact_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) # Inactivation variable h for Na - Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) # Activation variable n for K + Act_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) # Activation variable n for K g_AMPA real = 0 g_NMDA real = 0 @@ -51,12 +50,12 @@ neuron traub_cond_multisyn: recordable inline I_syn_nmda pA = -convolve(g_NMDA, NMDA) * ( V_m - NMDA_E_rev ) / ( 1 + exp( ( NMDA_Vact - V_m ) / NMDA_Sact ) ) recordable inline I_syn_gaba_a pA = -convolve(g_GABAA, GABA_A) * ( V_m - GABA_A_E_rev ) recordable inline I_syn_gaba_b pA = -convolve(g_GABAB, GABA_B) * ( V_m - GABA_B_E_rev ) - recordable inline I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b - + recordable inline I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * ( V_m - E_Na ) - inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * ( V_m - E_K ) + inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) - + V_m' = ( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn ) / C_m # Act_n @@ -73,7 +72,7 @@ neuron traub_cond_multisyn: inline alpha_h real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) inline beta_h real = 4.0 / (1.0 + exp(-(V_m / mV + 27.) / 5.)) Inact_h' = ( alpha_h * ( 1 - Inact_h ) - beta_h * Inact_h ) / ms # h-variable - + ############# # Synapses ############# @@ -101,25 +100,25 @@ neuron traub_cond_multisyn: E_K mV = -100. mV # Potassium reversal potentia E_L mV = -67. mV # Leak reversal Potential (aka resting potential) V_Tr mV = -20. mV # Spike Threshold - + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA AMPA_g_peak nS = 0.1 nS # peak conductance AMPA_E_rev mV = 0.0 mV # reversal potential tau_AMPA_1 ms = 0.5 ms # rise time tau_AMPA_2 ms = 2.4 ms # decay time, Tau_1 < Tau_2 - + NMDA_g_peak nS = 0.075 nS # peak conductance tau_NMDA_1 ms = 4.0 ms # rise time tau_NMDA_2 ms = 40.0 ms # decay time, Tau_1 < Tau_2 NMDA_E_rev mV = 0.0 mV # reversal potential NMDA_Vact mV = -58.0 mV # inactive for V << Vact, inflection of sigmoid NMDA_Sact mV = 2.5 mV # scale of inactivation - + GABA_A_g_peak nS = 0.33 nS # peak conductance tau_GABAA_1 ms = 1.0 ms # rise time tau_GABAA_2 ms = 7.0 ms # decay time, Tau_1 < Tau_2 GABA_A_E_rev mV = -70.0 mV # reversal potential - + GABA_B_g_peak nS = 0.0132 nS # peak conductance tau_GABAB_1 ms = 60.0 ms # rise time tau_GABAB_2 ms = 200.0 ms # decay time, Tau_1 < Tau_2 @@ -129,17 +128,17 @@ neuron traub_cond_multisyn: I_e pA = 0 pA end - internals: + internals: AMPAInitialValue real = compute_synapse_constant( tau_AMPA_1, tau_AMPA_2, AMPA_g_peak ) NMDAInitialValue real = compute_synapse_constant( tau_NMDA_1, tau_NMDA_2, NMDA_g_peak ) GABA_AInitialValue real = compute_synapse_constant( tau_GABAA_1, tau_GABAA_2, GABA_A_g_peak ) GABA_BInitialValue real = compute_synapse_constant( tau_GABAB_1, tau_GABAB_2, GABA_B_g_peak ) RefractoryCounts integer = steps(t_ref) # refractory time in steps - alpha_n_init real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.)) - beta_n_init real = 0.5 * exp(-(V_m / mV + 57.) / 40.) - alpha_m_init real = 0.32 * (V_m / mV + 54.) / (1.0 - exp(-(V_m / mV + 54.) / 4.)) - beta_m_init real = 0.28 * (V_m / mV + 27.) / (exp((V_m / mV + 27.) / 5.) - 1.) + alpha_n_init real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.)) + beta_n_init real = 0.5 * exp(-(V_m / mV + 57.) / 40.) + alpha_m_init real = 0.32 * (V_m / mV + 54.) / (1.0 - exp(-(V_m / mV + 54.) / 4.)) + beta_m_init real = 0.28 * (V_m / mV + 27.) / (exp((V_m / mV + 27.) / 5.) - 1.) alpha_h_init real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) beta_h_init real = 4.0 / (1.0 + exp(-(V_m / mV + 27.) / 5.)) end @@ -149,7 +148,7 @@ neuron traub_cond_multisyn: NMDA nS <- spike GABA_A nS <- spike GABA_B nS <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike @@ -158,7 +157,7 @@ neuron traub_cond_multisyn: U_old mV = V_m integrate_odes() - # sending spikes: + # sending spikes: if r > 0: # is refractory? r -= 1 elif V_m > V_Tr and U_old > V_Tr: # threshold && maximum diff --git a/models/traub_psc_alpha.nestml b/models/neurons/traub_psc_alpha.nestml similarity index 52% rename from models/traub_psc_alpha.nestml rename to models/neurons/traub_psc_alpha.nestml index c5d5c9f5d..f4ebf4edf 100644 --- a/models/traub_psc_alpha.nestml +++ b/models/neurons/traub_psc_alpha.nestml @@ -1,33 +1,29 @@ """ -Name: traub_psc_alpha - Traub model according to Borgers 2017. +traub_psc_alpha - Traub model according to Borgers 2017 +####################################################### -Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus[1]. -parameters got from reference [2]. +Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. +parameters got from reference [2]_. -(1) Post-synaptic currents - Incoming spike events induce a post-synaptic change of current modelled - by an alpha function. +Incoming spike events induce a post-synaptic change of current modelled +by an alpha function. -(2) Spike Detection - Spike detection is done by a combined threshold-and-local-maximum search: if - there is a local maximum above a certain threshold of the membrane potential, - it is considered a spike. +References +++++++++++ +.. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. +.. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. -References: -[1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. -[2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. +See also +++++++++ - -SeeAlso: hh_cond_exp_traub +hh_cond_exp_traub """ neuron traub_psc_alpha: state: - r integer # number of steps in the current refractory phase - end + r integer = 0 # number of steps in the current refractory phase - initial_values: V_m mV = -70. mV # Membrane potential Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m for Na @@ -37,15 +33,15 @@ neuron traub_psc_alpha: equations: # synapses: alpha functions - kernel I_syn_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) - kernel I_syn_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) + kernel K_syn_inh = (e/tau_syn_inh) * t * exp(-t/tau_syn_inh) + kernel K_syn_exc = (e/tau_syn_exc) * t * exp(-t/tau_syn_exc) - inline I_syn_exc pA = convolve(I_syn_ex, spikeExc) - inline I_syn_inh pA = convolve(I_syn_in, spikeInh) + inline I_syn_exc pA = convolve(K_syn_exc, exc_spikes) + inline I_syn_inh pA = convolve(K_syn_inh, inh_spikes) inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Inact_h * ( V_m - E_Na ) inline I_K pA = g_K * Act_n * Act_n * Act_n * Act_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) - V_m' = ( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_inh + I_syn_exc ) / C_m + V_m' = ( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_exc - I_syn_inh ) / C_m # Act_n inline alpha_n real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.)) @@ -64,17 +60,17 @@ neuron traub_psc_alpha: end parameters: - t_ref ms = 2.0 ms # Refractory period 2.0 - g_Na nS = 10000.0 nS # Sodium peak conductance - g_K nS = 8000.0 nS # Potassium peak conductance - g_L nS = 10 nS # Leak conductance - C_m pF = 100.0 pF # Membrane Capacitance - E_Na mV = 50. mV # Sodium reversal potential - E_K mV = -100. mV # Potassium reversal potentia - E_L mV = -67. mV # Leak reversal Potential (aka resting potential) - V_Tr mV = -20. mV # Spike Threshold - tau_syn_ex ms = 0.2 ms # Rise time of the excitatory synaptic alpha function - tau_syn_in ms = 2. ms # Rise time of the inhibitory synaptic alpha function + t_ref ms = 2 ms # Refractory period + g_Na nS = 10000 nS # Sodium peak conductance + g_K nS = 8000 nS # Potassium peak conductance + g_L nS = 10 nS # Leak conductance + C_m pF = 100 pF # Membrane capacitance + E_Na mV = 50 mV # Sodium reversal potential + E_K mV = -100 mV # Potassium reversal potential + E_L mV = -67 mV # Leak reversal potential (aka resting potential) + V_Tr mV = -20 mV # Spike threshold + tau_syn_exc ms = 0.2 ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 2 ms # Rise time of the inhibitory synaptic alpha function # constant external input current I_e pA = 0 pA @@ -83,18 +79,18 @@ neuron traub_psc_alpha: internals: RefractoryCounts integer = steps(t_ref) # refractory time in steps - alpha_n_init real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.)) - beta_n_init real = 0.5 * exp(-(V_m / mV + 57.) / 40.) - alpha_m_init real = 0.32 * (V_m / mV + 54.) / (1.0 - exp(-(V_m / mV + 54.) / 4.)) - beta_m_init real = 0.28 * (V_m / mV + 27.) / (exp((V_m / mV + 27.) / 5.) - 1.) + alpha_n_init real = 0.032 * (V_m / mV + 52.) / (1. - exp(-(V_m / mV + 52.) / 5.)) + beta_n_init real = 0.5 * exp(-(V_m / mV + 57.) / 40.) + alpha_m_init real = 0.32 * (V_m / mV + 54.) / (1.0 - exp(-(V_m / mV + 54.) / 4.)) + beta_m_init real = 0.28 * (V_m / mV + 27.) / (exp((V_m / mV + 27.) / 5.) - 1.) alpha_h_init real = 0.128 * exp(-(V_m / mV + 50.0) / 18.0) beta_h_init real = 4.0 / (1.0 + exp(-(V_m / mV + 27.) / 5.)) end input: - spikeInh pA <- inhibitory spike - spikeExc pA <- excitatory spike - I_stim pA <- current + inh_spikes pA <- inhibitory spike + exc_spikes pA <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/wb_cond_exp.nestml b/models/neurons/wb_cond_exp.nestml similarity index 66% rename from models/wb_cond_exp.nestml rename to models/neurons/wb_cond_exp.nestml index 8b548a5c3..421da29f9 100644 --- a/models/wb_cond_exp.nestml +++ b/models/neurons/wb_cond_exp.nestml @@ -28,10 +28,8 @@ hh_cond_exp_traub, wb_cond_multisyn """ neuron wb_cond_exp: state: - r integer # number of steps in the current refractory phase - end + r integer = 0 # number of steps in the current refractory phase - initial_values: V_m mV = E_L # Membrane potential Inact_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) @@ -40,35 +38,35 @@ neuron wb_cond_exp: equations: # synapses: exponential conductance - kernel g_in = exp(-1.0 / tau_syn_in * t) - kernel g_ex = exp(-1.0 / tau_syn_ex * t) + kernel g_inh = exp(-t / tau_syn_inh) + kernel g_exc = exp(-t / tau_syn_exc) - recordable inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - recordable inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + recordable inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) + recordable inline I_syn_inh pA = convolve(g_inh, inh_spikes) * ( V_m - E_inh ) inline I_Na pA = g_Na * _subexpr(V_m) * Inact_h * ( V_m - E_Na ) - inline I_K pA = g_K * Act_n**4 * ( V_m - E_K ) + inline I_K pA = g_K * Act_n**4 * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) - V_m' =( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_inh + I_syn_exc ) / C_m + V_m' =( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_exc - I_syn_inh ) / C_m Act_n' = ( alpha_n(V_m) * ( 1 - Act_n ) - beta_n(V_m) * Act_n ) # n-variable Inact_h' = ( alpha_h(V_m) * ( 1 - Inact_h ) - beta_h(V_m) * Inact_h ) # h-variable end parameters: - t_ref ms = 2.0 ms # Refractory period - g_Na nS = 3500.0 nS # Sodium peak conductance - g_K nS = 900.0 nS # Potassium peak conductance - g_L nS = 10 nS # Leak conductance - C_m pF = 100.0 pF # Membrane Capacitance - E_Na mV = 55.0 mV # Sodium reversal potential - E_K mV = -90.0 mV # Potassium reversal potentia - E_L mV = -65.0 mV # Leak reversal Potential (aka resting potential) - V_Tr mV = -55.0 mV # Spike Threshold - tau_syn_ex ms = 0.2 ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 10.0 ms # Rise time of the inhibitory synaptic alpha function - E_ex mV = 0.0 mV # Excitatory synaptic reversal potential - E_in mV = -75.0 mV # Inhibitory synaptic reversal potential + t_ref ms = 2 ms # Refractory period + g_Na nS = 3500 nS # Sodium peak conductance + g_K nS = 900 nS # Potassium peak conductance + g_L nS = 10 nS # Leak conductance + C_m pF = 100 pF # Membrane capacitance + E_Na mV = 55 mV # Sodium reversal potential + E_K mV = -90 mV # Potassium reversal potential + E_L mV = -65 mV # Leak reversal potential (aka resting potential) + V_Tr mV = -55 mV # Spike threshold + tau_syn_exc ms = 0.2 ms # Rise time of the excitatory synaptic alpha function + tau_syn_inh ms = 10 ms # Rise time of the inhibitory synaptic alpha function + E_exc mV = 0 mV # Excitatory synaptic reversal potential + E_inh mV = -75 mV # Inhibitory synaptic reversal potential # constant external input current I_e pA = 0 pA @@ -84,9 +82,9 @@ neuron wb_cond_exp: end input: - spikeInh nS <- inhibitory spike - spikeExc nS <- excitatory spike - I_stim pA <- current + inh_spikes nS <- inhibitory spike + exc_spikes nS <- excitatory spike + I_stim pA <- continuous end output: spike diff --git a/models/wb_cond_multisyn.nestml b/models/neurons/wb_cond_multisyn.nestml similarity index 98% rename from models/wb_cond_multisyn.nestml rename to models/neurons/wb_cond_multisyn.nestml index 61e6a3847..d629ae9d0 100644 --- a/models/wb_cond_multisyn.nestml +++ b/models/neurons/wb_cond_multisyn.nestml @@ -29,10 +29,8 @@ wb_cond_multisyn neuron wb_cond_multisyn: state: - r integer # number of steps in the current refractory phase - end + r integer = 0 # number of steps in the current refractory phase - initial_values: V_m mV = -65. mV # Membrane potential Inact_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) # Inactivation variable h for Na Act_n real = alpha_n_init / (alpha_n_init + beta_n_init) # Activation variable n for K @@ -138,7 +136,7 @@ neuron wb_cond_multisyn: NMDA nS <- spike GABA_A nS <- spike GABA_B nS <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike diff --git a/models/syn_not_so_minimal.nestml b/models/syn_not_so_minimal.nestml new file mode 100644 index 000000000..c9941d071 --- /dev/null +++ b/models/syn_not_so_minimal.nestml @@ -0,0 +1,79 @@ +""" +syn_not_so_minimal - +######################################################################### + +Description ++++++++++++ + +References +++++++++++ + + +See also +++++++++ + + +Author +++++++ + +pythonjam +""" + + +neuron not_so_minimal: + + state: + # the presence of the state variable [v_comp] + # triggers compartment model context + v_comp real = 0 + end + + equations: + #synapses are inlines that utilize kernels + kernel g_ex_AMPA = exp(-t / tau_syn_AMPA) + inline AMPA real = convolve(g_ex_AMPA, b_spikes) * (e_AMPA - v_comp ) + + kernel g_ex_NMDA = exp(-t / tau_syn_NMDA) + inline NMDA real = convolve(g_ex_NMDA, b_spikes) * (e_NMDA - v_comp ) * (1. / ( 1. + 0.3 * exp( -.1 * v_comp ) )) + + inline AMPA_NMDA real = convolve(g_ex_NMDA, b_spikes) * (e_NMDA - v_comp ) * (1. / ( 1. + 0.3 * exp( -.1 * v_comp ) )) + NMDA_ratio_ * convolve(g_ex_AMPA, b_spikes) * (v_comp - e_AMPA) + + kernel g_exc = g_norm_exc * ( - exp(-t / tau_r) + exp(-t / tau_d) ) + inline I_syn_exc real = convolve(g_exc, spikesExc) * (E_exc - v_comp ) + + end + + parameters: + + # synaptic parameters + e_AMPA mV = 0 mV # Excitatory reversal Potential + tau_syn_AMPA ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse + + e_NMDA real = 0.0 # Excitatory reversal Potential + tau_syn_NMDA real = 0.2 # Synaptic Time Constant Excitatory Synapse + + e_AMPA_NMDA real = 0.0 # Excitatory reversal Potential + NMDA_ratio_ real = 2.0 # Synaptic Time Constant Excitatory Synapse + + E_exc mV = 0 mV # Excitatory reversal Potential + tau_r ms = 0.2 ms # Synaptic Rise Time Constant Excitatory Synapse + tau_d ms = 3. ms # Synaptic Decay Time Constant Excitatory Synapse + + end + + # NMDA + function NMDA_sigmoid(v_comp real) real: + return 1. / ( 1. + 0.3 * exp( -.1 * v_comp ) ) + end + + internals: + g_norm_exc real = 1. / ( -exp( -tp / tau_r ) + exp( -tp / tau_d ) ) + tp real = (tau_r * tau_d) / (tau_d - tau_r) * ln( tau_d / tau_r ) + end + + input: + b_spikes nS <- excitatory spike + spikesExc nS <- excitatory spike + end + +end \ No newline at end of file diff --git a/models/synapses/neuromodulated_stdp.nestml b/models/synapses/neuromodulated_stdp.nestml new file mode 100644 index 000000000..f5a734c83 --- /dev/null +++ b/models/synapses/neuromodulated_stdp.nestml @@ -0,0 +1,97 @@ +""" +neuromodulated_stdp - Synapse model for spike-timing dependent plasticity modulated by a neurotransmitter such as dopamine +########################################################################################################################## + +Description ++++++++++++ + +stdp_dopamine_synapse is a connection to create synapses with +dopamine-modulated spike-timing dependent plasticity (used as a +benchmark model in [1]_, based on [2]_). The dopaminergic signal is a +low-pass filtered version of the spike rate of a user-specific pool +of neurons. The spikes emitted by the pool of dopamine neurons are +delivered to the synapse via the assigned volume transmitter. The +dopaminergic dynamics is calculated in the synapse itself. + +References +++++++++++ +.. [1] Potjans W, Morrison A, Diesmann M (2010). Enabling functional neural + circuit simulations with distributed computing of neuromodulated + plasticity. Frontiers in Computational Neuroscience, 4:141. + DOI: https://doi.org/10.3389/fncom.2010.00141 +.. [2] Izhikevich EM (2007). Solving the distal reward problem through linkage + of STDP and dopamine signaling. Cerebral Cortex, 17(10):2443-2452. + DOI: https://doi.org/10.1093/cercor/bhl152 +""" +synapse neuromodulated_stdp: + + state: + w real = 1. + n real = 0. # Neuromodulator concentration + c real = 0. # Eligibility trace + pre_tr real = 0. + post_tr real = 0. + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + tau_tr_pre ms = 20 ms # STDP time constant for weight changes caused by pre-before-post spike pairings. + tau_tr_post ms = 20 ms # STDP time constant for weight changes caused by post-before-pre spike pairings. + tau_c ms = 1000 ms # Time constant of eligibility trace + tau_n ms = 200 ms # Time constant of dopaminergic trace + b real = 0. # Dopaminergic baseline concentration + Wmax real = 200. # Maximal synaptic weight + Wmin real = 0. # Minimal synaptic weight + A_plus real = 1. # Multiplier applied to weight changes caused by pre-before-post spike pairings. If b (dopamine baseline concentration) is zero, then A_plus is simply the multiplier for facilitation (as in the stdp_synapse model). If b is not zero, then A_plus will be the multiplier for facilitation only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_plus will be the multiplier for depression. + A_minus real = 1.5 # Multiplier applied to weight changes caused by post-before-pre spike pairings. If b (dopamine baseline concentration) is zero, then A_minus is simply the multiplier for depression (as in the stdp_synapse model). If b is not zero, then A_minus will be the multiplier for depression only if n - b is positive, where n is the instantenous dopamine concentration in the volume transmitter. If n - b is negative, A_minus will be the multiplier for facilitation. + end + + equations: + pre_tr' = -pre_tr / tau_tr_pre + post_tr' = -post_tr / tau_tr_post + end + + internals: + tau_s 1/ms = (tau_c + tau_n) / (tau_c * tau_n) + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + mod_spikes real <- spike + end + + output: spike + + onReceive(mod_spikes): + n += 1. / tau_n + end + + onReceive(post_spikes): + post_tr += 1. + + # facilitation + c += A_plus * pre_tr + end + + onReceive(pre_spikes): + pre_tr += 1. + + # depression + c -= A_minus * post_tr + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + + # update from time t to t + resolution() + update: + # resolution() returns the timestep to be made (in units of time) + # the sequence here matters: the update step for w requires the "old" values of c and n + w -= c * ( n / tau_s * expm1( -tau_s * resolution() ) \ + - b * tau_c * expm1( -resolution() / tau_c )) + c = c * exp(-resolution() / tau_c) + n = n * exp(-resolution() / tau_n) + end + +end diff --git a/models/synapses/noisy_synapse.nestml b/models/synapses/noisy_synapse.nestml new file mode 100644 index 000000000..201baaf71 --- /dev/null +++ b/models/synapses/noisy_synapse.nestml @@ -0,0 +1,36 @@ +""" +noisy_synapse - Static synapse with Gaussian noise +################################################## + +Description ++++++++++++ + +Each presynaptic spike is passed to the postsynaptic partner with a weight sampled as :math:`w + A_\text{noise} \mathcal{N}(0, 1)`. +""" +synapse noisy_synapse: + + state: + w nS = 1 nS + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + A_noise real = .4 + end + + input: + pre_spikes nS <- spike + end + + output: spike + + onReceive(pre_spikes): + # temporary variable for the "weight" that will be transmitted + w_ nS = w + A_noise * random_normal(0, 1) + + # deliver spike to postsynaptic partner + deliver_spike(w_, the_delay) + end + +end + diff --git a/models/synapses/static_synapse.nestml b/models/synapses/static_synapse.nestml new file mode 100644 index 000000000..8a30b14aa --- /dev/null +++ b/models/synapses/static_synapse.nestml @@ -0,0 +1,26 @@ +""" +Static synapse +############## + +Description ++++++++++++ +A synapse where the synaptic strength (weight) does not evolve with simulated time, but is defined as a (constant) parameter. +""" +synapse static: + + parameters: + w real = 900 @nest::weight @homogeneous + d ms = .9 ms @nest::delay @heterogeneous + a real = 3.141592653589793 @nest::a @homogeneous + b real = 100. @nest::b @heterogeneous + end + + input: + pre_spikes mV <- spike + end + + onReceive(pre_spikes): + deliver_spike(3.18E-3 * a * b * w, d) + end + +end diff --git a/models/synapses/stdp_nn_pre_centered.nestml b/models/synapses/stdp_nn_pre_centered.nestml new file mode 100644 index 000000000..34812d184 --- /dev/null +++ b/models/synapses/stdp_nn_pre_centered.nestml @@ -0,0 +1,109 @@ +""" +stdp_nn_pre_centered - Synapse type for spike-timing dependent plasticity, with nearest-neighbour spike pairing +############################################################################################################### + +Description ++++++++++++ + +stdp_nn_pre_centered_synapse is a connector to create synapses with spike +time dependent plasticity with the presynaptic-centered nearest-neighbour +spike pairing scheme, as described in [1]_. + +Each presynaptic spike is taken into account in the STDP weight change rule +with the nearest preceding postsynaptic one and the nearest succeeding +postsynaptic one (instead of pairing with all spikes, like in stdp_synapse). +So, when a presynaptic spike occurs, it is accounted in the depression rule +with the nearest preceding postsynaptic one; and when a postsynaptic spike +occurs, it is accounted in the facilitation rule with all preceding +presynaptic spikes that were not earlier than the previous postsynaptic +spike. For a clear illustration of this scheme see fig. 7B in [2]_. + +The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike ++ dendritic_delay), leading to zero delta_t, are discarded. In this case the +concerned pre/postsynaptic spike is paired with the second latest preceding +post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +result in a potentiation pair 20-to-10). + +The implementation involves two additional variables - presynaptic and +postsynaptic traces [2]_. The presynaptic trace decays exponentially over +time with the time constant tau_plus, increases by 1 on a pre-spike +occurrence, and is reset to 0 on a post-spike occurrence. The postsynaptic +trace (implemented on the postsynaptic neuron side) decays with the time +constant tau_minus and increases to 1 on a post-spike occurrence. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner + + Original caption: + + Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) + + +References +++++++++++ + +.. [1] Izhikevich E. M., Desai N. S. (2003) Relating STDP to BCM, + Neural Comput. 15, 1511--1523 + +.. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 +""" +synapse stdp_nn_pre_centered: + + state: + w real = 1 + pre_trace real = 0. + post_trace real = 0. + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + lambda real = .01 + tau_tr_pre ms = 20 ms + tau_tr_post ms = 20 ms + alpha real = 1. + mu_plus real = 1. + mu_minus real = 1. + Wmax real = 100. + Wmin real = 0. + end + + equations: + # nearest-neighbour trace of presynaptic neuron + pre_trace' = -pre_trace / tau_tr_pre + + # nearest-neighbour trace of postsynaptic neuron + post_trace' = -post_trace / tau_tr_post + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + onReceive(post_spikes): + post_trace = 1 + + # potentiate synapse + w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace )) + w = min(Wmax, w_) + + pre_trace = 0 + end + + onReceive(pre_spikes): + pre_trace += 1 + + # depress synapse + w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace )) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end diff --git a/models/synapses/stdp_nn_restr_symm.nestml b/models/synapses/stdp_nn_restr_symm.nestml new file mode 100644 index 000000000..d98bfb253 --- /dev/null +++ b/models/synapses/stdp_nn_restr_symm.nestml @@ -0,0 +1,107 @@ +""" +Synapse type for spike-timing dependent plasticity with restricted symmetric nearest-neighbour spike pairing scheme +################################################################################################################### + +Description ++++++++++++ + +stdp_nn_restr_synapse is a connector to create synapses with spike time +dependent plasticity with the restricted symmetric nearest-neighbour spike +pairing scheme (fig. 7C in [1]_). + +When a presynaptic spike occurs, it is taken into account in the depression +part of the STDP weight change rule with the nearest preceding postsynaptic +one, but only if the latter occured not earlier than the previous presynaptic +one. When a postsynaptic spike occurs, it is accounted in the facilitation +rule with the nearest preceding presynaptic one, but only if the latter +occured not earlier than the previous postsynaptic one. So, a spike can +participate neither in two depression pairs nor in two potentiation pairs. +The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike ++ dendritic_delay), leading to zero delta_t, are discarded. In this case the +concerned pre/postsynaptic spike is paired with the second latest preceding +post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +result in a potentiation pair 20-to-10). + +The implementation relies on an additional variable - the postsynaptic +eligibility trace [1]_ (implemented on the postsynaptic neuron side). It +decays exponentially with the time constant tau_minus and increases to 1 on +a post-spike occurrence (instead of increasing by 1 as in stdp_synapse). + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner + + Original caption: + + Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) + +References +++++++++++ + +.. [1] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 +""" +synapse stdp_nn_restr_symm: + + state: + w real = 1. + pre_trace real = 0. + post_trace real = 0. + pre_handled boolean = True + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + lambda real = .01 + tau_tr_pre ms = 20 ms + tau_tr_post ms = 20 ms + alpha real = 1. + mu_plus real = 1. + mu_minus real = 1. + Wmax real = 100. + Wmin real = 0. + end + + equations: + # nearest-neighbour trace of presynaptic neuron + pre_trace' = -pre_trace / tau_tr_pre + + # nearest-neighbour trace of postsynaptic neuron + post_trace' = -post_trace / tau_tr_post + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + onReceive(post_spikes): + post_trace = 1 + + # potentiate synapse + if not pre_handled: + w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace )) + w = min(Wmax, w_) + pre_handled = True + end + end + + onReceive(pre_spikes): + pre_trace = 1 + + # depress synapse + if pre_handled: + w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace )) + w = max(Wmin, w_) + end + + pre_handled = False + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end diff --git a/models/synapses/stdp_nn_symm.nestml b/models/synapses/stdp_nn_symm.nestml new file mode 100644 index 000000000..917e8fd38 --- /dev/null +++ b/models/synapses/stdp_nn_symm.nestml @@ -0,0 +1,104 @@ +""" +Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing scheme +######################################################################################################## + +Description ++++++++++++ + +stdp_nn_symm_synapse is a connector to create synapses with spike time +dependent plasticity with the symmetric nearest-neighbour spike pairing +scheme [1]_. + +When a presynaptic spike occurs, it is taken into account in the depression +part of the STDP weight change rule with the nearest preceding postsynaptic +one, and when a postsynaptic spike occurs, it is accounted in the +facilitation rule with the nearest preceding presynaptic one (instead of +pairing with all spikes, like in stdp_synapse). For a clear illustration of +this scheme see fig. 7A in [2]_. + +The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike ++ dendritic_delay), leading to zero delta_t, are discarded. In this case the +concerned pre/postsynaptic spike is paired with the second latest preceding +post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +result in a potentiation pair 20-to-10). + +The implementation involves two additional variables - presynaptic and +postsynaptic traces [2]_. The presynaptic trace decays exponentially over +time with the time constant tau_plus and increases to 1 on a pre-spike +occurrence. The postsynaptic trace (implemented on the postsynaptic neuron +side) decays with the time constant tau_minus and increases to 1 on a +post-spike occurrence. + +.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png + + Figure 7 from Morrison, Diesmann and Gerstner + + Original caption: + + Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) + +References +++++++++++ + +.. [1] Morrison A., Aertsen A., Diesmann M. (2007) Spike-timing dependent + plasticity in balanced random networks, Neural Comput. 19:1437--1467 + +.. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological + models of synaptic plasticity based on spike timing, + Biol. Cybern. 98, 459--478 +""" +synapse stdp_nn_symm: + + state: + w real = 1. + pre_trace real = 0. + post_trace real = 0. + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + lambda real = .01 + tau_tr_pre ms = 20 ms + tau_tr_post ms = 20 ms + alpha real = 1. + mu_plus real = 1. + mu_minus real = 1. + Wmax real = 100. + Wmin real = 0. + end + + equations: + # nearest-neighbour trace of presynaptic neuron + pre_trace' = -pre_trace / tau_tr_pre + + # nearest-neighbour trace of postsynaptic neuron + post_trace' = -post_trace / tau_tr_post + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + onReceive(post_spikes): + post_trace = 1 + + # potentiate synapse + w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace )) + w = min(Wmax, w_) + end + + onReceive(pre_spikes): + pre_trace = 1 + + # depress synapse + w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace )) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end diff --git a/models/synapses/stdp_synapse.nestml b/models/synapses/stdp_synapse.nestml new file mode 100644 index 000000000..780e08646 --- /dev/null +++ b/models/synapses/stdp_synapse.nestml @@ -0,0 +1,95 @@ +""" +stdp - Synapse model for spike-timing dependent plasticity +######################################################### + +Description ++++++++++++ + +stdp_synapse is a synapse with spike time dependent plasticity (as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. Examples: + +=================== ==== ============================= +Multiplicative STDP [2]_ mu_plus = mu_minus = 1 +Additive STDP [3]_ mu_plus = mu_minus = 0 +Guetig STDP [1]_ mu_plus, mu_minus in [0, 1] +Van Rossum STDP [4]_ mu_plus = 0 mu_minus = 1 +=================== ==== ============================= + + +References +++++++++++ + +.. [1] Guetig et al. (2003) Learning Input Correlations through Nonlinear + Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience + +.. [2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium + properties of temporally asymmetric Hebbian plasticity, PRL + 86,364-367 + +.. [3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive + Hebbian learning through spike-timing-dependent synaptic + plasticity,Nature Neuroscience 3:9,919--926 + +.. [4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). + Stable Hebbian learning from spike timing-dependent + plasticity, Journal of Neuroscience, 20:23,8812--8821 +""" +synapse stdp: + + state: + w real = 1. @nest::weight + #pre_trace real = 0. + #post_trace real = 0. + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + lambda real = .01 + tau_tr_pre ms = 20 ms + tau_tr_post ms = 20 ms + alpha real = 1 + mu_plus real = 1 + mu_minus real = 1 + Wmax real = 100. + Wmin real = 0. + end + + equations: + kernel pre_trace_kernel = exp(-t / tau_tr_pre) + inline pre_trace real = convolve(pre_trace_kernel, pre_spikes) + + # all-to-all trace of postsynaptic neuron + kernel post_trace_kernel = exp(-t / tau_tr_post) + inline post_trace real = convolve(post_trace_kernel, post_spikes) + +# pre_trace' = -pre_trace / tau_tr_pre +# post_trace' = -post_trace / tau_tr_post + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + onReceive(post_spikes): + #post_trace += 1 + + # potentiate synapse + w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace )) + w = min(Wmax, w_) + end + + onReceive(pre_spikes): + #pre_trace += 1 + + # depress synapse + w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace )) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end + diff --git a/models/synapses/stdp_triplet_naive.nestml b/models/synapses/stdp_triplet_naive.nestml new file mode 100644 index 000000000..754fcec69 --- /dev/null +++ b/models/synapses/stdp_triplet_naive.nestml @@ -0,0 +1,83 @@ +""" +stdp_triplet - Synapse type with triplet spike-timing dependent plasticity +########################################################################## + +Description ++++++++++++ + +stdp_triplet_synapse is a connection with spike time dependent +plasticity accounting for spike triplet effects (as defined in [1]_). + +.. warning:: + + NAIVE VERSION: unclear about relative timing of pre and post trace updates due to incoming pre and post spikes + + +References +++++++++++ +.. [1] Pfister JP, Gerstner W (2006). Triplets of spikes in a model + of spike timing-dependent plasticity. The Journal of Neuroscience + 26(38):9673-9682. DOI: https://doi.org/10.1523/JNEUROSCI.1425-06.2006 +""" +synapse stdp_triplet: + + state: + w nS = 1 nS + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + + tau_plus ms = 16.8 ms # time constant for tr_r1 + tau_x ms = 101 ms # time constant for tr_r2 + tau_minus ms = 33.7 ms # time constant for tr_o1 + tau_y ms = 125 ms # time constant for tr_o2 + + A2_plus real = 7.5e-10 + A3_plus real = 9.3e-3 + A2_minus real = 7e-3 + A3_minus real = 2.3e-4 + + Wmax nS = 100 nS + Wmin nS = 0 nS + end + + equations: + kernel tr_r1_kernel = exp(-t / tau_plus) + inline tr_r1 real = convolve(tr_r1_kernel, pre_spikes) + + kernel tr_r2_kernel = exp(-t / tau_x) + inline tr_r2 real = convolve(tr_r2_kernel, pre_spikes) + + kernel tr_o1_kernel = exp(-t / tau_minus) + inline tr_o1 real = convolve(tr_o1_kernel, post_spikes) + + kernel tr_o2_kernel = exp(-t / tau_y) + inline tr_o2 real = convolve(tr_o2_kernel, post_spikes) + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + onReceive(post_spikes): + # potentiate synapse + #w_ nS = Wmax * ( w / Wmax + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) ) + w_ nS = w + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) + w = min(Wmax, w_) + end + + onReceive(pre_spikes): + # depress synapse + #w_ nS = Wmax * ( w / Wmax - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) ) + w_ nS = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end diff --git a/models/synapses/third_factor_stdp_synapse.nestml b/models/synapses/third_factor_stdp_synapse.nestml new file mode 100644 index 000000000..2f5427e3f --- /dev/null +++ b/models/synapses/third_factor_stdp_synapse.nestml @@ -0,0 +1,96 @@ +""" +third_factor_stdp - Synapse model for spike-timing dependent plasticity with postsynaptic third-factor modulation +################################################################################################################# + +Description ++++++++++++ + +third_factor_stdp is a synapse with spike time dependent plasticity (as defined in [1]). Here the weight dependence exponent can be set separately for potentiation and depression. Examples:: + +Multiplicative STDP [2] mu_plus = mu_minus = 1 +Additive STDP [3] mu_plus = mu_minus = 0 +Guetig STDP [1] mu_plus, mu_minus in [0, 1] +Van Rossum STDP [4] mu_plus = 0 mu_minus = 1 + +The weight changes are modulated by a "third factor", in this case the postsynaptic dendritic current ``I_post_dend``. + +``I_post_dend`` "gates" the weight update, so that if the current is 0, the weight is constant, whereas for a current of 1 pA, the weight change is maximal. + +Do not use values of ``I_post_dend`` larger than 1 pA! + +References +++++++++++ + +[1] Guetig et al. (2003) Learning Input Correlations through Nonlinear + Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience + +[2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium + properties of temporally asymmetric Hebbian plasticity, PRL + 86,364-367 + +[3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive + Hebbian learning through spike-timing-dependent synaptic + plasticity,Nature Neuroscience 3:9,919--926 + +[4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). + Stable Hebbian learning from spike timing-dependent + plasticity, Journal of Neuroscience, 20:23,8812--8821 +""" +synapse third_factor_stdp: + + state: + w real = 1. + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + lambda real = .01 + tau_tr_pre ms = 20 ms + tau_tr_post ms = 20 ms + alpha real = 1. + mu_plus real = 1. + mu_minus real = 1. + Wmax real = 100. + Wmin real = 0. + end + + equations: + kernel pre_trace_kernel = exp(-t / tau_tr_pre) + inline pre_trace real = convolve(pre_trace_kernel, pre_spikes) + + # all-to-all trace of postsynaptic neuron + kernel post_trace_kernel = exp(-t / tau_tr_post) + inline post_trace real = convolve(post_trace_kernel, post_spikes) + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + I_post_dend pA <- continuous + end + + output: spike + + onReceive(post_spikes): + # potentiate synapse + w_ real = Wmax * ( w / Wmax + (lambda * ( 1. - ( w / Wmax ) )**mu_plus * pre_trace )) + if I_post_dend <= 1 pA: + w_ = (I_post_dend / pA) * w_ + (1 - I_post_dend / pA) * w # "gating" of the weight update + end + w = min(Wmax, w_) + end + + onReceive(pre_spikes): + # depress synapse + w_ real = Wmax * ( w / Wmax - ( alpha * lambda * ( w / Wmax )**mu_minus * post_trace )) + if I_post_dend <= 1 pA: + w_ = (I_post_dend / pA) * w_ + (1 - I_post_dend / pA) * w # "gating" of the weight update + end + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end + diff --git a/models/synapses/triplet_stdp_synapse.nestml b/models/synapses/triplet_stdp_synapse.nestml new file mode 100644 index 000000000..4522fbe90 --- /dev/null +++ b/models/synapses/triplet_stdp_synapse.nestml @@ -0,0 +1,85 @@ +""" +stdp_triplet_nn - Synapse type with triplet spike-timing dependent plasticity +############################################################################# + +Description ++++++++++++ + +stdp_triplet_synapse is a connection with spike time dependent +plasticity accounting for spike triplet effects (as defined in [1]_). + + +References +++++++++++ +.. [1] Pfister JP, Gerstner W (2006). Triplets of spikes in a model + of spike timing-dependent plasticity. The Journal of Neuroscience + 26(38):9673-9682. DOI: https://doi.org/10.1523/JNEUROSCI.1425-06.2006 +""" +synapse stdp_triplet_nn: + + state: + w nS = 1 nS + + tr_r1 real = 0. + tr_r2 real = 0. + tr_o1 real = 0. + tr_o2 real = 0. + end + + parameters: + the_delay ms = 1 ms @nest::delay # !!! cannot have a variable called "delay" + + tau_plus ms = 16.8 ms # time constant for tr_r1 + tau_x ms = 101 ms # time constant for tr_r2 + tau_minus ms = 33.7 ms # time constant for tr_o1 + tau_y ms = 125 ms # time constant for tr_o2 + + A2_plus real = 7.5e-10 + A3_plus real = 9.3e-3 + A2_minus real = 7e-3 + A3_minus real = 2.3e-4 + + Wmax nS = 100 nS + Wmin nS = 0 nS + end + + equations: + tr_r1' = -tr_r1 / tau_plus + tr_r2' = -tr_r2 / tau_x + tr_o1' = -tr_o1 / tau_minus + tr_o2' = -tr_o2 / tau_y + end + + input: + pre_spikes nS <- spike + post_spikes nS <- spike + end + + output: spike + + onReceive(post_spikes): + # increment post trace values + tr_o1 += 1 + tr_o2 += 1 + + # potentiate synapse + #w_ nS = Wmax * ( w / Wmax + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) ) + w_ nS = w + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) + w = min(Wmax, w_) + end + + onReceive(pre_spikes): + # increment pre trace values + tr_r1 += 1 + tr_r2 += 1 + + # depress synapse + #w_ nS = Wmax * ( w / Wmax - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) ) + w_ nS = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) + w = max(Wmin, w_) + + # deliver spike to postsynaptic partner + deliver_spike(w, the_delay) + end + +end diff --git a/pynestml/__init__.py b/pynestml/__init__.py index 086df93ea..2a32f1040 100644 --- a/pynestml/__init__.py +++ b/pynestml/__init__.py @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -__version__ = "3.1-post-dev" +__version__ = "5.1.0-post-dev" __all__ = ['cocos', 'codegeneration', @@ -29,5 +29,6 @@ 'meta_model', 'symbols', 'symbol_table', + 'transformers', 'utils', 'visitors'] diff --git a/pynestml/cocos/__init__.py b/pynestml/cocos/__init__.py index 10597ad2a..a9e7160dc 100644 --- a/pynestml/cocos/__init__.py +++ b/pynestml/cocos/__init__.py @@ -23,11 +23,11 @@ 'co_co.py', 'co_co_all_variables_defined.py', - 'co_co_buffer_not_assigned.py', + 'co_co_input_port_not_assigned_to.py', 'co_co_convolve_cond_correctly_built.py', 'co_co_correct_numerator_of_unit.py', 'co_co_correct_order_in_equation.py', - 'co_co_current_buffers_not_specified.py', + 'co_co_continuous_input_port_not_qualified.py', 'co_co_each_block_unique_and_defined.py', 'co_co_equations_only_for_init_values.py', 'co_co_function_calls_consistent.py', @@ -40,12 +40,12 @@ 'co_co_neuron_name_unique.py', 'co_co_no_nest_name_space_collision.py', 'co_co_no_kernels_except_in_convolve.py', - 'co_co_no_two_neurons_in_set_of_compilation_units.py', - 'co_co_buffer_data_type.py', + 'co_co_no_duplicate_compilation_unit_names.py', + 'co_co_input_port_data_type.py', 'co_co_parameters_assigned_only_in_parameter_block.py', 'co_cos_manager.py', 'co_co_sum_has_correct_parameter.py', - 'co_co_buffer_qualifier_unique.py', + 'co_co_input_port_qualifier_unique.py', 'co_co_user_defined_function_correctly_defined.py', 'co_co_variable_once_per_scope.py', 'co_co_vector_variable_in_non_vector_declaration.py' diff --git a/pynestml/cocos/co_co.py b/pynestml/cocos/co_co.py index cab8157e2..6755e7f18 100644 --- a/pynestml/cocos/co_co.py +++ b/pynestml/cocos/co_co.py @@ -33,11 +33,11 @@ class CoCo: description = None @abstractmethod - def check_co_co(self, node): + def check_co_co(self, neuron): """ This is an abstract method which should be implemented by all concrete cocos. - :param node: a single neuron instance on which the coco will be checked. - :type node: ast_neuron + :param neuron: a single neuron instance on which the coco will be checked. + :type neuron: ast_neuron :return: True, if CoCo holds, otherwise False. :rtype: bool """ diff --git a/pynestml/cocos/co_co_all_variables_defined.py b/pynestml/cocos/co_co_all_variables_defined.py index e56d929c1..ed0d6826e 100644 --- a/pynestml/cocos/co_co_all_variables_defined.py +++ b/pynestml/cocos/co_co_all_variables_defined.py @@ -18,8 +18,11 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from pynestml.cocos.co_co import CoCo from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_variable import ASTVariable from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.variable_symbol import BlockType from pynestml.utils.logger import Logger, LoggingLevel @@ -39,50 +42,81 @@ class CoCoAllVariablesDefined(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, node: ASTNeuron, after_ast_rewrite: bool = False): """ - Checks if this coco applies for the handed over neuron. Models which use not defined elements are not - correct. + Checks if this coco applies for the handed over neuron. + Models which contain undefined variables are not correct. :param node: a single neuron instance. - :type node: ast_neuron + :param after_ast_rewrite: indicates whether this coco is checked + after the code generator has done rewriting of the abstract syntax tree. + If True, checks are not as rigorous. Use False where possible. """ # for each variable in all expressions, check if the variable has been defined previously expression_collector_visitor = ASTExpressionCollectorVisitor() node.accept(expression_collector_visitor) expressions = expression_collector_visitor.ret for expr in expressions: - for var in expr.get_variables(): + if isinstance(expr, ASTVariable): + vars = [expr] + else: + vars = expr.get_variables() + + for var in vars: symbol = var.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.VARIABLE) # this part is required to check that we handle invariants differently expr_par = node.get_parent(expr) + # test if the symbol has been defined at least if symbol is None: + if after_ast_rewrite: # after ODE-toolbox transformations, convolutions are replaced by state variables, so cannot perform this check properly + symbol2 = node.get_scope().resolve_to_symbol(var.get_name(), SymbolKind.VARIABLE) + if symbol2 is not None: + # an inline expression defining this variable name (ignoring differential order) exists + if "__X__" in str(symbol2): # if this variable was the result of a convolution... + continue + else: + # for kernels, also allow derivatives of that kernel to appear + if node.get_equations_block() is not None: + inline_expr_names = [inline_expr.variable_name for inline_expr in node.get_equations_block().get_inline_expressions()] + if var.get_name() in inline_expr_names: + inline_expr_idx = inline_expr_names.index(var.get_name()) + inline_expr = node.get_equations_block().get_inline_expressions()[inline_expr_idx] + from pynestml.utils.ast_utils import ASTUtils + if ASTUtils.inline_aliases_convolution(inline_expr): + symbol2 = node.get_scope().resolve_to_symbol(var.get_name(), SymbolKind.VARIABLE) + if symbol2 is not None: + # actually, no problem detected, skip error + # XXX: TODO: check that differential order is less than or equal to that of the kernel + continue + # check if this symbol is actually a type, e.g. "mV" in the expression "(1 + 2) * mV" - symbol = var.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.TYPE) - if symbol is None: - # symbol has not been defined; neither as a variable name nor as a type symbol - code, message = Messages.get_variable_not_defined(var.get_name()) - Logger.log_message(node=node, code=code, message=message, log_level=LoggingLevel.ERROR, - error_position=var.get_source_position()) - # first check if it is part of an invariant + symbol2 = var.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.TYPE) + if symbol2 is not None: + continue # symbol is a type symbol + + code, message = Messages.get_variable_not_defined(var.get_complete_name()) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR, node=node) + return + + # check if it is part of an invariant # if it is the case, there is no "recursive" declaration # so check if the parent is a declaration and the expression the invariant - elif isinstance(expr_par, ASTDeclaration) and expr_par.get_invariant() == expr: + if isinstance(expr_par, ASTDeclaration) and expr_par.get_invariant() == expr: # in this case its ok if it is recursive or defined later on continue - # now check if it has been defined before usage, except for predefined symbols, buffers and variables added by the AST transformation functions - elif (not symbol.is_predefined) \ - and symbol.block_type != BlockType.INPUT_BUFFER_CURRENT \ - and symbol.block_type != BlockType.INPUT_BUFFER_SPIKE \ + # check if it has been defined before usage, except for predefined symbols, input ports and variables added by the AST transformation functions + if (not symbol.is_predefined) \ + and symbol.block_type != BlockType.INPUT \ and not symbol.get_referenced_object().get_source_position().is_added_source_position(): # except for parameters, those can be defined after if ((not symbol.get_referenced_object().get_source_position().before(var.get_source_position())) - and (not symbol.block_type in [BlockType.PARAMETERS, BlockType.INTERNALS])): + and (not symbol.block_type in [BlockType.PARAMETERS, BlockType.INTERNALS, BlockType.STATE])): code, message = Messages.get_variable_used_before_declaration(var.get_name()) Logger.log_message(node=node, message=message, error_position=var.get_source_position(), code=code, log_level=LoggingLevel.ERROR) - # now check that they are now defined recursively, e.g. V_m mV = V_m + 1 + # now check that they are not defined recursively, e.g. V_m mV = V_m + 1 # todo: we should not check this for invariants if (symbol.get_referenced_object().get_source_position().encloses(var.get_source_position()) and not symbol.get_referenced_object().get_source_position().is_added_source_position()): @@ -90,25 +124,6 @@ def check_co_co(cls, node): Logger.log_message(code=code, message=message, error_position=symbol.get_referenced_object(). get_source_position(), log_level=LoggingLevel.ERROR, node=node) - # now check for each assignment whether the left hand side variable is defined - vis = ASTAssignedVariableDefinedVisitor(node) - node.accept(vis) - return - - -class ASTAssignedVariableDefinedVisitor(ASTVisitor): - def __init__(self, neuron): - super(ASTAssignedVariableDefinedVisitor, self).__init__() - self.neuron = neuron - - def visit_assignment(self, node): - symbol = node.get_scope().resolve_to_symbol(node.get_variable().get_complete_name(), - SymbolKind.VARIABLE) - if symbol is None: - code, message = Messages.get_variable_not_defined(node.get_variable().get_complete_name()) - Logger.log_message(code=code, message=message, error_position=node.get_source_position(), - log_level=LoggingLevel.ERROR, node=self.neuron) - class ASTExpressionCollectorVisitor(ASTVisitor): @@ -116,6 +131,9 @@ def __init__(self): super(ASTExpressionCollectorVisitor, self).__init__() self.ret = list() + def visit_assignment(self, node): + self.ret.append(node.get_variable()) + def visit_expression(self, node): self.ret.append(node) diff --git a/pynestml/cocos/co_co_compartmental_model.py b/pynestml/cocos/co_co_compartmental_model.py new file mode 100644 index 000000000..ac68e3f69 --- /dev/null +++ b/pynestml/cocos/co_co_compartmental_model.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# +# co_co_compartmental_model.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.ast_channel_information_collector import ASTChannelInformationCollector + + +class CoCoCompartmentalModel(CoCo): + @classmethod + def check_co_co(cls, neuron: ASTNeuron): + """ + Checks if this compartmental conditions apply for the handed over neuron. + If yes, it checks the presence of expected functions and declarations. + :param neuron: a single neuron instance. + :type neuron: ast_neuron + """ + return ASTChannelInformationCollector.check_co_co(neuron) diff --git a/pynestml/cocos/co_co_current_buffers_not_specified.py b/pynestml/cocos/co_co_continuous_input_port_not_qualified.py similarity index 59% rename from pynestml/cocos/co_co_current_buffers_not_specified.py rename to pynestml/cocos/co_co_continuous_input_port_not_qualified.py index 124e4eee3..289fa34e8 100644 --- a/pynestml/cocos/co_co_current_buffers_not_specified.py +++ b/pynestml/cocos/co_co_continuous_input_port_not_qualified.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_current_buffers_not_specified.py +# co_co_continuous_input_port_not_qualified.py # # This file is part of NEST. # @@ -25,17 +25,24 @@ from pynestml.visitors.ast_visitor import ASTVisitor -class CoCoCurrentBuffersNotSpecified(CoCo): +class CoCoContinuousInputPortNotQualified(CoCo): """ - This coco ensures that current buffers are not specified with a qualifier. + This coco ensures that continuous time input ports are not specified with a qualifier. Allowed: - input: - current <- current - end + + .. code-block:: nestml + + input: + x nA <- continuous + end + Not allowed: - input: - current <- inhibitory current - end + + .. code-block:: nestml + + input: + x nA <- inhibitory continuous + end """ @classmethod @@ -45,17 +52,17 @@ def check_co_co(cls, node): :param node: a single neuron instance. :type node: ast_neuron """ - node.accept(CurrentQualifierSpecifiedVisitor()) + node.accept(ContinuousPortQualifierSpecifiedVisitor()) -class CurrentQualifierSpecifiedVisitor(ASTVisitor): +class ContinuousPortQualifierSpecifiedVisitor(ASTVisitor): """ - This visitor ensures that current buffers are not specified with an `inputQualifier`, e.g. excitatory, inhibitory. + This visitor ensures that continuous time input ports are not specified with an `inputQualifier`, e.g. excitatory, inhibitory. """ def visit_input_port(self, node): - if node.is_current() and node.has_input_qualifiers() and len(node.get_input_qualifiers()) > 0: - code, message = Messages.get_current_buffer_specified(node.get_name(), - list((str(buf) for buf in node.get_input_qualifiers()))) + if node.is_continuous() and node.has_input_qualifiers() and len(node.get_input_qualifiers()) > 0: + qualifier_names = list((str(qualifier) for qualifier in node.get_input_qualifiers())) + code, message = Messages.get_continuous_input_port_specified(node.get_name(), qualifier_names) Logger.log_message(error_position=node.get_source_position(), code=code, message=message, log_level=LoggingLevel.ERROR) diff --git a/pynestml/cocos/co_co_convolve_cond_correctly_built.py b/pynestml/cocos/co_co_convolve_cond_correctly_built.py index e32526990..5e9bd66d7 100644 --- a/pynestml/cocos/co_co_convolve_cond_correctly_built.py +++ b/pynestml/cocos/co_co_convolve_cond_correctly_built.py @@ -27,24 +27,24 @@ class CoCoConvolveCondCorrectlyBuilt(CoCo): """ - This coco ensures that ``convolve`` is correctly called, i.e. that the first argument is the variable from the initial block and the second argument is an input buffer. + This coco ensures that ``convolve`` is correctly called, i.e. that the first argument is the variable from the state block and the second argument is a spiking input port. Allowed: - inline I_syn_exc pA = convolve(g_ex, spikesExc) * ( V_m - E_ex ) + inline I_syn_exc pA = convolve(g_exc, exc_spikes) * ( V_m - E_exc ) Not allowed: - inline I_syn_exc pA = convolve(g_ex, g_ex) * ( V_m - E_ex ) - inline I_syn_exc pA = convolve(spikesExc, g_ex) * ( V_m - E_ex ) + inline I_syn_exc pA = convolve(g_exc, g_exc) * ( V_m - E_exc ) + inline I_syn_exc pA = convolve(exc_spikes, g_exc) * ( V_m - E_exc ) """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - node.accept(ConvolveCheckerVisitor()) + neuron.accept(ConvolveCheckerVisitor()) class ConvolveCheckerVisitor(ASTVisitor): @@ -57,15 +57,14 @@ def visit_function_call(self, node): if func_name == 'convolve': symbol_var = node.get_scope().resolve_to_symbol(str(node.get_args()[0]), SymbolKind.VARIABLE) - symbol_buffer = node.get_scope().resolve_to_symbol(str(node.get_args()[1]), - SymbolKind.VARIABLE) - if symbol_var is not None and not symbol_var.is_kernel() and not symbol_var.is_init_values(): + symbol_port = node.get_scope().resolve_to_symbol(str(node.get_args()[1]), + SymbolKind.VARIABLE) + if symbol_var is not None and not symbol_var.is_kernel() and not symbol_var.is_state(): code, message = Messages.get_first_arg_not_kernel_or_equation(func_name) Logger.log_message(code=code, message=message, error_position=node.get_source_position(), log_level=LoggingLevel.ERROR) - if symbol_buffer is not None and not symbol_buffer.is_input_buffer_spike(): - code, message = Messages.get_second_arg_not_a_buffer(func_name) + if symbol_port is not None and not symbol_port.is_spike_input_port(): + code, message = Messages.get_second_arg_not_a_spike_port(func_name) Logger.log_message(error_position=node.get_source_position(), code=code, message=message, log_level=LoggingLevel.ERROR) - return diff --git a/pynestml/cocos/co_co_correct_numerator_of_unit.py b/pynestml/cocos/co_co_correct_numerator_of_unit.py index 247585235..3fce3ead1 100644 --- a/pynestml/cocos/co_co_correct_numerator_of_unit.py +++ b/pynestml/cocos/co_co_correct_numerator_of_unit.py @@ -35,13 +35,13 @@ class CoCoCorrectNumeratorOfUnit(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - node.accept(NumericNumeratorVisitor()) + neuron.accept(NumericNumeratorVisitor()) class NumericNumeratorVisitor(ASTVisitor): diff --git a/pynestml/cocos/co_co_correct_order_in_equation.py b/pynestml/cocos/co_co_correct_order_in_equation.py index 827ac64b9..1ef5c8367 100644 --- a/pynestml/cocos/co_co_correct_order_in_equation.py +++ b/pynestml/cocos/co_co_correct_order_in_equation.py @@ -39,13 +39,13 @@ class CoCoCorrectOrderInEquation(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - node.accept(OrderOfEquationVisitor()) + neuron.accept(OrderOfEquationVisitor()) class OrderOfEquationVisitor(ASTVisitor): diff --git a/pynestml/cocos/co_co_each_block_unique_and_defined.py b/pynestml/cocos/co_co_each_block_defined_at_most_once.py similarity index 90% rename from pynestml/cocos/co_co_each_block_unique_and_defined.py rename to pynestml/cocos/co_co_each_block_defined_at_most_once.py index d0fa4dc97..114b3fbfd 100644 --- a/pynestml/cocos/co_co_each_block_unique_and_defined.py +++ b/pynestml/cocos/co_co_each_block_defined_at_most_once.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_each_block_unique_and_defined.py +# co_co_each_block_defined_at_most_once.py # # This file is part of NEST. # @@ -18,34 +18,39 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.meta_model.ast_neuron import ASTNeuron + +from typing import Union + from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages -class CoCoEachBlockUniqueAndDefined(CoCo): +class CoCoEachBlockDefinedAtMostOnce(CoCo): """ - This context condition ensures that each block is defined at most once. + This context condition ensures that each block is defined at most once. + Not allowed: - state: - ... - end - ... - state: - ... - end + + .. code:: nestml + + state: + ... + end + ... + state: + ... + end """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, node: Union[ASTNeuron, ASTSynapse]): """ Checks whether each block is define at most once. - :param node: a single neuron. - :type node: ASTNeuron + :param node: a single neuron or synapse. """ - assert (node is not None and isinstance(node, ASTNeuron)), \ - '(PyNestML.CoCo.BlocksUniques) No or wrong type of neuron provided (%s)!' % type(node) if isinstance(node.get_state_blocks(), list) and len(node.get_state_blocks()) > 1: code, message = Messages.get_block_not_defined_correctly('State', False) Logger.log_message(code=code, message=message, node=node, error_position=node.get_source_position(), diff --git a/pynestml/cocos/co_co_equations_only_for_init_values.py b/pynestml/cocos/co_co_equations_only_for_init_values.py index bc77f3a28..c9c588cad 100644 --- a/pynestml/cocos/co_co_equations_only_for_init_values.py +++ b/pynestml/cocos/co_co_equations_only_for_init_values.py @@ -28,17 +28,17 @@ class CoCoEquationsOnlyForInitValues(CoCo): """ This coco ensures that ode equations are only provided for variables which have been defined in the - initial_values block. + state block. Allowed: - initial_values: - V_m mV = 10mV + state: + V_m mV = 10 mV end equations: V_m' = .... end Not allowed: state: - V_m mV = 10mV + V_abs mV = 5 mV end equations: V_m' = .... @@ -46,18 +46,18 @@ class CoCoEquationsOnlyForInitValues(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - node.accept(EquationsOnlyForInitValues()) + neuron.accept(EquationsOnlyForInitValues()) class EquationsOnlyForInitValues(ASTVisitor): """ - This visitor ensures that for all ode equations exists an initial value. + This visitor ensures that for all ode equations exists an initial value in the state block. """ def visit_ode_equation(self, node): @@ -67,8 +67,8 @@ def visit_ode_equation(self, node): :type node: ast_ode_equation """ symbol = node.get_scope().resolve_to_symbol(node.get_lhs().get_name_of_lhs(), SymbolKind.VARIABLE) - if symbol is not None and not symbol.is_init_values(): - code, message = Messages.get_equation_var_not_in_init_values_block(node.get_lhs().get_name_of_lhs()) + if symbol is not None and not symbol.is_state(): + code, message = Messages.get_equation_var_not_in_state_block(node.get_lhs().get_name_of_lhs()) Logger.log_message(code=code, message=message, error_position=node.get_source_position(), log_level=LoggingLevel.ERROR) diff --git a/pynestml/cocos/co_co_function_argument_template_types_consistent.py b/pynestml/cocos/co_co_function_argument_template_types_consistent.py index 933fdd55f..80adc18da 100644 --- a/pynestml/cocos/co_co_function_argument_template_types_consistent.py +++ b/pynestml/cocos/co_co_function_argument_template_types_consistent.py @@ -24,6 +24,7 @@ from pynestml.cocos.co_co import CoCo from pynestml.symbols.error_type_symbol import ErrorTypeSymbol from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.utils.ast_utils import ASTUtils from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.logging_helper import LoggingHelper from pynestml.utils.messages import Messages @@ -73,6 +74,13 @@ def visit_simple_expression(self, node): return function_name = node.get_function_call().get_name() method_symbol = scope.resolve_to_symbol(function_name, SymbolKind.FUNCTION) + + if method_symbol is None and ASTUtils.is_function_delay_variable(node.get_function_call()): + code, message = Messages.get_function_is_delay_variable(function_name) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.DEBUG) + return + # check if this function exists if method_symbol is None: code, message = Messages.get_could_not_resolve(function_name) diff --git a/pynestml/cocos/co_co_function_calls_consistent.py b/pynestml/cocos/co_co_function_calls_consistent.py index f79a2a6d5..4d9b61dfb 100644 --- a/pynestml/cocos/co_co_function_calls_consistent.py +++ b/pynestml/cocos/co_co_function_calls_consistent.py @@ -19,9 +19,13 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.symbols.error_type_symbol import ErrorTypeSymbol from pynestml.symbols.template_type_symbol import TemplateTypeSymbol from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import BlockType +from pynestml.utils.ast_utils import ASTUtils from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages from pynestml.utils.type_caster import TypeCaster @@ -34,13 +38,13 @@ class CoCoFunctionCallsConsistent(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Checks the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ASTNeuron + :param neuron: a single neuron instance. + :type neuron: ASTNeuron """ - node.accept(FunctionCallConsistencyVisitor()) + neuron.accept(FunctionCallConsistencyVisitor()) class FunctionCallConsistencyVisitor(ASTVisitor): @@ -67,6 +71,12 @@ def visit_function_call(self, node): symbol = node.get_scope().resolve_to_symbol(node.get_name(), SymbolKind.FUNCTION) + if symbol is None and ASTUtils.is_function_delay_variable(node): + code, message = Messages.get_function_is_delay_variable(node.get_name()) + Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.DEBUG, + code=code, message=message) + return + # first check if the function has been declared if symbol is None: code, message = Messages.get_function_not_declared(node.get_name()) diff --git a/pynestml/cocos/co_co_function_unique.py b/pynestml/cocos/co_co_function_unique.py index b6fd400ab..dd156ff77 100644 --- a/pynestml/cocos/co_co_function_unique.py +++ b/pynestml/cocos/co_co_function_unique.py @@ -30,14 +30,14 @@ class CoCoFunctionUnique(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Checks if each function is defined uniquely. - :param node: a single neuron - :type node: ast_neuron + :param neuron: a single neuron + :type neuron: ast_neuron """ checked_funcs_names = list() - for func in node.get_functions(): + for func in neuron.get_functions(): if func.get_name() not in checked_funcs_names: symbols = func.get_scope().resolve_to_all_symbols(func.get_name(), SymbolKind.FUNCTION) if isinstance(symbols, list) and len(symbols) > 1: diff --git a/pynestml/cocos/co_co_illegal_expression.py b/pynestml/cocos/co_co_illegal_expression.py index f72da47a3..71e7c2cb0 100644 --- a/pynestml/cocos/co_co_illegal_expression.py +++ b/pynestml/cocos/co_co_illegal_expression.py @@ -86,16 +86,15 @@ def visit_assignment(self, node): if node.is_direct_assignment: # case a = b is simple self.handle_simple_assignment(node) else: - self.handle_complex_assignment(node) # e.g. a *= b - return + self.handle_compound_assignment(node) # e.g. a *= b - def handle_complex_assignment(self, node): + def handle_compound_assignment(self, node): rhs_expr = node.get_expression() lhs_variable_symbol = node.get_variable().resolve_in_own_scope() rhs_type_symbol = rhs_expr.type if lhs_variable_symbol is None: - code, message = Messages.get_equation_var_not_in_init_values_block(node.get_variable().get_complete_name()) + code, message = Messages.get_equation_var_not_in_state_block(node.get_variable().get_complete_name()) Logger.log_message(code=code, message=message, error_position=node.get_source_position(), log_level=LoggingLevel.ERROR) return @@ -104,13 +103,31 @@ def handle_complex_assignment(self, node): LoggingHelper.drop_missing_type_error(node) return - if self.__types_do_not_match(lhs_variable_symbol.get_type_symbol(), rhs_type_symbol): - TypeCaster.try_to_recover_or_error(lhs_variable_symbol.get_type_symbol(), rhs_type_symbol, + lhs_type_symbol = lhs_variable_symbol.get_type_symbol() + + if node.is_compound_product: + if self.__types_do_not_match(lhs_type_symbol, lhs_type_symbol * rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_type_symbol, lhs_type_symbol * rhs_type_symbol, + node.get_expression()) + return + return + + if node.is_compound_quotient: + if self.__types_do_not_match(lhs_type_symbol, lhs_type_symbol / rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_type_symbol, lhs_type_symbol / rhs_type_symbol, + node.get_expression()) + return + return + + assert node.is_compound_sum or node.is_compound_minus + if self.__types_do_not_match(lhs_type_symbol, rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_type_symbol, rhs_type_symbol, node.get_expression()) - return @staticmethod def __types_do_not_match(lhs_type_symbol, rhs_type_symbol): + if lhs_type_symbol is None: + return True return not lhs_type_symbol.equals(rhs_type_symbol) def handle_simple_assignment(self, node): diff --git a/pynestml/cocos/co_co_init_vars_with_odes_provided.py b/pynestml/cocos/co_co_init_vars_with_odes_provided.py deleted file mode 100644 index 10a3deb8b..000000000 --- a/pynestml/cocos/co_co_init_vars_with_odes_provided.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf-8 -*- -# -# co_co_init_vars_with_odes_provided.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -from pynestml.meta_model.ast_neuron import ASTNeuron -from pynestml.cocos.co_co import CoCo -from pynestml.symbols.symbol import SymbolKind -from pynestml.utils.logger import Logger, LoggingLevel -from pynestml.utils.messages import Messages -from pynestml.visitors.ast_visitor import ASTVisitor - - -class CoCoInitVarsWithOdesProvided(CoCo): - """ - This CoCo ensures that all variables which have been declared in the "initial_values" block are provided - with a corresponding ode. - Allowed: - initial_values: - V_m mV = E_L - end - ... - equations: - V_m' = ... - end - Not allowed: - initial_values: - V_m mV = E_L - end - ... - equations: - # no ode declaration given - end - """ - - @classmethod - def check_co_co(cls, node): - """ - Checks this coco on the handed over neuron. - :param node: a single neuron instance. - :type node: ASTNeuron - """ - assert (node is not None and isinstance(node, ASTNeuron)), \ - '(PyNestML.CoCo.VariablesDefined) No or wrong type of neuron provided (%s)!' % type(node) - node.accept(InitVarsVisitor()) - return - - -class InitVarsVisitor(ASTVisitor): - """ - This visitor checks that all variables as provided in the init block have been provided with an ode. - """ - - def visit_declaration(self, node): - """ - Checks the coco on the current node. - :param node: a single declaration. - :type node: ast_declaration - """ - for var in node.get_variables(): - symbol = node.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.VARIABLE) - # first check that all initial value variables have a lhs - if symbol is not None and symbol.is_init_values() and not node.has_expression(): - code, message = Messages.get_no_rhs(symbol.get_symbol_name()) - Logger.log_message(error_position=var.get_source_position(), code=code, - message=message, log_level=LoggingLevel.WARNING) - # now check that they have been provided with an ODE - if symbol is not None and symbol.is_init_values() \ - and not (symbol.is_ode_defined() or symbol.is_kernel()) and not symbol.is_function: - code, message = Messages.get_no_ode(symbol.get_symbol_name()) - Logger.log_message(error_position=var.get_source_position(), code=code, - message=message, log_level=LoggingLevel.WARNING) - if symbol is not None and symbol.is_init_values() and not symbol.has_initial_value(): - code, message = Messages.get_no_init_value(symbol.get_symbol_name()) - Logger.log_message(error_position=var.get_source_position(), code=code, - message=message, log_level=LoggingLevel.WARNING) - return diff --git a/pynestml/cocos/co_co_function_have_rhs.py b/pynestml/cocos/co_co_inline_expressions_have_rhs.py similarity index 71% rename from pynestml/cocos/co_co_function_have_rhs.py rename to pynestml/cocos/co_co_inline_expressions_have_rhs.py index e8dd939a6..8d19e8fa9 100644 --- a/pynestml/cocos/co_co_function_have_rhs.py +++ b/pynestml/cocos/co_co_inline_expressions_have_rhs.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_function_have_rhs.py +# co_co_inline_expressions_have_rhs.py # # This file is part of NEST. # @@ -18,40 +18,40 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_neuron import ASTNeuron from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages from pynestml.visitors.ast_visitor import ASTVisitor -class CoCoFunctionHaveRhs(CoCo): +class CoCoInlineExpressionsHaveRhs(CoCo): """ - This coco ensures that all function declarations, e.g., function V_rest mV = V_m - 55mV, have a rhs. + This coco ensures that all inline expressions have a rhs. """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, node: ASTNeuron): """ Ensures the coco for the handed over neuron. :param node: a single neuron instance. - :type node: ast_neuron """ - node.accept(FunctionRhsVisitor()) + node.accept(InlineRhsVisitor()) -class FunctionRhsVisitor(ASTVisitor): +class InlineRhsVisitor(ASTVisitor): """ - This visitor ensures that everything declared as function has a rhs. + This visitor ensures that everything declared as inline expression has a rhs. """ - def visit_declaration(self, node): + def visit_declaration(self, node: ASTDeclaration): """ Checks if the coco applies. :param node: a single declaration. - :type node: ASTDeclaration. """ - if node.is_function and not node.has_expression(): + if node.is_inline_expression and not node.has_expression(): code, message = Messages.get_no_rhs(node.get_variables()[0].get_name()) Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, code=code, message=message) - return diff --git a/pynestml/cocos/co_co_function_max_one_lhs.py b/pynestml/cocos/co_co_inline_max_one_lhs.py similarity index 72% rename from pynestml/cocos/co_co_function_max_one_lhs.py rename to pynestml/cocos/co_co_inline_max_one_lhs.py index 816386445..e41150451 100644 --- a/pynestml/cocos/co_co_function_max_one_lhs.py +++ b/pynestml/cocos/co_co_inline_max_one_lhs.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_function_max_one_lhs.py +# co_co_inline_max_one_lhs.py # # This file is part of NEST. # @@ -18,19 +18,21 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages from pynestml.visitors.ast_visitor import ASTVisitor -class CoCoFunctionMaxOneLhs(CoCo): +class CoCoInlineMaxOneLhs(CoCo): """ - This coco ensures that whenever a function (aka alias) is declared, only one left-hand side is present. + This coco ensures that whenever an inline expression is declared, only one left-hand side is present. Allowed: - function V_rest mV = V_m - 55mV + inline V_rest mV = V_m - 55mV Not allowed: - function V_reset,V_rest mV = V_m - 55mV + inline V_reset, V_rest mV = V_m - 55mV """ @classmethod @@ -40,23 +42,21 @@ def check_co_co(cls, node): :param node: a single neuron instance. :type node: ast_neuron """ - node.accept(FunctionMaxOneLhs()) + node.accept(InlineMaxOneLhs()) -class FunctionMaxOneLhs(ASTVisitor): +class InlineMaxOneLhs(ASTVisitor): """ - This visitor ensures that every function has exactly one lhs. + This visitor ensures that every inline expression has exactly one lhs. """ - def visit_declaration(self, node): + def visit_declaration(self, node: ASTDeclaration): """ Checks the coco. :param node: a single declaration. - :type node: ast_declaration """ - if node.is_function and len(node.get_variables()) > 1: + if node.is_inline_expression and len(node.get_variables()) > 1: code, message = Messages.get_several_lhs(list((var.get_name() for var in node.get_variables()))) Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, code=code, message=message) - return diff --git a/pynestml/cocos/co_co_buffer_data_type.py b/pynestml/cocos/co_co_input_port_data_type.py similarity index 65% rename from pynestml/cocos/co_co_buffer_data_type.py rename to pynestml/cocos/co_co_input_port_data_type.py index af8a1e363..e8b580c1a 100644 --- a/pynestml/cocos/co_co_buffer_data_type.py +++ b/pynestml/cocos/co_co_input_port_data_type.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_buffer_data_type.py +# co_co_input_port_data_type.py # # This file is part of NEST. # @@ -20,43 +20,51 @@ # along with NEST. If not, see . from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_input_port import ASTInputPort +from pynestml.meta_model.ast_neuron import ASTNeuron from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages from pynestml.visitors.ast_visitor import ASTVisitor -class CoCoBufferDataType(CoCo): +class CoCoInputPortDataType(CoCo): """ - This coco ensures that all spike and current buffers have a data type stated. + This coco ensures that all spike and continuous time input ports have a data type stated. + Allowed: - input: - spikeIn integer <- inhibitory spike - current pA <- current - end + + .. code-block:: nestml + + input: + spikeIn integer <- inhibitory spike + current pA <- continuous + end Not allowed: - input: - spikeIn <- inhibitory spike - current <- current - end + + .. code-block:: nestml + + input: + spikeIn <- inhibitory spike + current <- continuous + end """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, node: ASTNeuron): """ Ensures the coco for the handed over neuron. :param node: a single neuron instance. - :type node: ast_neuron """ - node.accept(BufferDatatypeVisitor()) + node.accept(InputPortDatatypeVisitor()) -class BufferDatatypeVisitor(ASTVisitor): +class InputPortDatatypeVisitor(ASTVisitor): """ - This visitor checks if each buffer has a datatype selected according to the coco. + This visitor checks if each input port has a datatype selected according to the coco. """ - def visit_input_port(self, node): + def visit_input_port(self, node: ASTInputPort): """ Checks the coco on the current node. :param node: a single input port node. diff --git a/pynestml/cocos/co_co_buffer_not_assigned.py b/pynestml/cocos/co_co_input_port_not_assigned_to.py similarity index 71% rename from pynestml/cocos/co_co_buffer_not_assigned.py rename to pynestml/cocos/co_co_input_port_not_assigned_to.py index 8196cee89..392301bfd 100644 --- a/pynestml/cocos/co_co_buffer_not_assigned.py +++ b/pynestml/cocos/co_co_input_port_not_assigned_to.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_buffer_not_assigned.py +# co_co_input_port_not_assigned_to.py # # This file is part of NEST. # @@ -18,7 +18,9 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_neuron import ASTNeuron from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.variable_symbol import BlockType from pynestml.utils.logger import LoggingLevel, Logger @@ -26,33 +28,46 @@ from pynestml.visitors.ast_visitor import ASTVisitor -class CoCoBufferNotAssigned(CoCo): +class CoCoInputPortNotAssignedTo(CoCo): """ - This coco ensures that no values are assigned to buffers. + This coco ensures that no values are assigned to input ports. + + Given: + + .. code-block:: nestml + + input: + current_in pA <- continuous + end + Allowed: - currentSum = current + 10mV # current being a buffer + + .. code-block:: nestml + + foo = current_in + 10 pA + Not allowed: - current = currentSum + 10mV + + .. code-block:: nestml + + current_in = foo + 10 pA """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, node: ASTNeuron): """ Ensures the coco for the handed over neuron. :param node: a single neuron instance. - :type node: ast_neuron """ - node.accept(NoBufferAssignedVisitor()) + node.accept(NoInputPortAssignedToVisitor()) -class NoBufferAssignedVisitor(ASTVisitor): +class NoInputPortAssignedToVisitor(ASTVisitor): def visit_assignment(self, node): symbol = node.get_scope().resolve_to_symbol(node.get_variable().get_name(), SymbolKind.VARIABLE) - if symbol is not None and (symbol.block_type == BlockType.INPUT_BUFFER_SPIKE - or symbol.block_type == BlockType.INPUT_BUFFER_CURRENT): + if symbol is not None and symbol.block_type == BlockType.INPUT: code, message = Messages.get_value_assigned_to_buffer(node.get_variable().get_complete_name()) Logger.log_message(code=code, message=message, error_position=node.get_source_position(), log_level=LoggingLevel.ERROR) - return diff --git a/pynestml/cocos/co_co_buffer_qualifier_unique.py b/pynestml/cocos/co_co_input_port_qualifier_unique.py similarity index 54% rename from pynestml/cocos/co_co_buffer_qualifier_unique.py rename to pynestml/cocos/co_co_input_port_qualifier_unique.py index 5434713a5..d655e6eb2 100644 --- a/pynestml/cocos/co_co_buffer_qualifier_unique.py +++ b/pynestml/cocos/co_co_input_port_qualifier_unique.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_buffer_qualifier_unique.py +# co_co_input_port_qualifier_unique.py # # This file is part of NEST. # @@ -25,13 +25,22 @@ from pynestml.visitors.ast_visitor import ASTVisitor -class CoCoBufferQualifierUnique(CoCo): +class CoCoInputPortQualifierUnique(CoCo): """ - This coco ensures that each spike buffer has at most one type of modifier inhibitory and excitatory. + This coco ensures that each spike input port has at most one type of modifier inhibitory and excitatory. + Allowed: - spike <- inhibitory spike + + .. code-block:: nestml + + spike pA <- inhibitory spike + Not allowed: - spike <- inhibitory inhibitory spike + + .. code-block:: nestml + + spike pA <- inhibitory inhibitory spike + """ @classmethod @@ -42,12 +51,12 @@ def check_co_co(cls, node): :type node: ast_neuron """ cls.neuronName = node.get_name() - node.accept(BufferQualifierUniqueVisitor()) + node.accept(InputPortQualifierUniqueVisitor()) -class BufferQualifierUniqueVisitor(ASTVisitor): +class InputPortQualifierUniqueVisitor(ASTVisitor): """ - This visitor ensures that all buffers are qualified uniquely by keywords. + This visitor ensures that all input ports are qualified uniquely by keywords. """ def visit_input_port(self, node): @@ -58,19 +67,6 @@ def visit_input_port(self, node): """ if node.is_spike(): if node.has_input_qualifiers() and len(node.get_input_qualifiers()) > 1: - inh = 0 - ext = 0 - for typ in node.get_input_qualifiers(): - if typ.is_excitatory: - ext += 1 - if typ.is_inhibitory: - inh += 1 - if inh > 1: - code, message = Messages.get_multiple_keywords('inhibitory') - Logger.log_message(error_position=node.get_source_position(), code=code, message=message, - log_level=LoggingLevel.ERROR) - if ext > 1: - code, message = Messages.get_multiple_keywords('excitatory') - Logger.log_message(error_position=node.get_source_position(), code=code, message=message, - log_level=LoggingLevel.ERROR) - return + code, message = Messages.get_multiple_keywords(", ".join([str(q) for q in node.get_input_qualifiers()])) + Logger.log_message(error_position=node.get_source_position(), code=code, message=message, + log_level=LoggingLevel.ERROR) diff --git a/pynestml/cocos/co_co_integrate_odes_called_if_equations_defined.py b/pynestml/cocos/co_co_integrate_odes_called_if_equations_defined.py new file mode 100644 index 000000000..b56c1fc29 --- /dev/null +++ b/pynestml/cocos/co_co_integrate_odes_called_if_equations_defined.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# +# co_co_integrate_odes_called_if_equations_defined.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor +from pynestml.symbols.predefined_functions import PredefinedFunctions + + +class CoCoIntegrateOdesCalledIfEquationsDefined(CoCo): + """ + This coco ensures that integrate_odes() is called if one or more dynamical equations are defined. + """ + + @classmethod + def check_co_co(cls, node: ASTNeuron): + """ + Ensures the coco for the handed over neuron. + :param node: a single neuron instance. + """ + if isinstance(node, ASTSynapse): + return + equations_defined_visitor = EquationsDefinedVisitor() + node.accept(equations_defined_visitor) + integrate_odes_called_visitor = IntegrateOdesCalledVisitor() + node.accept(integrate_odes_called_visitor) + if equations_defined_visitor.equations_defined() and not integrate_odes_called_visitor.integrate_odes_called(): + code, message = Messages.get_equations_defined_but_integrate_odes_not_called() + Logger.log_message(code=code, message=message, + error_position=node.get_source_position(), log_level=LoggingLevel.ERROR) + + +class EquationsDefinedVisitor(ASTVisitor): + """ + This visitor checks if equations are defined. + """ + + _equations_defined = False + + def visit_ode_equation(self, node): + self._equations_defined = True + + def equations_defined(self) -> bool: + return self._equations_defined + + +class IntegrateOdesCalledVisitor(ASTVisitor): + """ + This visitor checks if integrate_odes() is called. + """ + + _integrate_odes_called = False + + def visit_function_call(self, node: ASTFunctionCall): + if node.get_name() == PredefinedFunctions.INTEGRATE_ODES: + self._integrate_odes_called = True + + def integrate_odes_called(self) -> bool: + return self._integrate_odes_called diff --git a/pynestml/cocos/co_co_kernel_type.py b/pynestml/cocos/co_co_kernel_type.py index 580619b3f..48a352b70 100644 --- a/pynestml/cocos/co_co_kernel_type.py +++ b/pynestml/cocos/co_co_kernel_type.py @@ -19,8 +19,10 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Optional + from pynestml.cocos.co_co import CoCo -from pynestml.codegeneration.debug_type_converter import DebugTypeConverter +from pynestml.codegeneration.printers.debug_types_printer import DebugTypesPrinter from pynestml.meta_model.ast_neuron import ASTNeuron from pynestml.symbols.integer_type_symbol import IntegerTypeSymbol from pynestml.symbols.real_type_symbol import RealTypeSymbol @@ -38,15 +40,15 @@ class CoCoKernelType(CoCo): """ @classmethod - def check_co_co(cls, node: ASTNeuron): + def check_co_co(cls, neuron: ASTNeuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ASTNeuron + :param neuron: a single neuron instance. + :type neuron: ASTNeuron """ kernel_type_visitor = KernelTypeVisitor() - kernel_type_visitor._neuron = node - node.accept(kernel_type_visitor) + kernel_type_visitor._neuron = neuron + neuron.accept(kernel_type_visitor) class KernelTypeVisitor(ASTVisitor): @@ -54,7 +56,7 @@ class KernelTypeVisitor(ASTVisitor): This visitor checks if each kernel has the appropriate data type. """ - _neuron = None # the parent ASTNeuron containing the kernel + _neuron: Optional[ASTNeuron] = None # the parent ASTNeuron containing the kernel def visit_kernel(self, node): """ @@ -78,20 +80,20 @@ def visit_kernel(self, node): Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, code=code, message=message) - # check types of the initial values + # check types of the state variables for order in range(var.get_differential_order()): iv_name = var.get_name() + order * "'" - decl = ASTUtils.get_declaration_by_name(self._neuron.get_initial_blocks(), iv_name) + decl = ASTUtils.get_declaration_by_name(self._neuron.get_state_blocks(), iv_name) if decl is None: code, message = Messages.get_variable_not_defined(iv_name) Logger.log_message(node=self._neuron, code=code, message=message, log_level=LoggingLevel.ERROR, error_position=node.get_source_position()) continue - assert len(self._neuron.get_initial_blocks().get_declarations()[0].get_variables( + assert len(self._neuron.get_state_blocks().get_declarations()[0].get_variables( )) == 1, "Only single variables are supported as targets of an assignment." iv = decl.get_variables()[0] if not iv.get_type_symbol().get_value().is_castable_to(PredefinedTypes.get_type("ms")**-order): - actual_type_str = DebugTypeConverter.convert(iv.get_type_symbol()) + actual_type_str = DebugTypesPrinter().convert(iv.get_type_symbol()) expected_type_str = "s^-" + str(order) code, message = Messages.get_kernel_iv_wrong_type(iv_name, actual_type_str, expected_type_str) Logger.log_message(error_position=node.get_source_position(), diff --git a/pynestml/cocos/co_co_neuron_name_unique.py b/pynestml/cocos/co_co_neuron_name_unique.py index 1e5205382..9d56a477f 100644 --- a/pynestml/cocos/co_co_neuron_name_unique.py +++ b/pynestml/cocos/co_co_neuron_name_unique.py @@ -56,7 +56,7 @@ def check_co_co(cls, compilation_unit): for neuronA in compilation_unit.get_neuron_list(): for neuronB in compilation_unit.get_neuron_list(): if neuronA is not neuronB and neuronA.get_name() == neuronB.get_name() and neuronB not in checked: - code, message = Messages.get_neuron_redeclared(neuronB.get_name()) + code, message = Messages.get_model_redeclared(neuronB.get_name()) Logger.log_message(error_position=neuronB.get_source_position(), code=code, message=message, log_level=LoggingLevel.ERROR) diff --git a/pynestml/cocos/co_co_no_two_neurons_in_set_of_compilation_units.py b/pynestml/cocos/co_co_no_duplicate_compilation_unit_names.py similarity index 69% rename from pynestml/cocos/co_co_no_two_neurons_in_set_of_compilation_units.py rename to pynestml/cocos/co_co_no_duplicate_compilation_unit_names.py index d783be291..9f5b03b59 100644 --- a/pynestml/cocos/co_co_no_two_neurons_in_set_of_compilation_units.py +++ b/pynestml/cocos/co_co_no_duplicate_compilation_unit_names.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# co_co_no_two_neurons_in_set_of_compilation_units.py +# co_co_no_duplicate_compilation_unit_names.py # # This file is part of NEST. # @@ -24,9 +24,9 @@ from pynestml.utils.messages import Messages -class CoCoNoTwoNeuronsInSetOfCompilationUnits(CoCo): +class CoCoNoDuplicateCompilationUnitNames(CoCo): """ - This Coco checks that for a handed over list of compilation units, not two neurons have the same name. + This Coco checks that for a handed over list of compilation units, there are not two units that have the same name. """ @classmethod @@ -36,16 +36,16 @@ def check_co_co(cls, list_of_compilation_units): :param list_of_compilation_units: a list of compilation units. :type list_of_compilation_units: list(ASTNestMLCompilationUnit) """ - list_of_neurons = ASTUtils.get_all_neurons(list_of_compilation_units) - conflicting_neurons = list() + # list_of_nodes = ASTUtils.get_all_nodes(list_of_compilation_units) + conflicting_nodes = list() checked = list() - for neuronA in list_of_neurons: - for neuronB in list_of_neurons: - if neuronA is not neuronB and neuronA.get_name() == neuronB.get_name(): - code, message = Messages.get_compilation_unit_name_collision(neuronA.get_name(), - neuronA.get_artifact_name(), - neuronB.get_artifact_name()) + for nodeA in list_of_compilation_units: + for nodeB in list_of_compilation_units: + if nodeA is not nodeB and nodeA.get_name() == nodeB.get_name(): + code, message = Messages.get_compilation_unit_name_collision(nodeA.get_name(), + nodeA.get_artifact_name(), + nodeB.get_artifact_name()) Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR) - conflicting_neurons.append(neuronB) - checked.append(neuronA) - return conflicting_neurons + conflicting_nodes.append(nodeB) + checked.append(nodeA) + return conflicting_nodes diff --git a/pynestml/cocos/co_co_no_kernels_except_in_convolve.py b/pynestml/cocos/co_co_no_kernels_except_in_convolve.py index 3e1169837..5129fe3d3 100644 --- a/pynestml/cocos/co_co_no_kernels_except_in_convolve.py +++ b/pynestml/cocos/co_co_no_kernels_except_in_convolve.py @@ -22,6 +22,7 @@ from pynestml.cocos.co_co import CoCo from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_external_variable import ASTExternalVariable from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.symbols.symbol import SymbolKind from pynestml.utils.logger import Logger, LoggingLevel @@ -43,16 +44,16 @@ class CoCoNoKernelsExceptInConvolve(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ kernel_collector_visitor = KernelCollectingVisitor() - kernel_names = kernel_collector_visitor.collect_kernels(neuron=node) + kernel_names = kernel_collector_visitor.collect_kernels(neuron=neuron) kernel_usage_visitor = KernelUsageVisitor(_kernels=kernel_names) - kernel_usage_visitor.work_on(node) + kernel_usage_visitor.work_on(neuron) class KernelUsageVisitor(ASTVisitor): @@ -77,13 +78,15 @@ def visit_variable(self, node: ASTNode): """ Visits each kernel and checks if it is used correctly. :param node: a single node. - :type node: ASTNode """ for kernelName in self.__kernels: # in order to allow shadowing by local scopes, we first check if the element has been declared locally symbol = node.get_scope().resolve_to_symbol(kernelName, SymbolKind.VARIABLE) # if it is not a kernel just continue if symbol is None: + if not isinstance(node, ASTExternalVariable): + code, message = Messages.get_no_variable_found(kernelName) + Logger.log_message(node=self.__neuron_node, code=code, message=message, log_level=LoggingLevel.ERROR) continue if not symbol.is_kernel(): continue diff --git a/pynestml/cocos/co_co_no_nest_name_space_collision.py b/pynestml/cocos/co_co_no_nest_name_space_collision.py index 9a834691c..a6757d181 100644 --- a/pynestml/cocos/co_co_no_nest_name_space_collision.py +++ b/pynestml/cocos/co_co_no_nest_name_space_collision.py @@ -44,13 +44,13 @@ class CoCoNoNestNameSpaceCollision(CoCo): 'set_status', 'init_state_', 'init_buffers_'] @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - for func in node.get_functions(): + for func in neuron.get_functions(): if func.get_name() in cls.nest_name_space: code, message = Messages.get_nest_collision(func.get_name()) Logger.log_message(error_position=func.get_source_position(), diff --git a/pynestml/cocos/co_co_ode_functions_have_consistent_units.py b/pynestml/cocos/co_co_ode_functions_have_consistent_units.py index 1982afa19..2ed410ce0 100644 --- a/pynestml/cocos/co_co_ode_functions_have_consistent_units.py +++ b/pynestml/cocos/co_co_ode_functions_have_consistent_units.py @@ -32,13 +32,13 @@ class CoCoOdeFunctionsHaveConsistentUnits(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - node.accept(OdeFunctionConsistentUnitsVisitor()) + neuron.accept(OdeFunctionConsistentUnitsVisitor()) class OdeFunctionConsistentUnitsVisitor(ASTVisitor): diff --git a/pynestml/cocos/co_co_odes_have_consistent_units.py b/pynestml/cocos/co_co_odes_have_consistent_units.py index 5c4284cfc..8442241b4 100644 --- a/pynestml/cocos/co_co_odes_have_consistent_units.py +++ b/pynestml/cocos/co_co_odes_have_consistent_units.py @@ -32,13 +32,13 @@ class CoCoOdesHaveConsistentUnits(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ast_neuron + :param neuron: a single neuron instance. + :type neuron: ast_neuron """ - node.accept(OdeConsistentUnitsVisitor()) + neuron.accept(OdeConsistentUnitsVisitor()) class OdeConsistentUnitsVisitor(ASTVisitor): diff --git a/pynestml/cocos/co_co_output_port_defined_if_emit_call.py b/pynestml/cocos/co_co_output_port_defined_if_emit_call.py index 30ec94321..ea478f6ef 100644 --- a/pynestml/cocos/co_co_output_port_defined_if_emit_call.py +++ b/pynestml/cocos/co_co_output_port_defined_if_emit_call.py @@ -18,7 +18,11 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Optional + from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.meta_model.ast_neuron import ASTNeuron from pynestml.symbols.error_type_symbol import ErrorTypeSymbol from pynestml.symbols.template_type_symbol import TemplateTypeSymbol @@ -38,8 +42,7 @@ class CoCoOutputPortDefinedIfEmitCall(CoCo): def check_co_co(cls, neuron: ASTNeuron): """ Checks the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ASTNeuron + :param neuron: a single neuron instance. """ visitor = OutputPortDefinedIfEmitCalledVisitor() visitor.neuron = neuron @@ -51,15 +54,15 @@ class OutputPortDefinedIfEmitCalledVisitor(ASTVisitor): This visitor ensures that all function calls are consistent. """ - neuron = None + neuron = None # type: Optional[ASTNeuron] - def visit_function_call(self, node): + def visit_function_call(self, node: ASTFunctionCall): """ Check consistency for a single function call: check if the called function has been declared, whether the number and types of arguments correspond to the declaration, etc. :param node: a single function call. - :type node: ASTFunctionCall """ + assert self.neuron is not None func_name = node.get_name() if func_name == 'emit_spike': output_block = self.neuron.get_output_blocks() diff --git a/pynestml/cocos/co_co_parameters_assigned_only_in_parameter_block.py b/pynestml/cocos/co_co_parameters_assigned_only_in_parameter_block.py index a39470bd4..9c0834659 100644 --- a/pynestml/cocos/co_co_parameters_assigned_only_in_parameter_block.py +++ b/pynestml/cocos/co_co_parameters_assigned_only_in_parameter_block.py @@ -18,7 +18,9 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.cocos.co_co import CoCo from pynestml.symbol_table.scope import ScopeType from pynestml.symbols.symbol import SymbolKind @@ -52,7 +54,7 @@ def check_co_co(cls, node): :param node: a single neuron instance. :type node: ASTNeuron """ - assert (node is not None and isinstance(node, ASTNeuron)), \ + assert (node is not None and (isinstance(node, ASTNeuron) or isinstance(node, ASTSynapse))), \ '(PyNestML.CoCo.BufferNotAssigned) No or wrong type of neuron provided (%s)!' % type(node) node.accept(ParametersAssignmentVisitor()) return @@ -63,17 +65,15 @@ class ParametersAssignmentVisitor(ASTVisitor): This visitor checks that no parameters have been assigned outside the parameters block. """ - def visit_assignment(self, node): + def visit_assignment(self, node: ASTAssignment) -> None: """ Checks the coco on the current node. :param node: a single node. - :type node: ast_assignment """ symbol = node.get_scope().resolve_to_symbol(node.get_variable().get_name(), SymbolKind.VARIABLE) - if (symbol is not None and symbol.block_type == BlockType.PARAMETERS + if (symbol is not None and symbol.block_type in [BlockType.PARAMETERS, BlockType.COMMON_PARAMETERS] and node.get_scope().get_scope_type() != ScopeType.GLOBAL): code, message = Messages.get_assignment_not_allowed(node.get_variable().get_complete_name()) Logger.log_message(error_position=node.get_source_position(), code=code, message=message, log_level=LoggingLevel.ERROR) - return diff --git a/pynestml/cocos/co_co_priorities_correctly_specified.py b/pynestml/cocos/co_co_priorities_correctly_specified.py new file mode 100644 index 000000000..7d7b005c5 --- /dev/null +++ b/pynestml/cocos/co_co_priorities_correctly_specified.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# +# co_co_priorities_correctly_specified.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Dict + +from pynestml.cocos.co_co import CoCo +from pynestml.symbols.symbol import SymbolKind +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages + + +class CoCoPrioritiesCorrectlySpecified(CoCo): + """ + This Coco ensures that priorities for event handlers are correctly specified. + """ + + @classmethod + def check_co_co(cls, node: ASTSynapse): + """ + Checks the context condition. + :param node: a single synapse + """ + if not isinstance(node, ASTSynapse): + # only synapses have event handlers + return + + priorities = {} # type: Dict[str, int] + for on_receive_block in node.get_on_receive_blocks(): + if "priority" in on_receive_block.get_const_parameters(): + priorities[on_receive_block.get_port_name()] = int(on_receive_block.get_const_parameters()["priority"]) + + if len(priorities) == 1: + on_receive_block_name = priorities.keys()[0] + + code, message = Messages.get_priority_defined_for_only_one_receive_block(on_receive_block_name) + Logger.log_message(code=code, + message=message, + error_position=node.get_on_receive_block(on_receive_block_name).get_source_position(), + log_level=LoggingLevel.ERROR, + node=node.get_on_receive_block(on_receive_block_name)) + return + + unique_priorities = set(priorities.values()) + if len(unique_priorities) < len(priorities.values()): + code, message = Messages.get_repeated_priorty_value() + Logger.log_message(code=code, + message=message, + log_level=LoggingLevel.ERROR) + return diff --git a/pynestml/cocos/co_co_resolution_func_legally_used.py b/pynestml/cocos/co_co_resolution_func_legally_used.py new file mode 100644 index 000000000..4ab636d4a --- /dev/null +++ b/pynestml/cocos/co_co_resolution_func_legally_used.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# +# co_co_resolution_func_legally_used.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.meta_model.ast_function import ASTFunction +from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor +from pynestml.symbols.predefined_functions import PredefinedFunctions + + +class CoCoResolutionFuncLegallyUsed(CoCo): + """ + This Coco ensures that the predefined ``resolution()`` function appears only in the update, parameters, internals, or state block. + """ + + @classmethod + def check_co_co(cls, node): + """ + Checks the coco. + :param node: a single node (typically, a neuron or synapse) + """ + visitor = CoCoResolutionFuncLegallyUsedVisitor() + visitor.neuron = node + node.accept(visitor) + + +class CoCoResolutionFuncLegallyUsedVisitor(ASTVisitor): + def visit_simple_expression(self, node): + """ + Visits a single function call + + :param node: a simple expression + """ + assert isinstance(node, ASTSimpleExpression), \ + '(PyNestML.Visitor.FunctionCallVisitor) No or wrong type of simple expression provided (%s)!' % tuple(node) + assert (node.get_scope() is not None), \ + "(PyNestML.Visitor.FunctionCallVisitor) No scope found, run symboltable creator!" + if node.get_function_call() is None: + return + function_name = node.get_function_call().get_name() + if function_name == PredefinedFunctions.TIME_RESOLUTION: + _node = node + while _node: + _node = self.neuron.get_parent(_node) + + if isinstance(_node, ASTEquationsBlock) \ + or isinstance(_node, ASTFunction): + code, message = Messages.get_could_not_resolve(function_name) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR) diff --git a/pynestml/cocos/co_co_simple_delta_function.py b/pynestml/cocos/co_co_simple_delta_function.py index d3ae81710..f2b140a89 100644 --- a/pynestml/cocos/co_co_simple_delta_function.py +++ b/pynestml/cocos/co_co_simple_delta_function.py @@ -36,18 +36,18 @@ class CoCoSimpleDeltaFunction(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Checks if this coco applies for the handed over neuron. - :param node: a single neuron instance. - :type node: ASTNeuron + :param neuron: a single neuron instance. + :type neuron: ASTNeuron """ def check_simple_delta(_expr=None): if _expr.is_function_call() and _expr.get_function_call().get_name() == "delta": deltafunc = _expr.get_function_call() - parent = node.get_parent(_expr) + parent = neuron.get_parent(_expr) # check the argument if not (len(deltafunc.get_args()) == 1 @@ -66,4 +66,4 @@ def check_simple_delta(_expr=None): def func(x): return check_simple_delta(x) if isinstance(x, ASTSimpleExpression) else True - node.accept(ASTHigherOrderVisitor(func)) + neuron.accept(ASTHigherOrderVisitor(func)) diff --git a/pynestml/cocos/co_co_state_variables_initialized.py b/pynestml/cocos/co_co_state_variables_initialized.py new file mode 100644 index 000000000..751fadeec --- /dev/null +++ b/pynestml/cocos/co_co_state_variables_initialized.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# +# co_co_state_variables_initialized.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages + + +class CoCoStateVariablesInitialized(CoCo): + """ + This CoCo ensures that all the variables declared in the state block are initialized with a value. + """ + + @classmethod + def check_co_co(cls, node: ASTNeuron): + """ + Checks if the coco applies for the node. All the variables declared in the state block + must be initialized with a value. + :param node: + """ + for variable in node.get_state_symbols(): + if not variable.has_declaring_expression(): + code, message = Messages.get_state_variables_not_initialized(var_name=variable.get_symbol_name()) + Logger.log_message(error_position=node.get_source_position(), + code=code, message=message, + log_level=LoggingLevel.ERROR) diff --git a/pynestml/cocos/co_co_synapses_model.py b/pynestml/cocos/co_co_synapses_model.py new file mode 100644 index 000000000..dd5c61b12 --- /dev/null +++ b/pynestml/cocos/co_co_synapses_model.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# +# co_co_synapses_model.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.syns_processing import SynsProcessing + + +class CoCoSynapsesModel(CoCo): + + @classmethod + def check_co_co(cls, neuron: ASTNeuron): + """ + Checks if this compartmental conditions apply for the handed over neuron. + If yes, it checks the presence of expected functions and declarations. + :param neuron: a single neuron instance. + :type neuron: ast_neuron + """ + return SynsProcessing.check_co_co(neuron) diff --git a/pynestml/cocos/co_co_user_defined_function_correctly_defined.py b/pynestml/cocos/co_co_user_defined_function_correctly_defined.py index 5e0dd7f8a..1c775d59f 100644 --- a/pynestml/cocos/co_co_user_defined_function_correctly_defined.py +++ b/pynestml/cocos/co_co_user_defined_function_correctly_defined.py @@ -20,6 +20,7 @@ # along with NEST. If not, see . from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.cocos.co_co import CoCo @@ -49,16 +50,16 @@ class CoCoUserDefinedFunctionCorrectlyDefined(CoCo): processed_function = None @classmethod - def check_co_co(cls, _neuron=None): + def check_co_co(cls, _node=None): """ - Checks the coco for the handed over neuron. - :param _neuron: a single neuron instance. - :type _neuron: ASTNeuron + Checks the coco for the handed over node. + :param _node: a single node instance. + :type _node: ASTNeuron or ASTSynapse """ - assert (_neuron is not None and isinstance(_neuron, ASTNeuron)), \ - '(PyNestML.CoCo.FunctionCallsConsistent) No or wrong type of neuron provided (%s)!' % type(_neuron) - cls.__neuronName = _neuron.get_name() - for userDefinedFunction in _neuron.get_functions(): + assert (_node is not None and (isinstance(_node, ASTNeuron) or isinstance(_node, ASTSynapse))), \ + '(PyNestML.CoCo.FunctionCallsConsistent) No or wrong type of node provided (%s)!' % type(_node) + cls.__nodeName = _node.get_name() + for userDefinedFunction in _node.get_functions(): cls.processed_function = userDefinedFunction symbol = userDefinedFunction.get_scope().resolve_to_symbol(userDefinedFunction.get_name(), SymbolKind.FUNCTION) @@ -71,7 +72,7 @@ def check_co_co(cls, _neuron=None): elif symbol is not None and userDefinedFunction.has_return_type() and \ not symbol.get_return_type().equals(PredefinedTypes.get_void_type()): code, message = Messages.get_no_return() - Logger.log_message(node=_neuron, code=code, message=message, + Logger.log_message(node=_node, code=code, message=message, error_position=userDefinedFunction.get_source_position(), log_level=LoggingLevel.ERROR) return diff --git a/pynestml/cocos/co_co_v_comp_exists.py b/pynestml/cocos/co_co_v_comp_exists.py new file mode 100644 index 000000000..788369d82 --- /dev/null +++ b/pynestml/cocos/co_co_v_comp_exists.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# +# co_co_v_comp_exists.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.cocos.co_co import CoCo +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.messages import Messages +from pynestml.utils.logger import Logger, LoggingLevel + + +class CoCoVCompDefined(CoCo): + """ + This class represents a constraint condition which ensures that variable v_comp has benn + defined if we have compartmental model case. + When we start code generation with NEST_COMPARTMENTAL flag the following must exist: + state: + v_comp real = 0 + end + """ + + @classmethod + def check_co_co(cls, neuron: ASTNeuron, after_ast_rewrite: bool = False): + """ + Checks if this coco applies for the handed over neuron. + Models which are supposed to be compartmental but do not contain + state variable called v_comp are not correct. + :param neuron: a single neuron instance. + :param after_ast_rewrite: indicates whether this coco is checked + after the code generator has done rewriting of the abstract syntax tree. + If True, checks are not as rigorous. Use False where possible. + """ + + if not FrontendConfiguration.target_is_compartmental(): + return + enforced_variable_name = FrontendConfiguration.getCompartmentalVariableName() + + state_blocks = neuron.get_state_blocks() + if state_blocks is None: + cls.log_error(neuron, neuron.get_source_position(), enforced_variable_name) + return False + + if isinstance(state_blocks, ASTBlockWithVariables): + state_blocks = [state_blocks] + + for state_block in state_blocks: + declarations = state_block.get_declarations() + for declaration in declarations: + variables = declaration.get_variables() + for variable in variables: + variable_name = variable.get_name().lower().strip() + if variable_name == enforced_variable_name: + return True + + cls.log_error(neuron, state_blocks[0].get_source_position(), enforced_variable_name) + return False + + @classmethod + def log_error(cls, neuron: ASTNeuron, error_position, missing_variable_name): + code, message = Messages.get_v_comp_variable_value_missing(neuron.get_name(), missing_variable_name) + Logger.log_message(error_position=error_position, node=neuron, log_level=LoggingLevel.ERROR, code=code, message=message) diff --git a/pynestml/cocos/co_co_variable_once_per_scope.py b/pynestml/cocos/co_co_variable_once_per_scope.py index 02f15f86a..b9ab46108 100644 --- a/pynestml/cocos/co_co_variable_once_per_scope.py +++ b/pynestml/cocos/co_co_variable_once_per_scope.py @@ -20,7 +20,6 @@ # along with NEST. If not, see . from pynestml.cocos.co_co import CoCo from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.variable_symbol import VariableType from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages @@ -31,14 +30,14 @@ class CoCoVariableOncePerScope(CoCo): """ @classmethod - def check_co_co(cls, node): + def check_co_co(cls, neuron): """ Checks if each variable is defined at most once per scope. Obviously, this test does not check if a declaration is shadowed by an embedded scope. - :param node: a single neuron - :type node: ast_neuron + :param neuron: a single neuron + :type neuron: ast_neuron """ - cls.__check_scope(node, node.get_scope()) + cls.__check_scope(neuron, neuron.get_scope()) @classmethod def __check_scope(cls, neuron, scope): diff --git a/pynestml/cocos/co_co_vector_declaration_right_size.py b/pynestml/cocos/co_co_vector_declaration_right_size.py new file mode 100644 index 000000000..97722c6a5 --- /dev/null +++ b/pynestml/cocos/co_co_vector_declaration_right_size.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# +# co_co_vector_declaration_right_size.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.integer_type_symbol import IntegerTypeSymbol +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor + + +class CoCoVectorDeclarationRightSize(CoCo): + """ + This CoCo checks if the size of the vector during vector declaration is greater than 0 + """ + + @classmethod + def check_co_co(cls, node: ASTNeuron): + visitor = VectorDeclarationVisitor() + node.accept(visitor) + + +class VectorDeclarationVisitor(ASTVisitor): + """ + This visitor ensures that vectors are declared with size greater than 0 + """ + + def visit_declaration(self, node: ASTDeclaration): + + variables = node.get_variables() + for variable in variables: + vector_parameter = variable.get_vector_parameter() + if vector_parameter is not None: + vector_parameter_var = ASTVariable(vector_parameter, scope=node.get_scope()) + symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(), + SymbolKind.VARIABLE) + vector_parameter_val = None + if symbol is not None: + if isinstance(symbol.get_type_symbol(), IntegerTypeSymbol): + vector_parameter_val = int(str(symbol.get_declaring_expression())) + else: + vector_parameter_val = int(vector_parameter) + + if vector_parameter_val is not None and vector_parameter_val <= 0: + code, message = Messages.get_vector_parameter_wrong_size(vector_parameter_var.get_complete_name(), + str(vector_parameter_val)) + Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, + code=code, message=message) diff --git a/pynestml/cocos/co_co_vector_parameter_declared_in_right_block.py b/pynestml/cocos/co_co_vector_parameter_declared_in_right_block.py new file mode 100644 index 000000000..2aff2918f --- /dev/null +++ b/pynestml/cocos/co_co_vector_parameter_declared_in_right_block.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# co_co_vector_parameter_declared_in_right_block.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import BlockType +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor + + +class CoCoVectorParameterDeclaredInRightBlock(CoCo): + """ + This CoCo ensures that the vector parameter is declared in either the parameters or internals block. + """ + + @classmethod + def check_co_co(cls, node: ASTNeuron): + visitor = VectorDeclarationVisitor() + node.accept(visitor) + + +class VectorDeclarationVisitor(ASTVisitor): + """ + This visitor ensures that the vector parameter is declared in the right block and has an integer type. + """ + + def visit_declaration(self, node: ASTDeclaration): + + variables = node.get_variables() + for var in variables: + vector_parameter = var.get_vector_parameter() + if vector_parameter is not None: + vector_parameter_var = ASTVariable(vector_parameter, scope=node.get_scope()) + symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(), + SymbolKind.VARIABLE) + # vector parameter is a variable + if symbol is not None: + if not symbol.block_type == BlockType.PARAMETERS and not symbol.block_type == BlockType.INTERNALS: + code, message = Messages.get_vector_parameter_wrong_block(vector_parameter_var.get_complete_name(), + str(symbol.block_type)) + Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, + code=code, message=message) diff --git a/pynestml/cocos/co_co_vector_parameter_greater_than_zero.py b/pynestml/cocos/co_co_vector_parameter_greater_than_zero.py new file mode 100644 index 000000000..7cd14eb08 --- /dev/null +++ b/pynestml/cocos/co_co_vector_parameter_greater_than_zero.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# +# co_co_vector_parameter_greater_than_zero.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor + + +class CoCoVectorParameterGreaterThanZero(CoCo): + """ + This CoCo checks if the size of the vector (vector parameter) in a vector declaration is greater than 0 + """ + + @classmethod + def check_co_co(cls, node: ASTNeuron): + visitor = VectorDeclarationVisitor() + node.accept(visitor) + + +class VectorDeclarationVisitor(ASTVisitor): + + def visit_declaration(self, node: ASTDeclaration): + variables = node.get_variables() + + for variable in variables: + vector_parameter = variable.get_vector_parameter() + if vector_parameter is not None: + vector_parameter_var = ASTVariable(vector_parameter, scope=node.get_scope()) + symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(), + SymbolKind.VARIABLE) + if symbol is not None: + value = int(str(symbol.get_declaring_expression())) + else: + value = int(vector_parameter) + + if value <= 0: + code, message = Messages.get_vector_parameter_wrong_size(vector_parameter_var.get_complete_name(), + str(value)) + Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, + code=code, message=message) diff --git a/pynestml/cocos/co_co_vector_parameter_right_type.py b/pynestml/cocos/co_co_vector_parameter_right_type.py new file mode 100644 index 000000000..55bb009cc --- /dev/null +++ b/pynestml/cocos/co_co_vector_parameter_right_type.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# +# co_co_vector_parameter_right_type.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.integer_type_symbol import IntegerTypeSymbol +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor + + +class CoCoVectorParameterRightType(CoCo): + """ + This CoCo ensures that the vector parameter is of the integer type + """ + @classmethod + def check_co_co(cls, node: ASTNeuron): + visitor = VectorVariablesVisitor() + node.accept(visitor) + + +class VectorVariablesVisitor(ASTVisitor): + """ + A visitor to check if all the variables with a vector parameter has the parameter of type integer + """ + def visit_variable(self, node: ASTVariable): + vector_parameter = node.get_vector_parameter() + if vector_parameter is not None: + vector_parameter_var = ASTVariable(vector_parameter, scope=node.get_scope()) + symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(), + SymbolKind.VARIABLE) + + # vector parameter is a variable + if symbol is not None: + if not isinstance(symbol.get_type_symbol(), IntegerTypeSymbol): + code, message = Messages.get_vector_parameter_wrong_type(vector_parameter_var.get_complete_name()) + Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, + code=code, message=message) diff --git a/pynestml/cocos/co_co_vector_variable_in_non_vector_declaration.py b/pynestml/cocos/co_co_vector_variable_in_non_vector_declaration.py index 0163a6e5a..764f6ff94 100644 --- a/pynestml/cocos/co_co_vector_variable_in_non_vector_declaration.py +++ b/pynestml/cocos/co_co_vector_variable_in_non_vector_declaration.py @@ -19,6 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.cocos.co_co import CoCo from pynestml.symbols.symbol import SymbolKind from pynestml.utils.logger import Logger, LoggingLevel @@ -37,12 +38,12 @@ class CoCoVectorVariableInNonVectorDeclaration(CoCo): @classmethod def check_co_co(cls, node): """ - Ensures the coco for the handed over neuron. - :param node: a single neuron instance. - :type node: ASTNeuron + Ensures the coco for the handed over node. + :param node: a single node instance. + :type node: ASTNeuron or ASTSynapse """ - assert (node is not None and isinstance(node, ASTNeuron)), \ - '(PyNestML.CoCo.BufferNotAssigned) No or wrong type of neuron provided (%s)!' % type(node) + assert node is not None and (isinstance(node, ASTNeuron) or isinstance(node, ASTSynapse)), \ + '(PyNestML.CoCo.BufferNotAssigned) No or wrong type provided (%s): expecting neuron or synapse!' % type(node) node.accept(VectorInDeclarationVisitor()) return diff --git a/pynestml/cocos/co_cos_manager.py b/pynestml/cocos/co_cos_manager.py index db3bfff0c..da03a2b77 100644 --- a/pynestml/cocos/co_cos_manager.py +++ b/pynestml/cocos/co_cos_manager.py @@ -18,133 +18,190 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Union + from pynestml.cocos.co_co_all_variables_defined import CoCoAllVariablesDefined -from pynestml.cocos.co_co_buffer_not_assigned import CoCoBufferNotAssigned +from pynestml.cocos.co_co_input_port_not_assigned_to import CoCoInputPortNotAssignedTo +from pynestml.cocos.co_co_compartmental_model import CoCoCompartmentalModel from pynestml.cocos.co_co_convolve_cond_correctly_built import CoCoConvolveCondCorrectlyBuilt from pynestml.cocos.co_co_correct_numerator_of_unit import CoCoCorrectNumeratorOfUnit from pynestml.cocos.co_co_correct_order_in_equation import CoCoCorrectOrderInEquation -from pynestml.cocos.co_co_current_buffers_not_specified import CoCoCurrentBuffersNotSpecified -from pynestml.cocos.co_co_each_block_unique_and_defined import CoCoEachBlockUniqueAndDefined +from pynestml.cocos.co_co_continuous_input_port_not_qualified import CoCoContinuousInputPortNotQualified +from pynestml.cocos.co_co_each_block_defined_at_most_once import CoCoEachBlockDefinedAtMostOnce from pynestml.cocos.co_co_equations_only_for_init_values import CoCoEquationsOnlyForInitValues from pynestml.cocos.co_co_function_calls_consistent import CoCoFunctionCallsConsistent -from pynestml.cocos.co_co_function_have_rhs import CoCoFunctionHaveRhs -from pynestml.cocos.co_co_function_max_one_lhs import CoCoFunctionMaxOneLhs from pynestml.cocos.co_co_function_unique import CoCoFunctionUnique from pynestml.cocos.co_co_illegal_expression import CoCoIllegalExpression -from pynestml.cocos.co_co_init_vars_with_odes_provided import CoCoInitVarsWithOdesProvided +from pynestml.cocos.co_co_inline_expressions_have_rhs import CoCoInlineExpressionsHaveRhs +from pynestml.cocos.co_co_inline_max_one_lhs import CoCoInlineMaxOneLhs +from pynestml.cocos.co_co_integrate_odes_called_if_equations_defined import CoCoIntegrateOdesCalledIfEquationsDefined from pynestml.cocos.co_co_invariant_is_boolean import CoCoInvariantIsBoolean from pynestml.cocos.co_co_neuron_name_unique import CoCoNeuronNameUnique from pynestml.cocos.co_co_no_nest_name_space_collision import CoCoNoNestNameSpaceCollision from pynestml.cocos.co_co_no_kernels_except_in_convolve import CoCoNoKernelsExceptInConvolve -from pynestml.cocos.co_co_no_two_neurons_in_set_of_compilation_units import CoCoNoTwoNeuronsInSetOfCompilationUnits +from pynestml.cocos.co_co_no_duplicate_compilation_unit_names import CoCoNoDuplicateCompilationUnitNames from pynestml.cocos.co_co_odes_have_consistent_units import CoCoOdesHaveConsistentUnits from pynestml.cocos.co_co_kernel_type import CoCoKernelType from pynestml.cocos.co_co_simple_delta_function import CoCoSimpleDeltaFunction from pynestml.cocos.co_co_ode_functions_have_consistent_units import CoCoOdeFunctionsHaveConsistentUnits from pynestml.cocos.co_co_output_port_defined_if_emit_call import CoCoOutputPortDefinedIfEmitCall -from pynestml.cocos.co_co_buffer_data_type import CoCoBufferDataType +from pynestml.cocos.co_co_input_port_data_type import CoCoInputPortDataType from pynestml.cocos.co_co_parameters_assigned_only_in_parameter_block import \ CoCoParametersAssignedOnlyInParameterBlock +from pynestml.cocos.co_co_resolution_func_legally_used import CoCoResolutionFuncLegallyUsed +from pynestml.cocos.co_co_state_variables_initialized import CoCoStateVariablesInitialized from pynestml.cocos.co_co_sum_has_correct_parameter import CoCoSumHasCorrectParameter -from pynestml.cocos.co_co_buffer_qualifier_unique import CoCoBufferQualifierUnique +from pynestml.cocos.co_co_synapses_model import CoCoSynapsesModel +from pynestml.cocos.co_co_input_port_qualifier_unique import CoCoInputPortQualifierUnique from pynestml.cocos.co_co_user_defined_function_correctly_defined import CoCoUserDefinedFunctionCorrectlyDefined +from pynestml.cocos.co_co_v_comp_exists import CoCoVCompDefined from pynestml.cocos.co_co_variable_once_per_scope import CoCoVariableOncePerScope +from pynestml.cocos.co_co_vector_declaration_right_size import CoCoVectorDeclarationRightSize +from pynestml.cocos.co_co_vector_parameter_declared_in_right_block import CoCoVectorParameterDeclaredInRightBlock +from pynestml.cocos.co_co_vector_parameter_greater_than_zero import CoCoVectorParameterGreaterThanZero +from pynestml.cocos.co_co_vector_parameter_right_type import CoCoVectorParameterRightType from pynestml.cocos.co_co_vector_variable_in_non_vector_declaration import CoCoVectorVariableInNonVectorDeclaration from pynestml.cocos.co_co_function_argument_template_types_consistent import CoCoFunctionArgumentTemplateTypesConsistent +from pynestml.cocos.co_co_priorities_correctly_specified import CoCoPrioritiesCorrectlySpecified from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse -class CoCosManager(object): +class CoCosManager: """ This class provides a set of context conditions which have to hold for each neuron instance. """ @classmethod - def check_function_defined(cls, neuron): + def check_function_defined(cls, neuron: ASTNeuron): """ Checks for the handed over neuron that each used function it is defined. """ CoCoFunctionUnique.check_co_co(neuron) @classmethod - def check_each_block_unique_and_defined(cls, neuron): + def check_each_block_defined_at_most_once(cls, node: Union[ASTNeuron, ASTSynapse]): """ - Checks if in the handed over neuron each block ist defined at most once and mandatory blocks are defined. - :param neuron: a single neuron instance - :type neuron: ast_neuron + Checks if in the handed over neuron or synapse, each block is defined at most once and mandatory blocks are defined. + :param node: a single neuron or synapse instance """ - CoCoEachBlockUniqueAndDefined.check_co_co(neuron) + CoCoEachBlockDefinedAtMostOnce.check_co_co(node) @classmethod - def check_function_declared_and_correctly_typed(cls, neuron): + def check_function_declared_and_correctly_typed(cls, neuron: ASTNeuron): """ Checks if in the handed over neuron all function calls use existing functions and the arguments are correctly typed. :param neuron: a single neuron instance - :type neuron: ast_neuron """ CoCoFunctionCallsConsistent.check_co_co(neuron) @classmethod - def check_variables_unique_in_scope(cls, neuron): + def check_variables_unique_in_scope(cls, neuron: ASTNeuron): """ Checks that all variables have been declared at most once per scope. :param neuron: a single neuron instance - :type neuron: ast_neuron """ CoCoVariableOncePerScope.check_co_co(neuron) @classmethod - def check_variables_defined_before_usage(cls, neuron): + def check_state_variables_initialized(cls, neuron: ASTNeuron): + """ + Checks if all the variables declared in state block are initialized with a value + :param neuron: a single neuron instance + """ + CoCoStateVariablesInitialized.check_co_co(neuron) + + @classmethod + def check_variables_defined_before_usage(cls, neuron: ASTNeuron, after_ast_rewrite: bool) -> None: """ Checks that all variables are defined before being used. :param neuron: a single neuron. - :type neuron: ast_neuron """ - CoCoAllVariablesDefined.check_co_co(neuron) + CoCoAllVariablesDefined.check_co_co(neuron, after_ast_rewrite) @classmethod - def check_functions_have_rhs(cls, neuron): + def check_synapses_model(cls, neuron: ASTNeuron) -> None: + """ + similar to check_compartmental_model, but checks for synapses + synapses are defined by inlines that use kernels """ - Checks that all functions have a right-hand side, e.g., function V_reset mV = V_m - 55mV + CoCoSynapsesModel.check_co_co(neuron) + + @classmethod + def check_v_comp_requirement(cls, neuron: ASTNeuron, after_ast_rewrite: bool): + """ + In compartmental case, checks if v_comp variable was defined :param neuron: a single neuron object + """ + CoCoVCompDefined.check_co_co(neuron, after_ast_rewrite) + + @classmethod + def check_compartmental_model(cls, neuron: ASTNeuron, after_ast_rewrite: bool) -> None: + """ + searches ASTEquationsBlock for inline expressions without kernels + + If such inline expression is found + -finds all gatomg variables x_{channel_name} used in that expression + -makes sure following functions are defined: + + x_inf_{channelType}(somevariable real) real + tau_x_{channelType}(somevariable real) real + + -makes sure that all such functions have exactly one argument and that + they return real + + -makes sure that all Variables x are defined in state block + -makes sure that state block contains + + gbar_{channelType} + e_{channelType} + + -makes sure that in the key inline expression every variable is used only once + -makes sure there is at least one gating variable per cm inline expression + :param neuron: a single neuron. :type neuron: ast_neuron """ - CoCoFunctionHaveRhs.check_co_co(neuron) + CoCoCompartmentalModel.check_co_co(neuron) + + @classmethod + def check_inline_expressions_have_rhs(cls, neuron: ASTNeuron): + """ + Checks that all inline expressions have a right-hand side. + :param neuron: a single neuron object + """ + CoCoInlineExpressionsHaveRhs.check_co_co(neuron) @classmethod - def check_function_has_max_one_lhs(cls, neuron): + def check_inline_has_max_one_lhs(cls, neuron: ASTNeuron): """ - Checks that all functions have exactly one left-hand side, e.g., function V_reset mV = V_m - 55mV + Checks that all inline expressions have exactly one left-hand side. :param neuron: a single neuron object. - :type neuron: ast_neuron """ - CoCoFunctionMaxOneLhs.check_co_co(neuron) + CoCoInlineMaxOneLhs.check_co_co(neuron) @classmethod - def check_no_values_assigned_to_buffers(cls, neuron): + def check_input_ports_not_assigned_to(cls, neuron: ASTNeuron): """ - Checks that no values are assigned to buffers. + Checks that no values are assigned to input ports. :param neuron: a single neuron object. - :type neuron: ast_neuron """ - CoCoBufferNotAssigned.check_co_co(neuron) + CoCoInputPortNotAssignedTo.check_co_co(neuron) @classmethod - def check_order_of_equations_correct(cls, neuron): + def check_order_of_equations_correct(cls, neuron: ASTNeuron): """ Checks that all equations specify the order of the variable. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoCorrectOrderInEquation.check_co_co(neuron) @classmethod - def check_numerator_of_unit_is_one_if_numeric(cls, neuron): + def check_numerator_of_unit_is_one_if_numeric(cls, neuron: ASTNeuron): """ Checks that all units which have a numeric numerator use 1. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoCorrectNumeratorOfUnit.check_co_co(neuron) @@ -158,22 +215,20 @@ def check_neuron_names_unique(cls, compilation_unit): CoCoNeuronNameUnique.check_co_co(compilation_unit) @classmethod - def check_no_nest_namespace_collisions(cls, neuron): + def check_no_nest_namespace_collisions(cls, neuron: ASTNeuron): """ Checks that all units which have a numeric numerator use 1. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoNoNestNameSpaceCollision.check_co_co(neuron) @classmethod - def check_buffer_qualifier_unique(cls, neuron): + def check_input_port_qualifier_unique(cls, neuron: ASTNeuron): """ - Checks that all spike buffers have a unique type, i.e., no buffer is defined with redundant keywords. + Checks that no spiking input ports are defined with redundant qualifiers. :param neuron: a single neuron object. - :type neuron: ast_neuron """ - CoCoBufferQualifierUnique.check_co_co(neuron) + CoCoInputPortQualifierUnique.check_co_co(neuron) @classmethod def check_kernel_type(cls, neuron: ASTNeuron) -> None: @@ -183,25 +238,23 @@ def check_kernel_type(cls, neuron: ASTNeuron) -> None: CoCoKernelType.check_co_co(neuron) @classmethod - def check_parameters_not_assigned_outside_parameters_block(cls, neuron): + def check_parameters_not_assigned_outside_parameters_block(cls, neuron: ASTNeuron): """ Checks that parameters are not assigned outside the parameters block. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoParametersAssignedOnlyInParameterBlock.check_co_co(neuron) @classmethod - def check_current_buffers_no_keywords(cls, neuron): + def check_continuous_input_ports_not_qualified(cls, neuron: ASTNeuron): """ - Checks that input current buffers have not been specified with keywords, e.g., inhibitory. + Checks that continuous time input ports have not been specified with keywords, e.g., inhibitory. :param neuron: a single neuron object. - :type neuron: ast_neuron """ - CoCoCurrentBuffersNotSpecified.check_co_co(neuron) + CoCoContinuousInputPortNotQualified.check_co_co(neuron) @classmethod - def check_output_port_defined_if_emit_call(cls, neuron): + def check_output_port_defined_if_emit_call(cls, neuron: ASTNeuron): """ Checks that if emit_spike() function is called, an spiking output port is defined. :param neuron: a single neuron object. @@ -210,120 +263,107 @@ def check_output_port_defined_if_emit_call(cls, neuron): CoCoOutputPortDefinedIfEmitCall.check_co_co(neuron) @classmethod - def check_odes_have_consistent_units(cls, neuron): + def check_odes_have_consistent_units(cls, neuron: ASTNeuron): """ Checks that all ODE lhs and rhs have consistent units. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoOdesHaveConsistentUnits.check_co_co(neuron) @classmethod - def check_ode_functions_have_consistent_units(cls, neuron): + def check_ode_functions_have_consistent_units(cls, neuron: ASTNeuron): """ Checks that all ODE function lhs and rhs have consistent units. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoOdeFunctionsHaveConsistentUnits.check_co_co(neuron) @classmethod - def check_buffer_types_are_correct(cls, neuron): + def check_input_port_data_type(cls, neuron: ASTNeuron): """ - Checks that input buffers have specified the data type if required an no data type if not allowed. + Checks that input ports have specified the data type if required and no data type if not allowed. :param neuron: a single neuron object. - :type neuron: ast_neuron """ - CoCoBufferDataType.check_co_co(neuron) + CoCoInputPortDataType.check_co_co(neuron) @classmethod - def check_init_vars_with_odes_provided(cls, neuron): + def check_integrate_odes_called_if_equations_defined(cls, neuron: ASTNeuron): """ - Checks that all initial variables have a rhs and are provided with the corresponding ode declaration. - :param neuron: a single neuron object. - :type neuron: ast_neuron + Ensures that integrate_odes() is called if one or more dynamical equations are defined. """ - CoCoInitVarsWithOdesProvided.check_co_co(neuron) + CoCoIntegrateOdesCalledIfEquationsDefined.check_co_co(neuron) @classmethod - def check_user_defined_function_correctly_built(cls, neuron): + def check_user_defined_function_correctly_built(cls, neuron: ASTNeuron): """ Checks that all user defined functions are correctly constructed, i.e., have a return statement if declared and that the type corresponds to the declared one. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoUserDefinedFunctionCorrectlyDefined.check_co_co(neuron) @classmethod - def check_initial_ode_initial_values(cls, neuron): + def check_initial_ode_initial_values(cls, neuron: ASTNeuron): """ - Checks if variables of odes are declared in the initial_values block. + Checks if variables of odes are declared in the state block. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoEquationsOnlyForInitValues.check_co_co(neuron) @classmethod - def check_convolve_cond_curr_is_correct(cls, neuron): + def check_convolve_cond_curr_is_correct(cls, neuron: ASTNeuron): """ Checks if all convolve rhs are correctly provided with arguments. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoConvolveCondCorrectlyBuilt.check_co_co(neuron) @classmethod - def check_correct_usage_of_kernels(cls, neuron): + def check_correct_usage_of_kernels(cls, neuron: ASTNeuron): """ Checks if all kernels are only used in convolve. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoNoKernelsExceptInConvolve.check_co_co(neuron) @classmethod - def check_not_two_neurons_across_units(cls, compilation_units): + def check_no_duplicate_compilation_unit_names(cls, compilation_units): """ - Checks if in a set of compilation units, two neurons have the same name. - :param compilation_units: a list of compilation units + Checks if in a set of compilation units, two nodes have the same name. + :param compilation_units: a list of compilation units :type compilation_units: list(ASTNestMLCompilationUnit) """ - CoCoNoTwoNeuronsInSetOfCompilationUnits.check_co_co(compilation_units) + CoCoNoDuplicateCompilationUnitNames.check_co_co(compilation_units) @classmethod - def check_invariant_type_correct(cls, neuron): + def check_invariant_type_correct(cls, neuron: ASTNeuron): """ Checks if all invariants are of type boolean. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoInvariantIsBoolean.check_co_co(neuron) @classmethod - def check_vector_in_non_vector_declaration_detected(cls, neuron): + def check_vector_in_non_vector_declaration_detected(cls, neuron: ASTNeuron): """ Checks if no declaration a vector value is added to a non vector one. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoVectorVariableInNonVectorDeclaration.check_co_co(neuron) @classmethod - def check_sum_has_correct_parameter(cls, neuron): + def check_sum_has_correct_parameter(cls, neuron: ASTNeuron): """ Checks that all convolve function calls have variables as arguments. :param neuron: a single neuron object. - :type neuron: ast_neuron """ CoCoSumHasCorrectParameter.check_co_co(neuron) @classmethod - def check_expression_correct(cls, neuron): + def check_expression_correct(cls, neuron: ASTNeuron): """ Checks that all rhs in the model are correctly constructed, e.g. type(lhs)==type(rhs). :param neuron: a single neuron - :type neuron: ast_neuron """ CoCoIllegalExpression.check_co_co(neuron) @@ -331,27 +371,77 @@ def check_expression_correct(cls, neuron): def check_simple_delta_function(cls, neuron: ASTNeuron) -> None: CoCoSimpleDeltaFunction.check_co_co(neuron) + @classmethod + def check_function_argument_template_types_consistent(cls, neuron: ASTNeuron): + """ + Checks if no declaration a vector value is added to a non vector one. + :param neuron: a single neuron object. + """ + CoCoFunctionArgumentTemplateTypesConsistent.check_co_co(neuron) + + @classmethod + def check_vector_parameter_declaration(cls, neuron: ASTNeuron): + """ + Checks if the vector parameter is declared in the right block + :param neuron: a single neuron object + """ + CoCoVectorParameterDeclaredInRightBlock.check_co_co(neuron) + + @classmethod + def check_vector_parameter_type(cls, neuron: ASTNeuron): + """ + Checks if the vector parameter has the right type. + :param neuron: a single neuron object + """ + CoCoVectorParameterRightType.check_co_co(neuron) + + @classmethod + def check_vector_declaration_size(cls, neuron: ASTNeuron): + """ + Checks if the vector is declared with a size greater than 0 + :param neuron: a single neuron object + """ + CoCoVectorDeclarationRightSize.check_co_co(neuron) + + @classmethod + def check_co_co_priorities_correctly_specified(cls, neuron: ASTNeuron): + """ + :param neuron: a single neuron object. + """ + CoCoPrioritiesCorrectlySpecified.check_co_co(neuron) + + @classmethod + def check_resolution_func_legally_used(cls, neuron: ASTNeuron): + """ + :param neuron: a single neuron object. + """ + CoCoResolutionFuncLegallyUsed.check_co_co(neuron) + @classmethod def post_symbol_table_builder_checks(cls, neuron: ASTNeuron, after_ast_rewrite: bool = False): """ Checks all context conditions. :param neuron: a single neuron object. - :type neuron: ASTNeuron """ + cls.check_each_block_defined_at_most_once(neuron) cls.check_function_defined(neuron) cls.check_function_declared_and_correctly_typed(neuron) cls.check_variables_unique_in_scope(neuron) - cls.check_variables_defined_before_usage(neuron) - cls.check_functions_have_rhs(neuron) - cls.check_function_has_max_one_lhs(neuron) - cls.check_no_values_assigned_to_buffers(neuron) + cls.check_state_variables_initialized(neuron) + cls.check_variables_defined_before_usage(neuron, after_ast_rewrite) + cls.check_v_comp_requirement(neuron, after_ast_rewrite) + cls.check_compartmental_model(neuron, after_ast_rewrite) + cls.check_synapses_model(neuron) + cls.check_inline_expressions_have_rhs(neuron) + cls.check_inline_has_max_one_lhs(neuron) + cls.check_input_ports_not_assigned_to(neuron) cls.check_order_of_equations_correct(neuron) cls.check_numerator_of_unit_is_one_if_numeric(neuron) cls.check_no_nest_namespace_collisions(neuron) - cls.check_buffer_qualifier_unique(neuron) + cls.check_input_port_qualifier_unique(neuron) cls.check_parameters_not_assigned_outside_parameters_block(neuron) - cls.check_current_buffers_no_keywords(neuron) - cls.check_buffer_types_are_correct(neuron) + cls.check_continuous_input_ports_not_qualified(neuron) + cls.check_input_port_data_type(neuron) cls.check_user_defined_function_correctly_built(neuron) cls.check_initial_ode_initial_values(neuron) cls.check_kernel_type(neuron) @@ -360,31 +450,18 @@ def post_symbol_table_builder_checks(cls, neuron: ASTNeuron, after_ast_rewrite: if not after_ast_rewrite: # units might be incorrect due to e.g. refactoring convolve call (Real type assigned) cls.check_odes_have_consistent_units(neuron) - cls.check_ode_functions_have_consistent_units(neuron) # ODE functions have been removed at this point + # ODE functions have been removed at this point + cls.check_ode_functions_have_consistent_units(neuron) cls.check_correct_usage_of_kernels(neuron) + cls.check_integrate_odes_called_if_equations_defined(neuron) cls.check_invariant_type_correct(neuron) cls.check_vector_in_non_vector_declaration_detected(neuron) cls.check_sum_has_correct_parameter(neuron) cls.check_expression_correct(neuron) cls.check_simple_delta_function(neuron) cls.check_function_argument_template_types_consistent(neuron) - return - - @classmethod - def post_ode_specification_checks(cls, neuron): - """ - Checks the following constraints: - cls.check_init_vars_with_odes_provided - :param neuron: a single neuron object. - :type neuron: ast_neuron - """ - cls.check_init_vars_with_odes_provided(neuron) - - @classmethod - def check_function_argument_template_types_consistent(cls, neuron): - """ - Checks if no declaration a vector value is added to a non vector one. - :param neuron: a single neuron object. - :type neuron: ast_neuron - """ - CoCoFunctionArgumentTemplateTypesConsistent.check_co_co(neuron) + cls.check_vector_parameter_declaration(neuron) + cls.check_vector_parameter_type(neuron) + cls.check_co_co_priorities_correctly_specified(neuron) + cls.check_resolution_func_legally_used(neuron) + cls.check_vector_declaration_size(neuron) diff --git a/pynestml/codegeneration/__init__.py b/pynestml/codegeneration/__init__.py index 48f800721..5c13189a1 100644 --- a/pynestml/codegeneration/__init__.py +++ b/pynestml/codegeneration/__init__.py @@ -19,9 +19,4 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -__all__ = ['nest_assignments_helper.py', 'nest_codegeneration.py', 'nest_declarations_helper.py', - 'expressions_pretty_printer.py', 'pynestml_2_nest_type_converter.py', - 'nest_names_converter.py', 'nest_printer.py', 'gsl_names_converter.py', 'gsl_reference_converter.py', - 'i_reference_converter.py', 'idempotent_reference_converter.py', 'nest_reference_converter.py', - 'legacy_expression_printer.py', - 'unit_converter.py', 'codegeneration.py'] +__all__ = ['ast_transformers.py', 'autodoc_code_generator.py', 'builder.py', 'code_generator.py', 'nest_assignments_helper.py', 'nest_builder.py', 'nest_code_generator.py', 'nest_declarations_helper.py'] diff --git a/pynestml/codegeneration/ast_transformers.py b/pynestml/codegeneration/ast_transformers.py deleted file mode 100644 index d50171312..000000000 --- a/pynestml/codegeneration/ast_transformers.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# -# ast_transformers.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -import re - -from typing import List, Mapping - -from pynestml.codegeneration.expressions_pretty_printer import ExpressionsPrettyPrinter -from pynestml.symbols.variable_symbol import BlockType -from pynestml.meta_model.ast_assignment import ASTAssignment -from pynestml.meta_model.ast_declaration import ASTDeclaration -from pynestml.meta_model.ast_expression import ASTExpression -from pynestml.meta_model.ast_neuron import ASTNeuron -from pynestml.meta_model.ast_node_factory import ASTNodeFactory -from pynestml.meta_model.ast_kernel import ASTKernel -from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.symbol import SymbolKind -from pynestml.utils.ast_utils import ASTUtils -from pynestml.utils.model_parser import ModelParser -from pynestml.utils.ode_transformer import OdeTransformer -from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor -from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor - - -def add_declarations_to_internals(neuron: ASTNeuron, declarations: Mapping[str, str]) -> ASTNeuron: - """ - Adds the variables as stored in the declaration tuples to the neuron. - :param neuron: a single neuron instance - :param declarations: a map of variable names to declarations - :return: a modified neuron - """ - for variable in declarations: - add_declaration_to_internals(neuron, variable, declarations[variable]) - return neuron - - -def add_declaration_to_internals(neuron: ASTNeuron, variable_name: str, init_expression: str) -> ASTNeuron: - """ - Adds the variable as stored in the declaration tuple to the neuron. The declared variable is of type real. - :param neuron: a single neuron instance - :param variable_name: the name of the variable to add - :param init_expression: initialization expression - :return: the neuron extended by the variable - """ - tmp = ModelParser.parse_expression(init_expression) - vector_variable = ASTUtils.get_vectorized_variable(tmp, neuron.get_scope()) - - declaration_string = variable_name + ' real' + ( - '[' + vector_variable.get_vector_parameter() + ']' - if vector_variable is not None and vector_variable.has_vector_parameter() else '') + ' = ' + init_expression - ast_declaration = ModelParser.parse_declaration(declaration_string) - if vector_variable is not None: - ast_declaration.set_size_parameter(vector_variable.get_vector_parameter()) - neuron.add_to_internal_block(ast_declaration) - ast_declaration.update_scope(neuron.get_internals_blocks().get_scope()) - symtable_visitor = ASTSymbolTableVisitor() - symtable_visitor.block_type_stack.push(BlockType.INTERNALS) - ast_declaration.accept(symtable_visitor) - symtable_visitor.block_type_stack.pop() - return neuron - - -def add_declarations_to_initial_values(neuron: ASTNeuron, variables: List, initial_values: List) -> ASTNeuron: - """ - Adds a single declaration to the initial values block of the neuron. - :param neuron: a neuron - :param variables: list of variables - :param initial_values: list of initial values - :return: a modified neuron - """ - for variable, initial_value in zip(variables, initial_values): - add_declaration_to_initial_values(neuron, variable, initial_value) - return neuron - - -def add_declaration_to_initial_values(neuron: ASTNeuron, variable: str, initial_value: str) -> ASTNeuron: - """ - Adds a single declaration to the initial values block of the neuron. The declared variable is of type real. - :param neuron: a neuron - :param variable: state variable to add - :param initial_value: corresponding initial value - :return: a modified neuron - """ - tmp = ModelParser.parse_expression(initial_value) - vector_variable = ASTUtils.get_vectorized_variable(tmp, neuron.get_scope()) - declaration_string = variable + ' real' + ( - '[' + vector_variable.get_vector_parameter() + ']' - if vector_variable is not None and vector_variable.has_vector_parameter() else '') + ' = ' + initial_value - ast_declaration = ModelParser.parse_declaration(declaration_string) - if vector_variable is not None: - ast_declaration.set_size_parameter(vector_variable.get_vector_parameter()) - neuron.add_to_initial_values_block(ast_declaration) - ast_declaration.update_scope(neuron.get_initial_values_blocks().get_scope()) - - symtable_visitor = ASTSymbolTableVisitor() - symtable_visitor.block_type_stack.push(BlockType.INITIAL_VALUES) - ast_declaration.accept(symtable_visitor) - symtable_visitor.block_type_stack.pop() - - return neuron - - -def declaration_in_initial_values(neuron: ASTNeuron, variable_name: str) -> bool: - assert type(variable_name) is str - - for decl in neuron.get_initial_values_blocks().get_declarations(): - for var in decl.get_variables(): - if var.get_complete_name() == variable_name: - return True - - return False - - -def apply_incoming_spikes(neuron: ASTNeuron): - """ - Adds a set of update instructions to the handed over neuron. - :param neuron: a single neuron instance - :type neuron: ASTNeuron - :return: the modified neuron - :rtype: ASTNeuron - """ - assert (neuron is not None and isinstance(neuron, ASTNeuron)), \ - '(PyNestML.Solver.BaseTransformer) No or wrong type of neuron provided (%s)!' % type(neuron) - conv_calls = OdeTransformer.get_sum_function_calls(neuron) - printer = ExpressionsPrettyPrinter() - spikes_updates = list() - for convCall in conv_calls: - kernel = convCall.get_args()[0].get_variable().get_complete_name() - buffer = convCall.get_args()[1].get_variable().get_complete_name() - initial_values = ( - neuron.get_initial_values_blocks().get_declarations() if neuron.get_initial_values_blocks() is not None else list()) - for astDeclaration in initial_values: - for variable in astDeclaration.get_variables(): - if re.match(kernel + "[\']*", variable.get_complete_name()) or re.match(kernel + '__[\\d]+$', - variable.get_complete_name()): - spikes_updates.append(ModelParser.parse_assignment( - variable.get_complete_name() + " += " + buffer + " * " + printer.print_expression( - astDeclaration.get_expression()))) - for update in spikes_updates: - add_assignment_to_update_block(update, neuron) - return neuron - - -def add_assignment_to_update_block(assignment: ASTAssignment, neuron: ASTNeuron) -> ASTNeuron: - """ - Adds a single assignment to the end of the update block of the handed over neuron. - :param assignment: a single assignment - :param neuron: a single neuron instance - :return: the modified neuron - """ - small_stmt = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, - source_position=ASTSourceLocation.get_added_source_position()) - stmt = ASTNodeFactory.create_ast_stmt(small_stmt=small_stmt, - source_position=ASTSourceLocation.get_added_source_position()) - if not neuron.get_update_blocks(): - neuron.create_empty_update_block() - neuron.get_update_blocks().get_block().get_stmts().append(stmt) - small_stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) - stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) - return neuron - - -def add_declaration_to_update_block(declaration: ASTDeclaration, neuron: ASTNeuron) -> ASTNeuron: - """ - Adds a single declaration to the end of the update block of the handed over neuron. - :param declaration: ASTDeclaration node to add - :param neuron: a single neuron instance - :return: a modified neuron - """ - small_stmt = ASTNodeFactory.create_ast_small_stmt(declaration=declaration, - source_position=ASTSourceLocation.get_added_source_position()) - stmt = ASTNodeFactory.create_ast_stmt(small_stmt=small_stmt, - source_position=ASTSourceLocation.get_added_source_position()) - if not neuron.get_update_blocks(): - neuron.create_empty_update_block() - neuron.get_update_blocks().get_block().get_stmts().append(stmt) - small_stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) - stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) - return neuron - - -def add_state_updates(neuron: ASTNeuron, update_expressions: Mapping[str, str]) -> ASTNeuron: - """ - Adds all update instructions as contained in the solver output to the update block of the neuron. - :param neuron: a single neuron - :param update_expressions: map of variables to corresponding updates during the update step. - :return: a modified version of the neuron - """ - for variable, update_expression in update_expressions.items(): - declaration_statement = variable + '__tmp real = ' + update_expression - add_declaration_to_update_block(ModelParser.parse_declaration(declaration_statement), neuron) - for variable, update_expression in update_expressions.items(): - add_assignment_to_update_block(ModelParser.parse_assignment(variable + ' = ' + variable + '__tmp'), neuron) - return neuron - - -def variable_in_neuron_initial_values(name: str, neuron: ASTNeuron): - for decl in neuron.get_initial_blocks().get_declarations(): - assert len(decl.get_variables()) == 1, "Multiple declarations in the same statement not yet supported" - if decl.get_variables()[0].get_complete_name() == name: - return True - return False - - -def variable_in_solver(kernel_var: str, solver_dicts): - """ - Check if a variable by this name is defined in the ode-toolbox solver results, - """ - - for solver_dict in solver_dicts: - if solver_dict is None: - continue - - for var_name in solver_dict["state_variables"]: - var_name_base = var_name.split("__X__")[0] - if var_name_base == kernel_var: - return True - - return False - - -def is_ode_variable(var_base_name, neuron): - equations_block = neuron.get_equations_blocks() - for ode_eq in equations_block.get_ode_equations(): - var = ode_eq.get_lhs() - if var.get_name() == var_base_name: - return True - return False - - -def variable_in_kernels(var_name: str, kernels): - """ - Check if a variable by this name (in ode-toolbox style) is defined in the ode-toolbox solver results - """ - - var_name_base = var_name.split("__X__")[0] - var_name_base = var_name_base.split("__d")[0] - var_name_base = var_name_base.replace("__DOLLAR", "$") - - for kernel in kernels: - for kernel_var in kernel.get_variables(): - if var_name_base == kernel_var.get_name(): - return True - - return False - - -def get_initial_value_from_ode_toolbox_result(var_name: str, solver_dicts): - """ - Get the initial value of the variable with the given name from the ode-toolbox results JSON. - - N.B. the variable name is given in ode-toolbox notation. - """ - - for solver_dict in solver_dicts: - if solver_dict is None: - continue - - if var_name in solver_dict["state_variables"]: - return solver_dict["initial_values"][var_name] - - assert False, "Initial value not found for ODE with name \"" + var_name + "\"" - - -def get_kernel_var_order_from_ode_toolbox_result(kernel_var: str, solver_dicts): - """ - Get the differential order of the variable with the given name from the ode-toolbox results JSON. - - N.B. the variable name is given in NESTML notation, e.g. "g_in$"; convert to ode-toolbox export format notation (e.g. "g_in__DOLLAR"). - """ - - kernel_var = kernel_var.replace("$", "__DOLLAR") - - order = -1 - for solver_dict in solver_dicts: - if solver_dict is None: - continue - - for var_name in solver_dict["state_variables"]: - var_name_base = var_name.split("__X__")[0] - var_name_base = var_name_base.split("__d")[0] - if var_name_base == kernel_var: - order = max(order, var_name.count("__d") + 1) - - assert order >= 0, "Variable of name \"" + kernel_var + "\" not found in ode-toolbox result" - return order - - -def to_ode_toolbox_processed_name(name: str) -> str: - """ - Convert name in the same way as ode-toolbox does from input to output, i.e. returned names are compatible with ode-toolbox output - """ - return name.replace("$", "__DOLLAR").replace("'", "__d") - - -def to_ode_toolbox_name(name: str) -> str: - """ - Convert to a name suitable for ode-toolbox input - """ - return name.replace("$", "__DOLLAR") - - -def get_expr_from_kernel_var(kernel, var_name): - assert type(var_name) == str - for var, expr in zip(kernel.get_variables(), kernel.get_expressions()): - if var.get_complete_name() == var_name: - return expr - assert False, "variable name not found in kernel" - - -def construct_kernel_X_spike_buf_name(kernel_var_name: str, spike_input_port, order: int, diff_order_symbol="__d"): - assert type(kernel_var_name) is str - assert type(order) is int - assert type(diff_order_symbol) is str - return kernel_var_name.replace("$", "__DOLLAR") + "__X__" + str(spike_input_port) + diff_order_symbol * order - - -def replace_rhs_variable(expr, variable_name_to_replace, kernel_var, spike_buf): - def replace_kernel_var(node): - if type(node) is ASTSimpleExpression \ - and node.is_variable() \ - and node.get_variable().get_name() == variable_name_to_replace: - var_order = node.get_variable().get_differential_order() - new_variable_name = construct_kernel_X_spike_buf_name( - kernel_var.get_name(), spike_buf, var_order - 1, diff_order_symbol="'") - new_variable = ASTVariable(new_variable_name, var_order) - new_variable.set_source_position(node.get_variable().get_source_position()) - node.set_variable(new_variable) - - expr.accept(ASTHigherOrderVisitor(visit_funcs=replace_kernel_var)) - - -def replace_rhs_variables(expr, kernel_buffers): - """ - Replace variable names in definitions of kernel dynamics. - - Say that the kernel is - - .. code-block:: - - G = -G / tau - - Its variable symbol might be replaced by "G__X__spikesEx": - - .. code-block:: - - G__X__spikesEx = -G / tau - - This function updates the right-hand side of `expr` so that it would also read (in this example): - - .. code-block:: - - G__X__spikesEx = -G__X__spikesEx / tau - - These equations will later on be fed to ode-toolbox, so we use the symbol "'" to indicate differential order. - - Note that for kernels/systems of ODE of dimension > 1, all variable orders and all variables for this kernel will already be present in `kernel_buffers`. - """ - for kernel, spike_buf in kernel_buffers: - for kernel_var in kernel.get_variables(): - variable_name_to_replace = kernel_var.get_name() - replace_rhs_variable(expr, variable_name_to_replace=variable_name_to_replace, - kernel_var=kernel_var, spike_buf=spike_buf) - - -def is_delta_kernel(kernel): - """ - Catches definition of kernel, or reference (function call or variable name) of a delta kernel function. - """ - if type(kernel) is ASTKernel: - if not len(kernel.get_variables()) == 1: - # delta kernel not allowed if more than one variable is defined in this kernel - return False - expr = kernel.get_expressions()[0] - else: - expr = kernel - - rhs_is_delta_kernel = type(expr) is ASTSimpleExpression \ - and expr.is_function_call() \ - and expr.get_function_call().get_scope().resolve_to_symbol(expr.get_function_call().get_name(), SymbolKind.FUNCTION) == PredefinedFunctions.name2function["delta"] - rhs_is_multiplied_delta_kernel = type(expr) is ASTExpression \ - and type(expr.get_rhs()) is ASTSimpleExpression \ - and expr.get_rhs().is_function_call() \ - and expr.get_rhs().get_function_call().get_scope().resolve_to_symbol(expr.get_rhs().get_function_call().get_name(), SymbolKind.FUNCTION) == PredefinedFunctions.name2function["delta"] - return rhs_is_delta_kernel or rhs_is_multiplied_delta_kernel - - -def get_delta_kernel_prefactor_expr(kernel): - assert type(kernel) is ASTKernel - assert len(kernel.get_variables()) == 1 - expr = kernel.get_expressions()[0] - if type(expr) is ASTExpression \ - and expr.get_rhs().is_function_call() \ - and expr.get_rhs().get_function_call().get_scope().resolve_to_symbol(expr.get_rhs().get_function_call().get_name(), SymbolKind.FUNCTION) == PredefinedFunctions.name2function["delta"] \ - and expr.binary_operator.is_times_op: - return str(expr.lhs) diff --git a/pynestml/codegeneration/autodoc_codegenerator.py b/pynestml/codegeneration/autodoc_code_generator.py similarity index 50% rename from pynestml/codegeneration/autodoc_codegenerator.py rename to pynestml/codegeneration/autodoc_code_generator.py index 239dff6c4..a646c3e94 100644 --- a/pynestml/codegeneration/autodoc_codegenerator.py +++ b/pynestml/codegeneration/autodoc_code_generator.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# autodoc_codegenerator.py +# autodoc_code_generator.py # # This file is part of NEST. # @@ -19,23 +19,23 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Sequence, Union + import datetime import os -from typing import List +import textwrap from jinja2 import Environment, FileSystemLoader -from pynestml.codegeneration.codegenerator import CodeGenerator -from pynestml.codegeneration.latex_expression_printer import LatexExpressionPrinter +from pynestml.codegeneration.code_generator import CodeGenerator from pynestml.codegeneration.nest_assignments_helper import NestAssignmentsHelper -from pynestml.codegeneration.nest_declarations_helper import NestDeclarationsHelper -from pynestml.codegeneration.nest_names_converter import NestNamesConverter -from pynestml.codegeneration.nest_printer import NestPrinter -from pynestml.codegeneration.latex_reference_converter import LatexReferenceConverter +from pynestml.codegeneration.printers.latex_expression_printer import LatexExpressionPrinter +from pynestml.codegeneration.printers.latex_reference_converter import LatexReferenceConverter from pynestml.frontend.frontend_configuration import FrontendConfiguration from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.utils.ast_utils import ASTUtils -from pynestml.utils.ode_transformer import OdeTransformer +from pynestml.utils.logger import Logger class AutoDocCodeGenerator(CodeGenerator): @@ -45,22 +45,33 @@ def __init__(self): env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'resources_autodoc'))) self._template_nestml_models_index = env.get_template('nestml_models_index.jinja2') # setup the module class template - self._template_nestml_model = env.get_template('nestml_model.jinja2') + self._template_neuron_nestml_model = env.get_template('nestml_neuron_model.jinja2') + self._template_synapse_nestml_model = env.get_template('nestml_synapse_model.jinja2') - self._printer = LatexExpressionPrinter() + converter = LatexReferenceConverter() + self._printer = LatexExpressionPrinter(converter) - def generate_code(self, neurons: List[ASTNeuron]): + def generate_code(self, models: Sequence[Union[ASTNeuron, ASTSynapse]]) -> None: """ - Generate model documentation and index page for each neuron that is provided. + Generate model documentation and index page for each neuron and synapse that is provided. """ - self.generate_index(neurons) + if not os.path.isdir(FrontendConfiguration.get_target_path()): + os.makedirs(FrontendConfiguration.get_target_path()) + neurons = [model for model in models if isinstance(model, ASTNeuron)] + synapses = [model for model in models if isinstance(model, ASTSynapse)] + self.generate_index(neurons, synapses) self.generate_neurons(neurons) + self.generate_synapses(synapses) - def generate_index(self, neurons: List[ASTNeuron]): + for astnode in neurons + synapses: + if Logger.has_errors(astnode): + raise Exception("Error(s) occurred during code generation") + + def generate_index(self, neurons: Sequence[ASTNeuron], synapses: Sequence[ASTSynapse]): """ - Generate index (list) of all neuron models with links to their generated documentation. + Generate model documentation and index page for each neuron and synapse that is provided. """ - nestml_models_index = self._template_nestml_models_index.render(self.setup_index_generation_helpers(neurons)) + nestml_models_index = self._template_nestml_models_index.render(self.setup_index_generation_helpers(neurons, synapses)) with open(str(os.path.join(FrontendConfiguration.get_target_path(), 'index.rst')), 'w+') as f: f.write(str(nestml_models_index)) @@ -68,68 +79,89 @@ def generate_neuron_code(self, neuron: ASTNeuron): """ Generate model documentation for neuron model. :param neuron: a single neuron object. - :type neuron: ASTNeuron """ - if not os.path.isdir(FrontendConfiguration.get_target_path()): - os.makedirs(FrontendConfiguration.get_target_path()) - nestml_model_doc = self._template_nestml_model.render(self.setup_model_generation_helpers(neuron)) - with open(str(os.path.join(FrontendConfiguration.get_target_path(), neuron.get_name())) + '.rst', 'w+') as f: + nestml_model_doc = self._template_neuron_nestml_model.render(self.setup_neuron_model_generation_helpers(neuron)) + with open(str(os.path.join(FrontendConfiguration.get_target_path(), neuron.get_name())) + '.rst', + 'w+') as f: f.write(str(nestml_model_doc)) - def setup_model_generation_helpers(self, neuron: ASTNeuron): + def generate_synapse_code(self, synapse: ASTSynapse): + """ + Generate model documentation for synapse model. + :param synapse: a single synapse object. + """ + nestml_model_doc = self._template_synapse_nestml_model.render(self.setup_synapse_model_generation_helpers(synapse)) + with open(str(os.path.join(FrontendConfiguration.get_target_path(), synapse.get_name())) + '.rst', + 'w+') as f: + f.write(str(nestml_model_doc)) + + def setup_neuron_model_generation_helpers(self, neuron: ASTNeuron): """ Returns a namespace for Jinja2 neuron model documentation template. :param neuron: a single neuron instance - :type neuron: ASTNeuron :return: a map from name to functionality. :rtype: dict """ - converter = LatexReferenceConverter() - latex_expression_printer = LatexExpressionPrinter(converter) - namespace = dict() namespace['now'] = datetime.datetime.utcnow() namespace['neuron'] = neuron namespace['neuronName'] = str(neuron.get_name()) - namespace['printer'] = NestPrinter(latex_expression_printer) + namespace['printer'] = self._printer namespace['assignments'] = NestAssignmentsHelper() - namespace['names'] = NestNamesConverter() - namespace['declarations'] = NestDeclarationsHelper() namespace['utils'] = ASTUtils() - namespace['odeTransformer'] = OdeTransformer() import textwrap pre_comments_bak = neuron.pre_comments neuron.pre_comments = [] - namespace['neuron_source_code'] = textwrap.indent(neuron.__str__(), " ") + namespace['model_source_code'] = textwrap.indent(neuron.__str__(), " ") neuron.pre_comments = pre_comments_bak return namespace - def setup_index_generation_helpers(self, neurons: List[ASTNeuron]): + def setup_synapse_model_generation_helpers(self, synapse: ASTSynapse): + """ + Returns a namespace for Jinja2 synapse model documentation template. + + :param neuron: a single neuron instance + :return: a map from name to functionality. + :rtype: dict + """ + namespace = dict() + + namespace['now'] = datetime.datetime.utcnow() + namespace['synapse'] = synapse + namespace['synapseName'] = str(synapse.get_name()) + namespace['printer'] = self._printer + namespace['assignments'] = NestAssignmentsHelper() + namespace['utils'] = ASTUtils() + + pre_comments_bak = synapse.pre_comments + synapse.pre_comments = [] + namespace['model_source_code'] = textwrap.indent(synapse.__str__(), " ") + synapse.pre_comments = pre_comments_bak + + return namespace + + def setup_index_generation_helpers(self, neurons: Sequence[ASTNeuron], synapses: Sequence[ASTSynapse]): """ Returns a namespace for Jinja2 neuron model index page template. :param neurons: a list of neuron instances - :type neurons: List[ASTNeuron] :return: a map from name to functionality. :rtype: dict """ - converter = LatexReferenceConverter() - latex_expression_printer = LatexExpressionPrinter(converter) namespace = dict() namespace['now'] = datetime.datetime.utcnow() namespace['neurons'] = neurons + namespace['synapses'] = synapses namespace['neuronNames'] = [str(neuron.get_name()) for neuron in neurons] - namespace['printer'] = NestPrinter(latex_expression_printer) + namespace['synapseNames'] = [str(neuron.get_name()) for neuron in neurons] + namespace['printer'] = self._printer namespace['assignments'] = NestAssignmentsHelper() - namespace['names'] = NestNamesConverter() - namespace['declarations'] = NestDeclarationsHelper() namespace['utils'] = ASTUtils() - namespace['odeTransformer'] = OdeTransformer() return namespace diff --git a/pynestml/codegeneration/builder.py b/pynestml/codegeneration/builder.py new file mode 100644 index 000000000..2df31b307 --- /dev/null +++ b/pynestml/codegeneration/builder.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# +# builder.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +from typing import Any, Mapping, Optional + +from abc import ABCMeta, abstractmethod + +from pynestml.exceptions.invalid_target_exception import InvalidTargetException +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages +from pynestml.utils.with_options import WithOptions + + +class Builder(WithOptions, metaclass=ABCMeta): + r"""Compile, build and install the code for a given target platform. Runs after the CodeGenerator.""" + + def __init__(self, target, options: Optional[Mapping[str, Any]]=None): + super(Builder, self).__init__(options) + from pynestml.frontend.pynestml_frontend import get_known_targets + + if not target.upper() in get_known_targets(): + code, msg = Messages.get_unknown_target(target) + Logger.log_message(message=msg, code=code, log_level=LoggingLevel.ERROR) + self._target = "" + raise InvalidTargetException() + + self._target = target + + @abstractmethod + def build(self) -> None: + pass diff --git a/pynestml/codegeneration/code_generator.py b/pynestml/codegeneration/code_generator.py new file mode 100644 index 000000000..4eff71675 --- /dev/null +++ b/pynestml/codegeneration/code_generator.py @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- +# +# code_generator.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +import glob +from abc import abstractmethod + +from typing import Any, Dict, Mapping, List, Optional, Sequence, Union + +import os + +from jinja2 import Template, Environment, FileSystemLoader + +from pynestml.exceptions.invalid_path_exception import InvalidPathException +from pynestml.exceptions.invalid_target_exception import InvalidTargetException +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.utils.with_options import WithOptions + + +class CodeGenerator(WithOptions): + _default_options: Mapping[str, Any] = {} + _model_templates = dict() + _module_templates = list() + + def __init__(self, target, options: Optional[Mapping[str, Any]] = None): + from pynestml.frontend.pynestml_frontend import get_known_targets + + if not target.upper() in get_known_targets(): + code, msg = Messages.get_unknown_target(target) + Logger.log_message(message=msg, code=code, log_level=LoggingLevel.ERROR) + self._target = "" + raise InvalidTargetException() + + self._target = target + super(CodeGenerator, self).__init__(options) + + def setup_template_env(self): + """ + Setup the Jinja2 template environment + """ + # Get templates path + templates_root_dir = self.get_option("templates")["path"] + if not os.path.isabs(templates_root_dir): + # Prefix the default templates location + resources_dir = "resources_" + self._target.lower() + templates_root_dir = os.path.join(os.path.dirname(__file__), resources_dir, templates_root_dir) + code, message = Messages.get_template_root_path_created(templates_root_dir) + Logger.log_message(None, code, message, None, LoggingLevel.INFO) + if not os.path.isdir(templates_root_dir): + raise InvalidPathException("Templates path (" + templates_root_dir + ") is not a directory") + + # Setup neuron template environment + if "neuron" in self.get_option("templates")["model_templates"]: + neuron_model_templates = self.get_option("templates")["model_templates"]["neuron"] + if not neuron_model_templates: + raise Exception("A list of neuron model template files/directories is missing.") + self._model_templates["neuron"] = list() + self._model_templates["neuron"].extend( + self.__setup_template_env(neuron_model_templates, templates_root_dir)) + + # Setup synapse template environment + if "synapse" in self.get_option("templates")["model_templates"]: + synapse_model_templates = self.get_option("templates")["model_templates"]["synapse"] + if synapse_model_templates: + self._model_templates["synapse"] = list() + self._model_templates["synapse"].extend( + self.__setup_template_env(synapse_model_templates, templates_root_dir)) + + # Setup modules template environment + if "module_templates" in self.get_option("templates"): + module_templates = self.get_option("templates")["module_templates"] + if not module_templates: + raise Exception("A list of module template files/directories is missing.") + self._module_templates.extend(self.__setup_template_env(module_templates, templates_root_dir)) + + def __setup_template_env(self, template_files: List[str], templates_root_dir: str) -> List[Template]: + """ + A helper function to set up the jinja2 template environment + :param template_files: A list of template file names or a directory (relative to ``templates_root_dir``) + containing the templates + :param templates_root_dir: path of the root directory containing all the jinja2 templates + :return: A list of jinja2 template objects + """ + _template_files = self._get_abs_template_paths(template_files, templates_root_dir) + _template_dirs = set([os.path.dirname(_file) for _file in _template_files]) + + # Environment for neuron templates + env = Environment(loader=FileSystemLoader(_template_dirs)) + env.globals["raise"] = self.raise_helper + env.globals["is_delta_kernel"] = ASTUtils.is_delta_kernel + + # Load all the templates + _templates = list() + for _templ_file in _template_files: + _templates.append(env.get_template(os.path.basename(_templ_file))) + + return _templates + + def _get_abs_template_paths(self, template_files: List[str], templates_root_dir: str) -> List[str]: + """ + Resolve the directory paths and get the absolute paths of the jinja templates. + :param template_files: A list of template file names or a directory (relative to ``templates_root_dir``) + containing the templates + :param templates_root_dir: path of the root directory containing all the jinja2 templates + :return: A list of absolute paths of the ``template_files`` + """ + _abs_template_paths = list() + for _path in template_files: + # Convert from relative to absolute path + _path = os.path.join(templates_root_dir, _path) + if os.path.isdir(_path): + for file in glob.glob(os.path.join(_path, "*.jinja2")): + _abs_template_paths.append(os.path.join(_path, file)) + else: + _abs_template_paths.append(_path) + + return _abs_template_paths + + @abstractmethod + def generate_code(self, models: Sequence[Union[ASTNeuron, ASTSynapse]]) -> None: + """the base class CodeGenerator does not generate any code""" + pass + + def generate_neurons(self, neurons: Sequence[ASTNeuron]) -> None: + """ + Generate code for the given neurons. + + :param neurons: a list of neurons. + """ + from pynestml.frontend.frontend_configuration import FrontendConfiguration + + for neuron in neurons: + self.generate_neuron_code(neuron) + if not Logger.has_errors(neuron): + code, message = Messages.get_code_generated(neuron.get_name(), FrontendConfiguration.get_target_path()) + Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO) + + def generate_synapses(self, synapses: Sequence[ASTSynapse]) -> None: + """ + Generates code for a list of synapses. + :param synapses: a list of synapses. + """ + from pynestml.frontend.frontend_configuration import FrontendConfiguration + + for synapse in synapses: + if Logger.logging_level == LoggingLevel.INFO: + print("Generating code for the synapse {}.".format(synapse.get_name())) + self.generate_synapse_code(synapse) + code, message = Messages.get_code_generated(synapse.get_name(), FrontendConfiguration.get_target_path()) + Logger.log_message(synapse, code, message, synapse.get_source_position(), LoggingLevel.INFO) + + def generate_model_code(self, + model_name: str, + model_templates: List[Template], + template_namespace: Dict[str, Any], + model_name_escape_string: str = "@MODEL_NAME@") -> None: + """ + For a handed over model, this method generates the corresponding header and implementation file. + :param model_name: name of the neuron or synapse model + :param model_templates: list of neuron or synapse model templates + :param template_namespace: namespace for the template + :param model_name_escape_string: escape string where the model name is replaced + """ + if not os.path.isdir(FrontendConfiguration.get_target_path()): + os.makedirs(FrontendConfiguration.get_target_path()) + + for _model_templ in model_templates: + if not len(_model_templ.filename.split("/")[-1].split(".")) == 3: + raise Exception("Template file name should be of the form: " + "\"PREFIX@NEURON_NAME@SUFFIX.FILE_EXTENSION.jinja2\"") + templ_file_name = os.path.basename(_model_templ.filename) + if not len(templ_file_name.split(".")) == 3: + raise Exception("Template file name \"" + templ_file_name + "\" should be of the form \"PREFIX@NEURON_NAME@SUFFIX.FILE_EXTENSION.jinja2\"") + templ_file_name = templ_file_name.split(".")[0] # for example, "cm_main_@NEURON_NAME@" + templ_file_name = templ_file_name.replace(model_name_escape_string, model_name) + file_extension = _model_templ.filename.split(".")[-2] # for example, "cpp" + rendered_templ_file_name = os.path.join(FrontendConfiguration.get_target_path(), + templ_file_name + "." + file_extension) + _file = _model_templ.render(template_namespace) + Logger.log_message(message="Rendering template " + rendered_templ_file_name, + log_level=LoggingLevel.INFO) + with open(rendered_templ_file_name, "w+") as f: + f.write(str(_file)) + + def generate_neuron_code(self, neuron: ASTNeuron) -> None: + self.generate_model_code(neuron.get_name(), + model_templates=self._model_templates["neuron"], + template_namespace=self._get_neuron_model_namespace(neuron), + model_name_escape_string="@NEURON_NAME@") + + def generate_synapse_code(self, synapse: ASTNeuron) -> None: + self.generate_model_code(synapse.get_name(), + model_templates=self._model_templates["synapse"], + template_namespace=self._get_synapse_model_namespace(synapse), + model_name_escape_string="@SYNAPSE_NAME@") + + def generate_module_code(self, neurons: Sequence[ASTNeuron], synapses: Sequence[ASTSynapse]) -> None: + self.generate_model_code(FrontendConfiguration.get_module_name(), + model_templates=self._module_templates, + template_namespace=self._get_module_namespace(neurons, synapses), + model_name_escape_string="@MODULE_NAME@") + code, message = Messages.get_module_generated(FrontendConfiguration.get_target_path()) + Logger.log_message(None, code, message, None, LoggingLevel.INFO) diff --git a/pynestml/codegeneration/codegenerator.py b/pynestml/codegeneration/codegenerator.py deleted file mode 100644 index 6a8400026..000000000 --- a/pynestml/codegeneration/codegenerator.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -# -# codegenerator.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -from typing import List - -from pynestml.exceptions.invalid_target_exception import InvalidTargetException -from pynestml.meta_model.ast_node import ASTNode -from pynestml.utils.logger import Logger -from pynestml.utils.logger import LoggingLevel -from pynestml.utils.messages import Messages - - -class CodeGenerator(): - - def __init__(self, target): - if not target.upper() in self.get_known_targets(): - code, msg = Messages.get_unknown_target(target) - Logger.log_message(message=msg, code=code, log_level=LoggingLevel.ERROR) - self._target = "" - raise InvalidTargetException() - - self._target = target - - @staticmethod - def get_known_targets(): - targets = ["NEST", "autodoc", ""] # include the empty string here to represent "no code generated" - targets = [s.upper() for s in targets] - return targets - - def generate_neurons(self, neurons: List[ASTNode]): - """ - Generate code for the given neurons. - - :param neurons: a list of neurons. - :type neurons: List[ASTNode] - """ - from pynestml.frontend.frontend_configuration import FrontendConfiguration - - for neuron in neurons: - self.generate_neuron_code(neuron) - if not Logger.has_errors(neuron): - code, message = Messages.get_code_generated(neuron.get_name(), FrontendConfiguration.get_target_path()) - Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO) - - def generate_code(self, neurons): - """ - Generate code for the given neurons and (depending on the target) generate an index page, module entrypoint or - similar that incorporates an enumeration of all neurons. - - :param neurons: a list of neurons. - :type neurons: List[ASTNode] - """ - if self._target.upper() == "NEST": - from pynestml.codegeneration.nest_codegenerator import NESTCodeGenerator - _codeGenerator = NESTCodeGenerator() - _codeGenerator.generate_code(neurons) - elif self._target.upper() == "AUTODOC": - from pynestml.codegeneration.autodoc_codegenerator import AutoDocCodeGenerator - _codeGenerator = AutoDocCodeGenerator() - _codeGenerator.generate_code(neurons) - else: - # dummy/null target: user requested to not generate any code - assert self._target == "" - code, message = Messages.get_no_code_generated() - Logger.log_message(None, code, message, None, LoggingLevel.INFO) diff --git a/pynestml/codegeneration/expressions_pretty_printer.py b/pynestml/codegeneration/expressions_pretty_printer.py deleted file mode 100644 index e8e2453ee..000000000 --- a/pynestml/codegeneration/expressions_pretty_printer.py +++ /dev/null @@ -1,169 +0,0 @@ -# -*- coding: utf-8 -*- -# -# expressions_pretty_printer.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -from pynestml.codegeneration.i_reference_converter import IReferenceConverter -from pynestml.codegeneration.nestml_reference_converter import NestMLReferenceConverter -from pynestml.meta_model.ast_expression import ASTExpression -from pynestml.meta_model.ast_expression_node import ASTExpressionNode -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.utils.ast_utils import ASTUtils - - -class ExpressionsPrettyPrinter(object): - """ - Converts expressions to the executable platform dependent code. By using different - referenceConverters for the handling of variables, names, and functions can be adapted. For this, - implement own IReferenceConverter specialisation. - This class is used to transform only parts of the procedural language and not nestml in whole. - """ - - def __init__(self, reference_converter=None, types_printer=None): - # type: (IReferenceConverter,TypesPrinter) -> None - # todo by kp: this should expect a ITypesPrinter as the second arg - if reference_converter is not None: - self.reference_converter = reference_converter - else: - self.reference_converter = NestMLReferenceConverter() - - if types_printer is not None: - self.types_printer = types_printer - else: - self.types_printer = TypesPrinter() - - def print_expression(self, node, prefix=''): - """Print an expression. - - Parameters - ---------- - node : ASTExpressionNode - The expression node to print. - prefix : str - *See documentation for the function print_function_call().* - - Returns - ------- - s : str - The expression string. - """ - if (node.get_implicit_conversion_factor() is not None) \ - and (not node.get_implicit_conversion_factor() == 1): - return str(node.get_implicit_conversion_factor()) + ' * (' + self.__do_print(node, prefix=prefix) + ')' - else: - return self.__do_print(node, prefix=prefix) - - def __do_print(self, node, prefix=''): - # type: (ASTExpressionNode) -> str - if isinstance(node, ASTSimpleExpression): - if node.has_unit(): - # todo by kp: this should not be done in the typesPrinter, obsolete - return self.types_printer.pretty_print(node.get_numeric_literal()) + '*' + \ - self.reference_converter.convert_name_reference(node.get_variable(), prefix=prefix) - elif node.is_numeric_literal(): - return str(node.get_numeric_literal()) - elif node.is_inf_literal: - return self.reference_converter.convert_constant('inf') - elif node.is_string(): - return self.types_printer.pretty_print(node.get_string()) - elif node.is_boolean_true: - return self.types_printer.pretty_print(True) - elif node.is_boolean_false: - return self.types_printer.pretty_print(False) - elif node.is_variable(): - return self.reference_converter.convert_name_reference(node.get_variable(), prefix=prefix) - elif node.is_function_call(): - return self.print_function_call(node.get_function_call(), prefix=prefix) - elif isinstance(node, ASTExpression): - # a unary operator - if node.is_unary_operator(): - op = self.reference_converter.convert_unary_op(node.get_unary_operator()) - rhs = self.print_expression(node.get_expression(), prefix=prefix) - return op % rhs - # encapsulated in brackets - elif node.is_encapsulated: - return self.reference_converter.convert_encapsulated() % self.print_expression(node.get_expression(), prefix=prefix) - # logical not - elif node.is_logical_not: - op = self.reference_converter.convert_logical_not() - rhs = self.print_expression(node.get_expression(), prefix=prefix) - return op % rhs - # compound rhs with lhs + rhs - elif node.is_compound_expression(): - lhs = self.print_expression(node.get_lhs(), prefix=prefix) - op = self.reference_converter.convert_binary_op(node.get_binary_operator()) - rhs = self.print_expression(node.get_rhs(), prefix=prefix) - return op % (lhs, rhs) - elif node.is_ternary_operator(): - condition = self.print_expression(node.get_condition(), prefix=prefix) - if_true = self.print_expression(node.get_if_true(), prefix=prefix) - if_not = self.print_expression(node.if_not, prefix=prefix) - return self.reference_converter.convert_ternary_operator() % (condition, if_true, if_not) - else: - raise RuntimeError('Unsupported rhs in rhs pretty printer (%s)!' % str(node)) - - def print_function_call(self, function_call, prefix=''): - """Print a function call, including bracketed arguments list. - - Parameters - ---------- - node : ASTFunctionCall - The function call node to print. - prefix : str - Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". - - Predefined functions will not be prefixed. - - Returns - ------- - s : str - The function call string. - """ - function_name = self.reference_converter.convert_function_call(function_call, prefix=prefix) - if ASTUtils.needs_arguments(function_call): - return function_name.format(*self.print_function_call_argument_list(function_call, prefix=prefix)) - else: - return function_name - - def print_function_call_argument_list(self, function_call, prefix=''): - # type: (ASTFunctionCall) -> tuple of str - ret = [] - - for arg in function_call.get_args(): - ret.append(self.print_expression(arg, prefix=prefix)) - - return tuple(ret) - - -class TypesPrinter(object): - """ - Returns a processable format of the handed over element. - """ - - @classmethod - def pretty_print(cls, element): - assert (element is not None), \ - '(PyNestML.CodeGeneration.PrettyPrinter) No element provided (%s)!' % element - if isinstance(element, bool) and element: - return 'true' - elif isinstance(element, bool) and not element: - return 'false' - elif isinstance(element, int) or isinstance(element, float): - return str(element) diff --git a/pynestml/codegeneration/gsl_names_converter.py b/pynestml/codegeneration/gsl_names_converter.py deleted file mode 100644 index 346106dd2..000000000 --- a/pynestml/codegeneration/gsl_names_converter.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# -# gsl_names_converter.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -from pynestml.codegeneration.nest_names_converter import NestNamesConverter -from pynestml.symbols.variable_symbol import VariableSymbol - - -class GSLNamesConverter(object): - """ - A GSL names converter as use to transform names to GNU Scientific Library. - """ - - @classmethod - def array_index(cls, symbol): - """ - Transforms the haded over symbol to a GSL processable format. - :param symbol: a single variable symbol - :type symbol: VariableSymbol - :return: the corresponding string format - :rtype: str - """ - return 'State_::' + NestNamesConverter.convert_to_cpp_name(symbol.get_symbol_name()) - - @classmethod - def name(cls, symbol): - """ - Transforms the given symbol to a format that can be processed by GSL. - :param symbol: a single variable symbol - :type symbol: VariableSymbol - :return: the corresponding string format - :rtype: str - """ - if symbol.is_init_values() and not symbol.is_function: - return 'ode_state[State_::' + NestNamesConverter.convert_to_cpp_name(symbol.get_symbol_name()) + ']' - else: - return NestNamesConverter.name(symbol) - - @classmethod - def getter(cls, variable_symbol): - """ - Converts for a handed over symbol the corresponding name of the getter to a gsl processable format. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding representation as a string - :rtype: str - """ - return NestNamesConverter.getter(variable_symbol) - - @classmethod - def setter(cls, variable_symbol): - """ - Converts for a handed over symbol the corresponding name of the setter to a gsl processable format. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding representation as a string - :rtype: str - """ - return NestNamesConverter.setter(variable_symbol) - - @classmethod - def buffer_value(cls, variable_symbol): - """ - Converts for a handed over symbol the corresponding name of the buffer to a gsl processable format. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding representation as a string - :rtype: str - """ - return NestNamesConverter.buffer_value(variable_symbol) - - @classmethod - def convert_to_cpp_name(cls, variable_name): - """ - Converts a handed over name to the corresponding gsl / c++ naming guideline. - In concrete terms: - Converts names of the form g_in'' to a compilable C++ identifier: __DDX_g_in - :param variable_name: a single name. - :type variable_name: str - :return: the corresponding transformed name. - :rtype: str - """ - return NestNamesConverter.convert_to_cpp_name(variable_name) diff --git a/pynestml/codegeneration/gsl_reference_converter.py b/pynestml/codegeneration/gsl_reference_converter.py deleted file mode 100644 index 5408c6ae1..000000000 --- a/pynestml/codegeneration/gsl_reference_converter.py +++ /dev/null @@ -1,244 +0,0 @@ -# -*- coding: utf-8 -*- -# -# gsl_reference_converter.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -from pynestml.codegeneration.gsl_names_converter import GSLNamesConverter -from pynestml.codegeneration.i_reference_converter import IReferenceConverter -from pynestml.codegeneration.nest_names_converter import NestNamesConverter -from pynestml.codegeneration.nest_reference_converter import NESTReferenceConverter -from pynestml.codegeneration.unit_converter import UnitConverter -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.predefined_variables import PredefinedVariables -from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.unit_type_symbol import UnitTypeSymbol -from pynestml.utils.ast_utils import ASTUtils -from pynestml.utils.logger import Logger, LoggingLevel -from pynestml.utils.messages import Messages - - -class GSLReferenceConverter(IReferenceConverter): - """ - This class is used to convert operators and constant to the GSL (GNU Scientific Library) processable format. - """ - maximal_exponent = 10.0 - - def __init__(self, is_upper_bound=False): - """ - Standard constructor. - :param is_upper_bound: Indicates whether an upper bound for the exponent shall be used. - :type is_upper_bound: bool - """ - self.is_upper_bound = is_upper_bound - - def convert_name_reference(self, ast_variable: ASTVariable, prefix: str = ''): - """ - Converts a single name reference to a gsl processable format. - :param ast_variable: a single variable - :type ast_variable: ASTVariable - :return: a gsl processable format of the variable - :rtype: str - """ - variable_name = NestNamesConverter.convert_to_cpp_name(ast_variable.get_name()) - - if variable_name == PredefinedVariables.E_CONSTANT: - return 'numerics::e' - - symbol = ast_variable.get_scope().resolve_to_symbol(ast_variable.get_complete_name(), SymbolKind.VARIABLE) - if symbol is None: - # test if variable name can be resolved to a type - if PredefinedUnits.is_unit(ast_variable.get_complete_name()): - return str(UnitConverter.get_factor(PredefinedUnits.get_unit(ast_variable.get_complete_name()).get_unit())) - - code, message = Messages.get_could_not_resolve(variable_name) - Logger.log_message(log_level=LoggingLevel.ERROR, code=code, message=message, - error_position=ast_variable.get_source_position()) - return '' - - if symbol.is_init_values(): - return GSLNamesConverter.name(symbol) - - if symbol.is_buffer(): - if isinstance(symbol.get_type_symbol(), UnitTypeSymbol): - units_conversion_factor = UnitConverter.get_factor(symbol.get_type_symbol().unit.unit) - else: - units_conversion_factor = 1 - s = "" - if not units_conversion_factor == 1: - s += "(" + str(units_conversion_factor) + " * " - s += prefix + 'B_.' + NestNamesConverter.buffer_value(symbol) - if symbol.has_vector_parameter(): - s += '[i]' - if not units_conversion_factor == 1: - s += ")" - return s - - if symbol.is_local() or symbol.is_function: - return variable_name - - if symbol.has_vector_parameter(): - return prefix + 'get_' + variable_name + '()[i]' - - return prefix + 'get_' + variable_name + '()' - - def convert_function_call(self, function_call, prefix=''): - """Convert a single function call to C++ GSL API syntax. - - Parameters - ---------- - function_call : ASTFunctionCall - The function call node to convert. - prefix : str - Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". - - Predefined functions will not be prefixed. - - Returns - ------- - s : str - The function call string in C++ syntax. - """ - function_name = function_call.get_name() - - if function_name == PredefinedFunctions.TIME_RESOLUTION: - return 'nest::Time::get_resolution().get_ms()' - - if function_name == PredefinedFunctions.TIME_STEPS: - return 'nest::Time(nest::Time::ms((double) {!s})).get_steps()' - - if function_name == PredefinedFunctions.MAX: - return 'std::max({!s}, {!s})' - - if function_name == PredefinedFunctions.MIN: - return 'std::min({!s}, {!s})' - - if function_name == PredefinedFunctions.CLIP: - # warning: the arguments of this function have been swapped and - # are therefore [v_max, v_min, v], hence its structure - return 'std::min({2!s}, std::max({1!s}, {0!s}))' - - if function_name == PredefinedFunctions.EXP: - if self.is_upper_bound: - return 'std::exp(std::min({!s},' + str(self.maximal_exponent) + '))' - else: - return 'std::exp({!s})' - - if function_name == PredefinedFunctions.COSH: - if self.is_upper_bound: - return 'std::cosh(std::min(std::abs({!s}),' + str(self.maximal_exponent) + '))' - else: - return 'std::cosh({!s})' - - if function_name == PredefinedFunctions.SINH: - if self.is_upper_bound: - return 'std::sinh(({!s} > 0 ? 1 : -1)*std::min(std::abs({!s}),' + str(self.maximal_exponent) + '))' - else: - return 'std::sinh({!s})' - - if function_name == PredefinedFunctions.TANH: - return 'std::tanh({!s})' - - if function_name == PredefinedFunctions.LN: - return 'std::log({!s})' - - if function_name == PredefinedFunctions.LOG10: - return 'std::log10({!s})' - - if function_name == PredefinedFunctions.EXPM1: - return 'numerics::expm1({!s})' - - if function_name == PredefinedFunctions.RANDOM_NORMAL: - return '(({!s}) + ({!s}) * ' + prefix + 'normal_dev_( nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() ) ))' - - if function_name == PredefinedFunctions.RANDOM_UNIFORM: - return '(({!s}) + ({!s}) * nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() )->drand())' - - if function_name == PredefinedFunctions.EMIT_SPIKE: - return 'set_spiketime(nest::Time::step(origin.get_steps()+lag+1));\n' \ - 'nest::SpikeEvent se;\n' \ - 'nest::kernel().event_delivery_manager.send(*this, se, lag)' - - # suppress prefix for misc. predefined functions - # check if function is "predefined" purely based on the name, as we don't have access to the function symbol here - function_is_predefined = PredefinedFunctions.get_function(function_name) - if function_is_predefined: - prefix = '' - - if ASTUtils.needs_arguments(function_call): - n_args = len(function_call.get_args()) - return prefix + function_name + '(' + ', '.join(['{!s}' for _ in range(n_args)]) + ')' - - return prefix + function_name + '()' - - def convert_constant(self, constant_name): - """ - No modifications to the constant required. - :param constant_name: a single constant. - :type constant_name: str - :return: the same constant - :rtype: str - """ - return constant_name - - def convert_unary_op(self, unary_operator): - """ - No modifications to the operator required. - :param unary_operator: a string of a unary operator. - :type unary_operator: str - :return: the same operator - :rtype: str - """ - return str(unary_operator) + '(%s)' - - def convert_binary_op(self, binary_operator): - """ - Converts a singe binary operator. Here, we have only to regard the pow operator in a special manner. - :param binary_operator: a binary operator in string representation. - :type binary_operator: str - :return: a string representing the included binary operator. - :rtype: str - """ - from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator - if isinstance(binary_operator, ASTArithmeticOperator) and binary_operator.is_pow_op: - return 'pow(%s, %s)' - else: - return '%s' + str(binary_operator) + '%s' - - def convert_logical_not(self): - return NESTReferenceConverter.convert_logical_not() - - def convert_logical_operator(self, op): - return NESTReferenceConverter.convert_logical_operator(op) - - def convert_comparison_operator(self, op): - return NESTReferenceConverter.convert_comparison_operator(op) - - def convert_bit_operator(self, op): - return NESTReferenceConverter.convert_bit_operator(op) - - def convert_encapsulated(self): - return NESTReferenceConverter.convert_encapsulated() - - def convert_ternary_operator(self): - return NESTReferenceConverter.convert_ternary_operator() - - def convert_arithmetic_operator(self, op): - return NESTReferenceConverter.convert_arithmetic_operator(op) diff --git a/pynestml/codegeneration/nest_assignments_helper.py b/pynestml/codegeneration/nest_assignments_helper.py index 42987d194..4aa4b592f 100644 --- a/pynestml/codegeneration/nest_assignments_helper.py +++ b/pynestml/codegeneration/nest_assignments_helper.py @@ -18,24 +18,26 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Optional + from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import VariableSymbol from pynestml.utils.logger import LoggingLevel, Logger -class NestAssignmentsHelper(object): +class NestAssignmentsHelper: """ This class contains several helper functions as used during printing of code. """ @classmethod - def lhs_variable(cls, assignment): + def lhs_variable(cls, assignment: ASTAssignment) -> Optional[VariableSymbol]: """ Returns the corresponding symbol of the assignment. :param assignment: a single assignment. - :type assignment: ASTAssignment. :return: a single variable symbol - :rtype: variable_symbol """ assert isinstance(assignment, ASTAssignment), \ '(PyNestML.CodeGeneration.Assignments) No or wrong type of assignment provided (%s)!' % type(assignment) @@ -43,9 +45,26 @@ def lhs_variable(cls, assignment): SymbolKind.VARIABLE) if symbol is not None: return symbol - else: - Logger.log_message(message='No symbol could be resolved!', log_level=LoggingLevel.ERROR) - return + + Logger.log_message(message='No symbol could be resolved!', log_level=LoggingLevel.ERROR) + return None + + @classmethod + def lhs_vector_variable(cls, assignment: ASTAssignment) -> VariableSymbol: + """ + Returns the corresponding symbol of the assignment. + :param assignment: a single assignment. + :return: a single variable symbol + """ + assert isinstance(assignment, ASTAssignment), \ + '(PyNestML.CodeGeneration.Assignments) No or wrong type of assignment provided (%s)!' % type(assignment) + symbol = assignment.get_scope().resolve_to_symbol(assignment.get_variable().get_vector_parameter(), + SymbolKind.VARIABLE) + if symbol is not None: + return symbol + + Logger.log_message(message='No symbol could be resolved!', log_level=LoggingLevel.WARNING) + return None @classmethod def print_assignments_operation(cls, assignment): diff --git a/pynestml/codegeneration/nest_builder.py b/pynestml/codegeneration/nest_builder.py new file mode 100644 index 000000000..abdfa5155 --- /dev/null +++ b/pynestml/codegeneration/nest_builder.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# +# nest_builder.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +from typing import Any, Mapping, Optional, Sequence, Union + +import os +import platform +import subprocess +import sys + +from pynestml.codegeneration.builder import Builder +from pynestml.exceptions.generated_code_build_exception import GeneratedCodeBuildException +from pynestml.exceptions.invalid_path_exception import InvalidPathException +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel + + +def __add_library_to_sli(lib_path): + if not os.path.isabs(lib_path): + lib_path = os.path.abspath(lib_path) + + system = platform.system() + lib_key = "" + + if system == "Linux": + lib_key = "LD_LIBRARY_PATH" + else: + lib_key = "DYLD_LIBRARY_PATH" + + if lib_key in os.environ: + current = os.environ[lib_key].split(os.pathsep) + if lib_path not in current: + current.append(lib_path) + os.environ[lib_key] += os.pathsep.join(current) + else: + os.environ[lib_key] = lib_path + + +def add_libraries_to_sli(paths: Union[str, Sequence[str]]): + ''' + This method can be used to add external modules to SLI environment + + Parameters + ---------- + paths + paths to external nest modules + ''' + if isinstance(paths, str): + paths = [paths] + for path in paths: + __add_library_to_sli(path) + + +class NESTBuilder(Builder): + r"""Compile, build and install the NEST C++ code and NEST extension module.""" + + _default_options = { + "nest_path": None + } + + def __init__(self, options: Optional[Mapping[str, Any]] = None): + super().__init__("NEST", options) + + # auto-detect NEST Simulator install path + if not self.option_exists("nest_path") or not self.get_option("nest_path"): + try: + import nest + except ModuleNotFoundError: + Logger.log_message(None, -1, "An error occurred while importing the `nest` module in Python. Please check your NEST installation-related environment variables and paths, or specify ``nest_path`` manually in the code generator options.", None, LoggingLevel.ERROR) + sys.exit(1) + + nest_path = nest.ll_api.sli_func("statusdict/prefix ::") + self.set_options({"nest_path": nest_path}) + Logger.log_message(None, -1, "The NEST Simulator installation path was automatically detected as: " + nest_path, None, LoggingLevel.INFO) + + def build(self) -> None: + r""" + This method can be used to build the generated code and install the resulting extension module into NEST. + + Raises + ------ + GeneratedCodeBuildException + If any kind of failure occurs during cmake configuration, build, or install. + InvalidPathException + If a failure occurs while trying to access the target path or the NEST installation path. + """ + cmake_cmd = ["cmake"] + target_path = FrontendConfiguration.get_target_path() + install_path = FrontendConfiguration.get_install_path() + if install_path is not None: + add_libraries_to_sli(install_path) + nest_path = self.get_option("nest_path") + + if not os.path.isdir(target_path): + raise InvalidPathException('Target path (' + target_path + ') is not a directory!') + + if nest_path is None or (not os.path.isdir(nest_path)): + raise InvalidPathException('NEST path (' + str(nest_path) + ') is not a directory!') + + install_prefix = "" + if install_path: + if not os.path.isabs(install_path): + install_path = os.path.abspath(install_path) + install_prefix = f"-DCMAKE_INSTALL_PREFIX={install_path}" + + nest_config_path = f"-Dwith-nest={os.path.join(nest_path, 'bin', 'nest-config')}" + cmake_cmd = ['cmake', nest_config_path, install_prefix, '.'] + make_all_cmd = ['make', 'all'] + make_install_cmd = ['make', 'install'] + + # remove CMakeCache.txt if exists + cmake_cache = os.path.join(target_path, "CMakeCache.txt") + if os.path.exists(cmake_cache): + os.remove(cmake_cache) + + # check if we run on win + if sys.platform.startswith('win'): + shell = True + else: + shell = False + + # first call cmake with all the arguments + try: + subprocess.check_call(cmake_cmd, stderr=subprocess.STDOUT, shell=shell, + cwd=str(os.path.join(target_path))) + except subprocess.CalledProcessError as e: + raise GeneratedCodeBuildException('Error occurred during \'cmake\'! More detailed error messages can be found in stdout.') + + # now execute make all + try: + subprocess.check_call(make_all_cmd, stderr=subprocess.STDOUT, shell=shell, + cwd=str(os.path.join(target_path))) + except subprocess.CalledProcessError as e: + raise GeneratedCodeBuildException('Error occurred during \'make all\'! More detailed error messages can be found in stdout.') + + # finally execute make install + try: + subprocess.check_call(make_install_cmd, stderr=subprocess.STDOUT, shell=shell, + cwd=str(os.path.join(target_path))) + except subprocess.CalledProcessError as e: + raise GeneratedCodeBuildException('Error occurred during \'make install\'! More detailed error messages can be found in stdout.') diff --git a/pynestml/codegeneration/nest_code_generator.py b/pynestml/codegeneration/nest_code_generator.py new file mode 100644 index 000000000..811fa91fc --- /dev/null +++ b/pynestml/codegeneration/nest_code_generator.py @@ -0,0 +1,806 @@ +# -*- coding: utf-8 -*- +# +# nest_code_generator.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple, Union + +import datetime + +from jinja2 import TemplateRuntimeError + +import odetoolbox + +import pynestml +from pynestml.codegeneration.code_generator import CodeGenerator +from pynestml.codegeneration.nest_assignments_helper import NestAssignmentsHelper +from pynestml.codegeneration.nest_declarations_helper import NestDeclarationsHelper +from pynestml.codegeneration.printers.cpp_types_printer import CppTypesPrinter +from pynestml.codegeneration.printers.cpp_expression_printer import CppExpressionPrinter +from pynestml.codegeneration.printers.gsl_reference_converter import GSLReferenceConverter +from pynestml.codegeneration.printers.unitless_expression_printer import UnitlessExpressionPrinter +from pynestml.codegeneration.printers.nest_printer import NestPrinter +from pynestml.codegeneration.printers.nest_reference_converter import NESTReferenceConverter +from pynestml.codegeneration.printers.ode_toolbox_reference_converter import ODEToolboxReferenceConverter +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_assignment import ASTAssignment +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.meta_model.ast_input_port import ASTInputPort +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_kernel import ASTKernel +from pynestml.meta_model.ast_ode_equation import ASTOdeEquation +from pynestml.meta_model.ast_synapse import ASTSynapse +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.real_type_symbol import RealTypeSymbol +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_equations_with_delay_vars_visitor import ASTEquationsWithDelayVarsVisitor +from pynestml.visitors.ast_mark_delay_vars_visitor import ASTMarkDelayVarsVisitor +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor +from pynestml.visitors.ast_random_number_generator_visitor import ASTRandomNumberGeneratorVisitor + + +def find_spiking_post_port(synapse, namespace): + if "paired_neuron" in dir(synapse): + for post_port_name in namespace["post_ports"]: + if synapse.get_input_blocks() \ + and synapse.get_input_blocks().get_input_ports() \ + and ASTUtils.get_input_port_by_name(synapse.get_input_blocks(), post_port_name).is_spike(): + return post_port_name + return None + + +class NESTCodeGenerator(CodeGenerator): + r""" + Code generator for a NEST Simulator (versions 3.x.x or higher) C++ extension module. + + Options: + - **neuron_parent_class**: The C++ class from which the generated NESTML neuron class inherits. Examples: ``"ArchivingNode"``, ``"StructuralPlasticityNode"``. Default: ``"ArchivingNode"``. + - **neuron_parent_class_include**: The C++ header filename to include that contains **neuron_parent_class**. Default: ``"archiving_node.h"``. + - **neuron_synapse_pairs**: List of pairs of (neuron, synapse) model names. + - **preserve_expressions**: Set to True, or a list of strings corresponding to individual variable names, to disable internal rewriting of expressions, and return same output as input expression where possible. Only applies to variables specified as first-order differential equations. (This parameter is passed to ODE-toolbox.) + - **simplify_expression**: For all expressions ``expr`` that are rewritten by ODE-toolbox: the contents of this parameter string are ``eval()``ed in Python to obtain the final output expression. Override for custom expression simplification steps. Example: ``sympy.simplify(expr)``. Default: ``"sympy.logcombine(sympy.powsimp(sympy.expand(expr)))"``. (This parameter is passed to ODE-toolbox.) + - **templates**: Path containing jinja templates used to generate code for NEST simulator. + - **path**: Path containing jinja templates used to generate code for NEST simulator. + - **model_templates**: A list of the jinja templates or a relative path to a directory containing the neuron and synapse model templates. + - **neuron**: A list of neuron model jinja templates. + - **synapse**: A list of synapse model jinja templates. + - **module_templates**: A list of the jinja templates or a relative path to a directory containing the templates related to generating the NEST module. + - **nest_version**: A string identifying the version of NEST Simulator to generate code for. The string corresponds to the NEST Simulator git repository tag or git branch name, for instance, ``"v2.20.2"`` or ``"master"``. The default is the empty string, which causes the NEST version to be automatically identified from the ``nest`` Python module. + """ + + _default_options = { + "neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h", + "neuron_synapse_pairs": [], + "preserve_expressions": False, + "simplify_expression": "sympy.logcombine(sympy.powsimp(sympy.expand(expr)))", + "templates": { + "path": "point_neuron", + "model_templates": { + "neuron": ["@NEURON_NAME@.cpp.jinja2", "@NEURON_NAME@.h.jinja2"], + "synapse": ["@SYNAPSE_NAME@.h.jinja2"] + }, + "module_templates": ["setup"] + }, + "nest_version": "" + } + + def __init__(self, options: Optional[Mapping[str, Any]] = None): + super().__init__("NEST", options) + + # auto-detect NEST Simulator installed version + if not self.option_exists("nest_version") or not self.get_option("nest_version"): + from pynestml.codegeneration.nest_tools import NESTTools + nest_version = NESTTools.detect_nest_version() + self.set_options({"nest_version": nest_version}) + + # insist on using the old Archiving_Node class for NEST 2 + if self.get_option("nest_version").startswith("v2"): + self.set_options({"neuron_parent_class": "Archiving_Node", + "neuron_parent_class_include": "archiving_node.h"}) + + self.analytic_solver = {} + self.numeric_solver = {} + self.non_equations_state_variables = {} # those state variables not defined as an ODE in the equations block + + self.setup_template_env() + + self._types_printer = CppTypesPrinter() + + if self.get_option("nest_version").startswith("2") or self.get_option("nest_version").startswith("v2"): + from pynestml.codegeneration.printers.nest2_gsl_reference_converter import NEST2GSLReferenceConverter + from pynestml.codegeneration.printers.nest2_reference_converter import NEST2ReferenceConverter + self._gsl_reference_converter = NEST2GSLReferenceConverter() + self._nest_reference_converter = NEST2ReferenceConverter() + self._nest_reference_converter_no_origin = NEST2ReferenceConverter() + self._nest_reference_converter_no_origin.with_origin = False + else: + self._gsl_reference_converter = GSLReferenceConverter() + self._nest_reference_converter = NESTReferenceConverter() + self._nest_reference_converter_no_origin = NESTReferenceConverter() + self._nest_reference_converter_no_origin.with_origin = False + + self._printer = CppExpressionPrinter(self._nest_reference_converter) + self._unitless_expression_printer = UnitlessExpressionPrinter(self._nest_reference_converter) + self._unitless_expression_printer_no_origin = UnitlessExpressionPrinter(self._nest_reference_converter_no_origin) + self._gsl_printer = UnitlessExpressionPrinter(reference_converter=self._gsl_reference_converter) + + self._nest_printer = NestPrinter(reference_converter=self._nest_reference_converter, + types_printer=self._types_printer, + expression_printer=self._printer) + + self._unitless_nest_gsl_printer = NestPrinter(reference_converter=self._nest_reference_converter, + types_printer=self._types_printer, + expression_printer=self._unitless_expression_printer) + + self._ode_toolbox_printer = UnitlessExpressionPrinter(ODEToolboxReferenceConverter()) + + def raise_helper(self, msg): + raise TemplateRuntimeError(msg) + + def set_options(self, options: Mapping[str, Any]) -> Mapping[str, Any]: + # insist on using the old Archiving_Node class for NEST 2 + if self.get_option("nest_version").startswith("v2"): + Logger.log_message(None, -1, "Overriding parent class for NEST 2 compatibility", None, LoggingLevel.WARNING) + options["neuron_parent_class"] = "Archiving_Node" + options["neuron_parent_class_include"] = "archiving_node.h" + + ret = super().set_options(options) + self.setup_template_env() + + return ret + + def generate_code(self, models: Sequence[Union[ASTNeuron, ASTSynapse]]) -> None: + neurons = [model for model in models if isinstance(model, ASTNeuron)] + synapses = [model for model in models if isinstance(model, ASTSynapse)] + self.analyse_transform_neurons(neurons) + self.analyse_transform_synapses(synapses) + self.generate_neurons(neurons) + self.generate_synapses(synapses) + self.generate_module_code(neurons, synapses) + + for astnode in neurons + synapses: + if Logger.has_errors(astnode): + raise Exception("Error(s) occurred during code generation") + + def _get_module_namespace(self, neurons: List[ASTNeuron], synapses: List[ASTSynapse]) -> Dict: + """ + Creates a namespace for generating NEST extension module code + :param neurons: List of neurons + :return: a context dictionary for rendering templates + """ + namespace = {"neurons": neurons, + "synapses": synapses, + "moduleName": FrontendConfiguration.get_module_name(), + "now": datetime.datetime.utcnow()} + return namespace + + def analyse_transform_neurons(self, neurons: List[ASTNeuron]) -> None: + """ + Analyse and transform a list of neurons. + :param neurons: a list of neurons. + """ + for neuron in neurons: + code, message = Messages.get_analysing_transforming_neuron(neuron.get_name()) + Logger.log_message(None, code, message, None, LoggingLevel.INFO) + spike_updates, post_spike_updates, equations_with_delay_vars = self.analyse_neuron(neuron) + neuron.spike_updates = spike_updates + neuron.post_spike_updates = post_spike_updates + neuron.equations_with_delay_vars = equations_with_delay_vars + + def analyse_transform_synapses(self, synapses: List[ASTSynapse]) -> None: + """ + Analyse and transform a list of synapses. + :param synapses: a list of synapses. + """ + for synapse in synapses: + Logger.log_message(None, None, "Analysing/transforming synapse {}.".format(synapse.get_name()), None, LoggingLevel.INFO) + spike_updates = self.analyse_synapse(synapse) + synapse.spike_updates = spike_updates + + def analyse_neuron(self, neuron: ASTNeuron) -> Tuple[Dict[str, ASTAssignment], Dict[str, ASTAssignment], + List[ASTOdeEquation]]: + """ + Analyse and transform a single neuron. + :param neuron: a single neuron. + :return: see documentation for get_spike_update_expressions() for more information. + :return: post_spike_updates: list of post-synaptic spike update expressions + :return: equations_with_delay_vars: list of equations containing delay variables + """ + code, message = Messages.get_start_processing_model(neuron.get_name()) + Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO) + + equations_block = neuron.get_equations_block() + + if equations_block is None: + # add all declared state variables as none of them are used in equations block + self.non_equations_state_variables[neuron.get_name()] = [] + self.non_equations_state_variables[neuron.get_name()].extend( + ASTUtils.all_variables_defined_in_block(neuron.get_state_blocks())) + + return [], [], [] + + delta_factors = ASTUtils.get_delta_factors_(neuron, equations_block) + kernel_buffers = ASTUtils.generate_kernel_buffers_(neuron, equations_block) + ASTUtils.replace_convolve_calls_with_buffers_(neuron, equations_block) + ASTUtils.make_inline_expressions_self_contained(equations_block.get_inline_expressions()) + ASTUtils.replace_inline_expressions_through_defining_expressions( + equations_block.get_ode_equations(), equations_block.get_inline_expressions()) + + # Collect all equations with delay variables and replace ASTFunctionCall to ASTVariable wherever necessary + equations_with_delay_vars_visitor = ASTEquationsWithDelayVarsVisitor() + neuron.accept(equations_with_delay_vars_visitor) + equations_with_delay_vars = equations_with_delay_vars_visitor.equations + + analytic_solver, numeric_solver = self.ode_toolbox_analysis(neuron, kernel_buffers) + self.analytic_solver[neuron.get_name()] = analytic_solver + self.numeric_solver[neuron.get_name()] = numeric_solver + + self.non_equations_state_variables[neuron.get_name()] = [] + for decl in neuron.get_state_blocks().get_declarations(): + for var in decl.get_variables(): + # check if this variable is not in equations + if not neuron.get_equations_blocks(): + self.non_equations_state_variables[neuron.get_name()].append(var) + continue + + used_in_eq = False + for ode_eq in neuron.get_equations_blocks().get_ode_equations(): + if ode_eq.get_lhs().get_name() == var.get_name(): + used_in_eq = True + break + for kern in neuron.get_equations_blocks().get_kernels(): + for kern_var in kern.get_variables(): + if kern_var.get_name() == var.get_name(): + used_in_eq = True + break + + if not used_in_eq: + self.non_equations_state_variables[neuron.get_name()].append(var) + + ASTUtils.remove_initial_values_for_kernels(neuron) + kernels = ASTUtils.remove_kernel_definitions_from_equations_block(neuron) + ASTUtils.update_initial_values_for_odes(neuron, [analytic_solver, numeric_solver]) + ASTUtils.remove_ode_definitions_from_equations_block(neuron) + ASTUtils.create_initial_values_for_kernels(neuron, [analytic_solver, numeric_solver], kernels) + ASTUtils.replace_variable_names_in_expressions(neuron, [analytic_solver, numeric_solver]) + ASTUtils.replace_convolution_aliasing_inlines(neuron) + ASTUtils.add_timestep_symbol(neuron) + + if self.analytic_solver[neuron.get_name()] is not None: + neuron = ASTUtils.add_declarations_to_internals( + neuron, self.analytic_solver[neuron.get_name()]["propagators"]) + + state_vars_before_update = neuron.get_state_symbols() + self.update_symbol_table(neuron) + + # Update the delay parameter parameters after symbol table update + ASTUtils.update_delay_parameter_in_state_vars(neuron, state_vars_before_update) + + spike_updates, post_spike_updates = self.get_spike_update_expressions( + neuron, kernel_buffers, [analytic_solver, numeric_solver], delta_factors) + + return spike_updates, post_spike_updates, equations_with_delay_vars + + def analyse_synapse(self, synapse: ASTSynapse) -> Dict[str, ASTAssignment]: + """ + Analyse and transform a single synapse. + :param synapse: a single synapse. + """ + code, message = Messages.get_start_processing_model(synapse.get_name()) + Logger.log_message(synapse, code, message, synapse.get_source_position(), LoggingLevel.INFO) + + equations_block = synapse.get_equations_block() + spike_updates = {} + if equations_block is not None: + delta_factors = ASTUtils.get_delta_factors_(synapse, equations_block) + kernel_buffers = ASTUtils.generate_kernel_buffers_(synapse, equations_block) + ASTUtils.replace_convolve_calls_with_buffers_(synapse, equations_block) + ASTUtils.make_inline_expressions_self_contained(equations_block.get_inline_expressions()) + ASTUtils.replace_inline_expressions_through_defining_expressions( + equations_block.get_ode_equations(), equations_block.get_inline_expressions()) + + analytic_solver, numeric_solver = self.ode_toolbox_analysis(synapse, kernel_buffers) + self.analytic_solver[synapse.get_name()] = analytic_solver + self.numeric_solver[synapse.get_name()] = numeric_solver + + ASTUtils.remove_initial_values_for_kernels(synapse) + kernels = ASTUtils.remove_kernel_definitions_from_equations_block(synapse) + ASTUtils.update_initial_values_for_odes(synapse, [analytic_solver, numeric_solver]) + ASTUtils.remove_ode_definitions_from_equations_block(synapse) + ASTUtils.create_initial_values_for_kernels(synapse, [analytic_solver, numeric_solver], kernels) + ASTUtils.replace_variable_names_in_expressions(synapse, [analytic_solver, numeric_solver]) + ASTUtils.add_timestep_symbol(synapse) + self.update_symbol_table(synapse) + + if not self.analytic_solver[synapse.get_name()] is None: + synapse = ASTUtils.add_declarations_to_internals( + synapse, self.analytic_solver[synapse.get_name()]["propagators"]) + + self.update_symbol_table(synapse) + spike_updates, _ = self.get_spike_update_expressions( + synapse, kernel_buffers, [analytic_solver, numeric_solver], delta_factors) + else: + ASTUtils.add_timestep_symbol(synapse) + + ASTUtils.update_blocktype_for_common_parameters(synapse) + + return spike_updates + + def _get_synapse_model_namespace(self, synapse: ASTSynapse) -> Dict: + """ + Returns a standard namespace with often required functionality. + :param synapse: a single synapse instance + :return: a map from name to functionality. + :rtype: dict + """ + namespace = dict() + + namespace["nest_version"] = self.get_option("nest_version") + + if "paired_neuron" in dir(synapse): + # synapse is being co-generated with neuron + namespace["paired_neuron"] = synapse.paired_neuron.get_name() + namespace["post_ports"] = synapse.post_port_names + + namespace["spiking_post_ports"] = synapse.spiking_post_port_names + namespace["vt_ports"] = synapse.vt_port_names + all_input_port_names = [p.name for p in synapse.get_input_blocks().get_input_ports()] + namespace["pre_ports"] = list(set(all_input_port_names) + - set(namespace["post_ports"]) - set(namespace["vt_ports"])) + else: + # separate (not neuron+synapse co-generated) + all_input_port_names = [p.name for p in synapse.get_input_blocks().get_input_ports()] + namespace["pre_ports"] = all_input_port_names + + assert len(namespace["pre_ports"]) <= 1, "Synapses only support one spiking input port" + + namespace["synapseName"] = synapse.get_name() + namespace["synapse"] = synapse + namespace["astnode"] = synapse + namespace["moduleName"] = FrontendConfiguration.get_module_name() + namespace["printer"] = self._unitless_nest_gsl_printer + namespace["assignments"] = NestAssignmentsHelper() + namespace["names"] = self._nest_reference_converter + namespace["declarations"] = NestDeclarationsHelper(self._types_printer) + namespace["utils"] = ASTUtils + namespace["idemPrinter"] = self._printer + namespace["printerGSL"] = self._gsl_printer + namespace["now"] = datetime.datetime.utcnow() + namespace["tracing"] = FrontendConfiguration.is_dev + namespace["has_state_vectors"] = False + namespace["vector_symbols"] = [] + namespace['has_delay_variables'] = synapse.has_delay_variables() + namespace['names_namespace'] = synapse.get_name() + "_names" + + # event handlers priority + # XXX: this should be refactored in case we have additional modulatory (3rd-factor) spiking input ports in the synapse + namespace["pre_before_post_update"] = 0 # C++-compatible boolean... + spiking_post_port = find_spiking_post_port(synapse, namespace) + if spiking_post_port: + post_spike_port_priority = None + if "priority" in synapse.get_on_receive_block(spiking_post_port).get_const_parameters().keys(): + post_spike_port_priority = int(synapse.get_on_receive_block( + spiking_post_port).get_const_parameters()["priority"]) + + if post_spike_port_priority \ + and len(namespace["pre_ports"]) and len(namespace["post_ports"]) \ + and "priority" in synapse.get_on_receive_block(namespace["pre_ports"][0]).get_const_parameters().keys() \ + and int(synapse.get_on_receive_block(namespace["pre_ports"][0]).get_const_parameters()["priority"]) < post_spike_port_priority: + namespace["pre_before_post_update"] = 1 # C++-compatible boolean... + + namespace["PredefinedUnits"] = pynestml.symbols.predefined_units.PredefinedUnits + namespace["UnitTypeSymbol"] = pynestml.symbols.unit_type_symbol.UnitTypeSymbol + namespace["SymbolKind"] = pynestml.symbols.symbol.SymbolKind + + namespace["initial_values"] = {} + namespace["variable_symbols"] = {} + namespace["uses_analytic_solver"] = synapse.get_name() in self.analytic_solver.keys() \ + and self.analytic_solver[synapse.get_name()] is not None + if namespace["uses_analytic_solver"]: + namespace["analytic_state_variables"] = self.analytic_solver[synapse.get_name()]["state_variables"] + namespace["variable_symbols"].update({sym: synapse.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["analytic_state_variables"]}) + namespace["update_expressions"] = {} + for sym, expr in self.analytic_solver[synapse.get_name()]["initial_values"].items(): + namespace["initial_values"][sym] = expr + for sym in namespace["analytic_state_variables"]: + expr_str = self.analytic_solver[synapse.get_name()]["update_expressions"][sym] + expr_ast = ModelParser.parse_expression(expr_str) + # pretend that update expressions are in "equations" block, which should always be present, + # as differential equations must have been defined to get here + expr_ast.update_scope(synapse.get_equations_blocks().get_scope()) + expr_ast.accept(ASTSymbolTableVisitor()) + namespace["update_expressions"][sym] = expr_ast + + namespace["propagators"] = self.analytic_solver[synapse.get_name()]["propagators"] + + namespace["uses_numeric_solver"] = synapse.get_name() in self.numeric_solver.keys() \ + and self.numeric_solver[synapse.get_name()] is not None + if namespace["uses_numeric_solver"]: + namespace["numeric_state_variables"] = self.numeric_solver[synapse.get_name()]["state_variables"] + namespace["variable_symbols"].update({sym: synapse.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["numeric_state_variables"]}) + assert not any([sym is None for sym in namespace["variable_symbols"].values()]) + namespace["numeric_update_expressions"] = {} + for sym, expr in self.numeric_solver[synapse.get_name()]["initial_values"].items(): + namespace["initial_values"][sym] = expr + for sym in namespace["numeric_state_variables"]: + expr_str = self.numeric_solver[synapse.get_name()]["update_expressions"][sym] + expr_ast = ModelParser.parse_expression(expr_str) + # pretend that update expressions are in "equations" block, which should always be present, + # as differential equations must have been defined to get here + expr_ast.update_scope(synapse.get_equations_blocks().get_scope()) + expr_ast.accept(ASTSymbolTableVisitor()) + namespace["numeric_update_expressions"][sym] = expr_ast + + namespace["names"] = self._gsl_reference_converter + namespace["printer"] = self._unitless_nest_gsl_printer + + namespace["spike_updates"] = synapse.spike_updates + + rng_visitor = ASTRandomNumberGeneratorVisitor() + synapse.accept(rng_visitor) + namespace["norm_rng"] = rng_visitor._norm_rng_is_used + + namespace["PyNestMLLexer"] = {} + from pynestml.generated.PyNestMLLexer import PyNestMLLexer + for kw in dir(PyNestMLLexer): + if kw.isupper(): + namespace["PyNestMLLexer"][kw] = eval("PyNestMLLexer." + kw) + + return namespace + + def _get_neuron_model_namespace(self, neuron: ASTNeuron) -> Dict: + """ + Returns a standard namespace with often required functionality. + :param neuron: a single neuron instance + :type neuron: ASTNeuron + :return: a map from name to functionality. + :rtype: dict + """ + namespace = dict() + + namespace["nest_version"] = self.get_option("nest_version") + + if "paired_synapse" in dir(neuron): + namespace["paired_synapse"] = neuron.paired_synapse.get_name() + namespace["post_spike_updates"] = neuron.post_spike_updates + if "moved_spike_updates" in dir(neuron): + namespace["spike_update_stmts"] = neuron.moved_spike_updates + else: + namespace["spike_update_stmts"] = [] + namespace["transferred_variables"] = neuron._transferred_variables + namespace["transferred_variables_syms"] = {var_name: neuron.scope.resolve_to_symbol( + var_name, SymbolKind.VARIABLE) for var_name in namespace["transferred_variables"]} + assert not any([v is None for v in namespace["transferred_variables_syms"].values()]) + # {var_name: ASTUtils.get_declaration_by_name(neuron.get_initial_values_blocks(), var_name) for var_name in namespace["transferred_variables"]} + namespace["neuronName"] = neuron.get_name() + namespace["neuron"] = neuron + namespace["astnode"] = neuron + namespace["moduleName"] = FrontendConfiguration.get_module_name() + namespace["printer"] = self._unitless_nest_gsl_printer + namespace["nest_printer"] = self._nest_printer + namespace["assignments"] = NestAssignmentsHelper() + namespace["names"] = self._nest_reference_converter + namespace["declarations"] = NestDeclarationsHelper(self._types_printer) + namespace["utils"] = ASTUtils + namespace["idemPrinter"] = self._printer + namespace["outputEvent"] = namespace["printer"].print_output_event(neuron.get_body()) + namespace["has_spike_input"] = ASTUtils.has_spike_input(neuron.get_body()) + namespace["has_continuous_input"] = ASTUtils.has_continuous_input(neuron.get_body()) + namespace["printerGSL"] = self._gsl_printer + namespace["now"] = datetime.datetime.utcnow() + namespace["tracing"] = FrontendConfiguration.is_dev + namespace["has_state_vectors"] = neuron.has_state_vectors() + namespace["vector_symbols"] = neuron.get_vector_symbols() + namespace["has_delay_variables"] = neuron.has_delay_variables() + namespace["names_namespace"] = neuron.get_name() + "_names" + + namespace["neuron_parent_class"] = self.get_option("neuron_parent_class") + namespace["neuron_parent_class_include"] = self.get_option("neuron_parent_class_include") + + namespace["PredefinedUnits"] = pynestml.symbols.predefined_units.PredefinedUnits + namespace["UnitTypeSymbol"] = pynestml.symbols.unit_type_symbol.UnitTypeSymbol + namespace["SymbolKind"] = pynestml.symbols.symbol.SymbolKind + + namespace["initial_values"] = {} + namespace["variable_symbols"] = {} + + namespace["uses_analytic_solver"] = neuron.get_name() in self.analytic_solver.keys() \ + and self.analytic_solver[neuron.get_name()] is not None + if namespace["uses_analytic_solver"]: + namespace["analytic_state_variables_moved"] = [] + if "paired_synapse" in dir(neuron): + namespace["analytic_state_variables"] = [] + for sv in self.analytic_solver[neuron.get_name()]["state_variables"]: + moved = False + for mv in neuron.recursive_vars_used: + name_snip = mv + "__" + if name_snip == sv[:len(name_snip)]: + # this variable was moved from synapse to neuron + if not sv in namespace["analytic_state_variables_moved"]: + namespace["analytic_state_variables_moved"].append(sv) + moved = True + if not moved: + namespace["analytic_state_variables"].append(sv) + namespace["variable_symbols"].update({sym: neuron.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["analytic_state_variables_moved"]}) + else: + namespace["analytic_state_variables"] = self.analytic_solver[neuron.get_name()]["state_variables"] + namespace["variable_symbols"].update({sym: neuron.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["analytic_state_variables"]}) + + namespace["update_expressions"] = {} + for sym, expr in self.analytic_solver[neuron.get_name()]["initial_values"].items(): + namespace["initial_values"][sym] = expr + for sym in namespace["analytic_state_variables"] + namespace["analytic_state_variables_moved"]: + expr_str = self.analytic_solver[neuron.get_name()]["update_expressions"][sym] + expr_ast = ModelParser.parse_expression(expr_str) + # pretend that update expressions are in "equations" block, which should always be present, + # as differential equations must have been defined to get here + expr_ast.update_scope(neuron.get_equations_blocks().get_scope()) + expr_ast.accept(ASTSymbolTableVisitor()) + namespace["update_expressions"][sym] = expr_ast + + # Check if the update expression has delay variables + if ASTUtils.has_equation_with_delay_variable(neuron.equations_with_delay_vars, sym): + marks_delay_vars_visitor = ASTMarkDelayVarsVisitor() + expr_ast.accept(marks_delay_vars_visitor) + + namespace["propagators"] = self.analytic_solver[neuron.get_name()]["propagators"] + + namespace["propagators_are_state_dependent"] = False + for prop_name, prop_expr in namespace["propagators"].items(): + prop_expr_ast = ModelParser.parse_expression(prop_expr) + + for var_sym in neuron.get_state_symbols(): + if var_sym.get_symbol_name() in [var.get_name() for var in prop_expr_ast.get_variables()]: + namespace["propagators_are_state_dependent"] = True + + # convert variables from ASTVariable instances to strings + _names = self.non_equations_state_variables[neuron.get_name()] + _names = [ASTUtils.to_ode_toolbox_processed_name(var.get_complete_name()) for var in _names] + namespace["non_equations_state_variables"] = _names + + namespace["uses_numeric_solver"] = neuron.get_name() in self.numeric_solver.keys() \ + and self.numeric_solver[neuron.get_name()] is not None + if namespace["uses_numeric_solver"]: + namespace["numeric_state_variables_moved"] = [] + if "paired_synapse" in dir(neuron): + namespace["numeric_state_variables"] = [] + for sv in self.numeric_solver[neuron.get_name()]["state_variables"]: + moved = False + for mv in neuron.recursive_vars_used: + name_snip = mv + "__" + if name_snip == sv[:len(name_snip)]: + # this variable was moved from synapse to neuron + if not sv in namespace["numeric_state_variables_moved"]: + namespace["numeric_state_variables_moved"].append(sv) + moved = True + if not moved: + namespace["numeric_state_variables"].append(sv) + namespace["variable_symbols"].update({sym: neuron.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["numeric_state_variables_moved"]}) + else: + namespace["numeric_state_variables"] = self.numeric_solver[neuron.get_name()]["state_variables"] + + namespace["variable_symbols"].update({sym: neuron.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["numeric_state_variables"]}) + assert not any([sym is None for sym in namespace["variable_symbols"].values()]) + for sym, expr in self.numeric_solver[neuron.get_name()]["initial_values"].items(): + namespace["initial_values"][sym] = expr + namespace["numeric_update_expressions"] = {} + for sym in namespace["numeric_state_variables"] + namespace["numeric_state_variables_moved"]: + expr_str = self.numeric_solver[neuron.get_name()]["update_expressions"][sym] + expr_ast = ModelParser.parse_expression(expr_str) + # pretend that update expressions are in "equations" block, which should always be present, + # as differential equations must have been defined to get here + expr_ast.update_scope(neuron.get_equations_blocks().get_scope()) + expr_ast.accept(ASTSymbolTableVisitor()) + namespace["numeric_update_expressions"][sym] = expr_ast + + # Check if the update expression has delay variables + if ASTUtils.has_equation_with_delay_variable(neuron.equations_with_delay_vars, sym): + marks_delay_vars_visitor = ASTMarkDelayVarsVisitor() + expr_ast.accept(marks_delay_vars_visitor) + + if namespace["uses_numeric_solver"]: + if "analytic_state_variables_moved" in namespace.keys(): + namespace["purely_numeric_state_variables_moved"] = list( + set(namespace["numeric_state_variables_moved"]) - set(namespace["analytic_state_variables_moved"])) + + else: + namespace["purely_numeric_state_variables_moved"] = namespace["numeric_state_variables_moved"] + + namespace["names"] = self._gsl_reference_converter + namespace["printer"] = self._unitless_nest_gsl_printer + namespace["spike_updates"] = neuron.spike_updates + + namespace["recordable_state_variables"] = [sym for sym in neuron.get_state_symbols() + if isinstance(sym.get_type_symbol(), (UnitTypeSymbol, RealTypeSymbol)) + and sym.is_recordable + and not ASTUtils.is_delta_kernel(neuron.get_kernel_by_name(sym.name))] + + namespace["recordable_inline_expressions"] = [sym for sym in neuron.get_inline_expression_symbols() + if isinstance(sym.get_type_symbol(), (UnitTypeSymbol, RealTypeSymbol)) + and sym.is_recordable] + + namespace["parameter_syms_with_iv"] = [sym for sym in neuron.get_parameter_symbols() + if sym.has_declaring_expression() + and (not neuron.get_kernel_by_name(sym.name))] + + rng_visitor = ASTRandomNumberGeneratorVisitor() + neuron.accept(rng_visitor) + namespace["norm_rng"] = rng_visitor._norm_rng_is_used + + return namespace + + def ode_toolbox_analysis(self, neuron: ASTNeuron, kernel_buffers: Mapping[ASTKernel, ASTInputPort]): + """ + Prepare data for ODE-toolbox input format, invoke ODE-toolbox analysis via its API, and return the output. + """ + assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "only one equation block should be present" + + equations_block = neuron.get_equations_block() + + if len(equations_block.get_kernels()) == 0 and len(equations_block.get_ode_equations()) == 0: + # no equations defined -> no changes to the neuron + return None, None + + parameters_block = neuron.get_parameter_blocks() + odetoolbox_indict = ASTUtils.transform_ode_and_kernels_to_json(neuron, parameters_block, kernel_buffers, printer=self._ode_toolbox_printer) + odetoolbox_indict["options"] = {} + odetoolbox_indict["options"]["output_timestep_symbol"] = "__h" + solver_result = odetoolbox.analysis(odetoolbox_indict, + disable_stiffness_check=True, + preserve_expressions=self.get_option("preserve_expressions"), + simplify_expression=self.get_option("simplify_expression"), + log_level=FrontendConfiguration.logging_level) + analytic_solver = None + analytic_solvers = [x for x in solver_result if x["solver"] == "analytical"] + assert len(analytic_solvers) <= 1, "More than one analytic solver not presently supported" + if len(analytic_solvers) > 0: + analytic_solver = analytic_solvers[0] + + # if numeric solver is required, generate a stepping function that includes each state variable, including the analytic ones + numeric_solver = None + numeric_solvers = [x for x in solver_result if x["solver"].startswith("numeric")] + if numeric_solvers: + solver_result = odetoolbox.analysis(odetoolbox_indict, + disable_stiffness_check=True, + disable_analytic_solver=True, + preserve_expressions=self.get_option("preserve_expressions"), + simplify_expression=self.get_option("simplify_expression"), + log_level=FrontendConfiguration.logging_level) + numeric_solvers = [x for x in solver_result if x["solver"].startswith("numeric")] + assert len(numeric_solvers) <= 1, "More than one numeric solver not presently supported" + if len(numeric_solvers) > 0: + numeric_solver = numeric_solvers[0] + + return analytic_solver, numeric_solver + + def update_symbol_table(self, neuron) -> None: + """ + Update symbol table and scope. + """ + SymbolTable.delete_neuron_scope(neuron.get_name()) + symbol_table_visitor = ASTSymbolTableVisitor() + symbol_table_visitor.after_ast_rewrite_ = True + neuron.accept(symbol_table_visitor) + SymbolTable.add_neuron_scope(neuron.get_name(), neuron.get_scope()) + + def get_spike_update_expressions(self, neuron: ASTNeuron, kernel_buffers, solver_dicts, delta_factors) -> Tuple[Dict[str, ASTAssignment], Dict[str, ASTAssignment]]: + r""" + Generate the equations that update the dynamical variables when incoming spikes arrive. To be invoked after + ode-toolbox. + + For example, a resulting `assignment_str` could be "I_kernel_in += (inh_spikes/nS) * 1". The values are taken from the initial values for each corresponding dynamical variable, either from ode-toolbox or directly from user specification in the model. + from the initial values for each corresponding dynamical variable, either from ode-toolbox or directly from + user specification in the model. + + Note that for kernels, `initial_values` actually contains the increment upon spike arrival, rather than the + initial value of the corresponding ODE dimension. + ``spike_updates`` is a mapping from input port name (as a string) to update expressions. + + ``post_spike_updates`` is a mapping from kernel name (as a string) to update expressions. + """ + spike_updates = {} + post_spike_updates = {} + + for kernel, spike_input_port in kernel_buffers: + if ASTUtils.is_delta_kernel(kernel): + continue + + if not str(spike_input_port) in spike_updates.keys(): + spike_updates[str(spike_input_port)] = [] + + if "_is_post_port" in dir(spike_input_port.get_variable()) \ + and spike_input_port.get_variable()._is_post_port: + # it's a port in the neuron ??? that receives post spikes ??? + orig_port_name = str(spike_input_port)[:str(spike_input_port).index("__for_")] + buffer_type = neuron.paired_synapse.get_scope().resolve_to_symbol(orig_port_name, SymbolKind.VARIABLE).get_type_symbol() + else: + buffer_type = neuron.get_scope().resolve_to_symbol(str(spike_input_port), SymbolKind.VARIABLE).get_type_symbol() + + assert not buffer_type is None + + for kernel_var in kernel.get_variables(): + for var_order in range(ASTUtils.get_kernel_var_order_from_ode_toolbox_result(kernel_var.get_name(), solver_dicts)): + kernel_spike_buf_name = ASTUtils.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_input_port, var_order) + expr = ASTUtils.get_initial_value_from_ode_toolbox_result( + kernel_spike_buf_name, solver_dicts) + assert expr is not None, "Initial value not found for kernel " + kernel_var + expr = str(expr) + if expr in ["0", "0.", "0.0"]: + continue # skip adding the statement if we are only adding zero + + assignment_str = kernel_spike_buf_name + " += " + if "_is_post_port" in dir(spike_input_port.get_variable()) \ + and spike_input_port.get_variable()._is_post_port: + assignment_str += "1." + else: + assignment_str += "(" + str(spike_input_port) + ")" + if not expr in ["1.", "1.0", "1"]: + assignment_str += " * (" + expr + ")" + + if not buffer_type.print_nestml_type() in ["1.", "1.0", "1", "real", "integer"]: + assignment_str += " / (" + buffer_type.print_nestml_type() + ")" + + ast_assignment = ModelParser.parse_assignment(assignment_str) + ast_assignment.update_scope(neuron.get_scope()) + ast_assignment.accept(ASTSymbolTableVisitor()) + + if neuron.get_scope().resolve_to_symbol(str(spike_input_port), SymbolKind.VARIABLE) is None: + # this case covers variables that were moved from synapse to the neuron + post_spike_updates[kernel_var.get_name()] = ast_assignment + elif "_is_post_port" in dir(spike_input_port.get_variable()) and spike_input_port.get_variable()._is_post_port: + Logger.log_message(None, None, "Adding post assignment string: " + str(ast_assignment), None, LoggingLevel.INFO) + spike_updates[str(spike_input_port)].append(ast_assignment) + else: + spike_updates[str(spike_input_port)].append(ast_assignment) + + for k, factor in delta_factors.items(): + var = k[0] + inport = k[1] + assignment_str = var.get_name() + "'" * (var.get_differential_order() - 1) + " += " + if not factor in ["1.", "1.0", "1"]: + factor_expr = ModelParser.parse_expression(factor) + factor_expr.update_scope(neuron.get_scope()) + factor_expr.accept(ASTSymbolTableVisitor()) + assignment_str += "(" + self._unitless_expression_printer_no_origin.print_expression(factor_expr) + ") * " + + assignment_str += str(inport) + ast_assignment = ModelParser.parse_assignment(assignment_str) + ast_assignment.update_scope(neuron.get_scope()) + ast_assignment.accept(ASTSymbolTableVisitor()) + + if not str(inport) in spike_updates.keys(): + spike_updates[str(inport)] = [] + + spike_updates[str(inport)].append(ast_assignment) + + return spike_updates, post_spike_updates diff --git a/pynestml/codegeneration/nest_codegenerator.py b/pynestml/codegeneration/nest_codegenerator.py deleted file mode 100644 index 36ca0f23f..000000000 --- a/pynestml/codegeneration/nest_codegenerator.py +++ /dev/null @@ -1,871 +0,0 @@ -# -*- coding: utf-8 -*- -# -# nest_codegenerator.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -import copy -import json -import datetime -import os -import re -import sympy -from typing import Optional, Union, List, Dict, Mapping -from jinja2 import Environment, FileSystemLoader, TemplateRuntimeError -from odetoolbox import analysis - -import pynestml - -from pynestml.codegeneration.ast_transformers import add_assignment_to_update_block, add_declarations_to_internals, add_declaration_to_initial_values, declaration_in_initial_values, get_delta_kernel_prefactor_expr, is_delta_kernel, replace_rhs_variables, replace_rhs_variable, construct_kernel_X_spike_buf_name, get_expr_from_kernel_var, to_ode_toolbox_name, to_ode_toolbox_processed_name, get_kernel_var_order_from_ode_toolbox_result, get_initial_value_from_ode_toolbox_result, variable_in_kernels, is_ode_variable, variable_in_solver, variable_in_neuron_initial_values -from pynestml.codegeneration.codegenerator import CodeGenerator -from pynestml.codegeneration.expressions_pretty_printer import ExpressionsPrettyPrinter -from pynestml.codegeneration.gsl_names_converter import GSLNamesConverter -from pynestml.codegeneration.gsl_reference_converter import GSLReferenceConverter -from pynestml.codegeneration.nestml_reference_converter import NestMLReferenceConverter -from pynestml.codegeneration.ode_toolbox_reference_converter import ODEToolboxReferenceConverter -from pynestml.codegeneration.unitless_expression_printer import UnitlessExpressionPrinter -from pynestml.codegeneration.nest_assignments_helper import NestAssignmentsHelper -from pynestml.codegeneration.nest_declarations_helper import NestDeclarationsHelper -from pynestml.codegeneration.nest_names_converter import NestNamesConverter -from pynestml.codegeneration.nest_printer import NestPrinter -from pynestml.codegeneration.nest_reference_converter import NESTReferenceConverter -from pynestml.frontend.frontend_configuration import FrontendConfiguration -from pynestml.meta_model.ast_assignment import ASTAssignment -from pynestml.meta_model.ast_declaration import ASTDeclaration -from pynestml.meta_model.ast_equations_block import ASTEquationsBlock -from pynestml.meta_model.ast_expression import ASTExpression -from pynestml.meta_model.ast_input_port import ASTInputPort -from pynestml.meta_model.ast_inline_expression import ASTInlineExpression -from pynestml.meta_model.ast_neuron import ASTNeuron -from pynestml.meta_model.ast_node_factory import ASTNodeFactory -from pynestml.meta_model.ast_kernel import ASTKernel -from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.symbol_table.symbol_table import SymbolTable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.variable_symbol import VariableType, VariableSymbol -from pynestml.symbols.variable_symbol import BlockType -from pynestml.utils.ast_utils import ASTUtils -from pynestml.utils.logger import Logger -from pynestml.utils.logger import LoggingLevel -from pynestml.utils.messages import Messages -from pynestml.utils.model_parser import ModelParser -from pynestml.utils.ode_transformer import OdeTransformer -from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor -from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor -from pynestml.visitors.ast_random_number_generator_visitor import ASTRandomNumberGeneratorVisitor - - -class NESTCodeGenerator(CodeGenerator): - """ - Code generator for a C++ NEST extension module. - """ - - _variable_matching_template = r'(\b)({})(\b)' - - def __init__(self): - self.analytic_solver = {} - self.numeric_solver = {} - self.non_equations_state_variables = {} # those state variables not defined as an ODE in the equations block - self._setup_template_env() - - def _setup_template_env(self): - """setup the Jinja2 template environment""" - - def raise_helper(msg): - raise TemplateRuntimeError(msg) - - env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'resources_nest'))) - env.globals['raise'] = raise_helper - env.globals["is_delta_kernel"] = is_delta_kernel - setup_env = Environment(loader=FileSystemLoader(os.path.join( - os.path.dirname(__file__), 'resources_nest', 'setup'))) - setup_env.globals['raise'] = raise_helper - # setup the cmake template - self._template_cmakelists = setup_env.get_template('CMakeLists.jinja2') - # setup the module class template - self._template_module_class = env.get_template('ModuleClass.jinja2') - # setup the NEST module template - self._template_module_header = env.get_template('ModuleHeader.jinja2') - # setup the SLI_Init file - self._template_sli_init = setup_env.get_template('SLI_Init.jinja2') - # setup the neuron header template - self._template_neuron_h_file = env.get_template('NeuronHeader.jinja2') - # setup the neuron implementation template - self._template_neuron_cpp_file = env.get_template('NeuronClass.jinja2') - self._printer = ExpressionsPrettyPrinter() - - def generate_code(self, neurons): - self.analyse_transform_neurons(neurons) - self.generate_neurons(neurons) - self.generate_module_code(neurons) - - def generate_module_code(self, neurons: List[ASTNeuron]) -> None: - """ - Generates code that is necessary to integrate neuron models into the NEST infrastructure. - :param neurons: a list of neurons - :type neurons: list(ASTNeuron) - """ - namespace = {'neurons': neurons, - 'moduleName': FrontendConfiguration.get_module_name(), - 'now': datetime.datetime.utcnow()} - if not os.path.exists(FrontendConfiguration.get_target_path()): - os.makedirs(FrontendConfiguration.get_target_path()) - - with open(str(os.path.join(FrontendConfiguration.get_target_path(), - FrontendConfiguration.get_module_name())) + '.h', 'w+') as f: - f.write(str(self._template_module_header.render(namespace))) - - with open(str(os.path.join(FrontendConfiguration.get_target_path(), - FrontendConfiguration.get_module_name())) + '.cpp', 'w+') as f: - f.write(str(self._template_module_class.render(namespace))) - - with open(str(os.path.join(FrontendConfiguration.get_target_path(), - 'CMakeLists')) + '.txt', 'w+') as f: - f.write(str(self._template_cmakelists.render(namespace))) - - if not os.path.isdir(os.path.realpath(os.path.join(FrontendConfiguration.get_target_path(), 'sli'))): - os.makedirs(os.path.realpath(os.path.join(FrontendConfiguration.get_target_path(), 'sli'))) - - with open(str(os.path.join(FrontendConfiguration.get_target_path(), 'sli', - FrontendConfiguration.get_module_name() + "-init")) + '.sli', 'w+') as f: - f.write(str(self._template_sli_init.render(namespace))) - - code, message = Messages.get_module_generated(FrontendConfiguration.get_target_path()) - Logger.log_message(None, code, message, None, LoggingLevel.INFO) - - def analyse_transform_neurons(self, neurons: List[ASTNeuron]) -> None: - """ - Analyse and transform a list of neurons. - :param neurons: a list of neurons. - """ - for neuron in neurons: - code, message = Messages.get_analysing_transforming_neuron(neuron.get_name()) - Logger.log_message(None, code, message, None, LoggingLevel.INFO) - spike_updates = self.analyse_neuron(neuron) - neuron.spike_updates = spike_updates - # now store the transformed model - self.store_transformed_model(neuron) - - def get_delta_factors_(self, neuron, equations_block): - r""" - For every occurrence of a convolution of the form `x^(n) = a * convolve(kernel, inport) + ...` where `kernel` is a delta function, add the element `(x^(n), inport) --> a` to the set. - """ - delta_factors = {} - for ode_eq in equations_block.get_ode_equations(): - var = ode_eq.get_lhs() - expr = ode_eq.get_rhs() - conv_calls = OdeTransformer.get_convolve_function_calls(expr) - for conv_call in conv_calls: - assert len( - conv_call.args) == 2, "convolve() function call should have precisely two arguments: kernel and spike buffer" - kernel = conv_call.args[0] - if is_delta_kernel(neuron.get_kernel_by_name(kernel.get_variable().get_name())): - inport = conv_call.args[1].get_variable() - expr_str = str(expr) - sympy_expr = sympy.parsing.sympy_parser.parse_expr(expr_str) - sympy_expr = sympy.expand(sympy_expr) - sympy_conv_expr = sympy.parsing.sympy_parser.parse_expr(str(conv_call)) - factor_str = [] - for term in sympy.Add.make_args(sympy_expr): - if term.find(sympy_conv_expr): - factor_str.append(str(term.replace(sympy_conv_expr, 1))) - factor_str = " + ".join(factor_str) - delta_factors[(var, inport)] = factor_str - - return delta_factors - - def generate_kernel_buffers_(self, neuron, equations_block): - """ - For every occurrence of a convolution of the form `convolve(var, spike_buf)`: add the element `(kernel, spike_buf)` to the set, with `kernel` being the kernel that contains variable `var`. - """ - - kernel_buffers = set() - convolve_calls = OdeTransformer.get_convolve_function_calls(equations_block) - for convolve in convolve_calls: - el = (convolve.get_args()[0], convolve.get_args()[1]) - sym = convolve.get_args()[0].get_scope().resolve_to_symbol( - convolve.get_args()[0].get_variable().name, SymbolKind.VARIABLE) - if sym is None: - raise Exception("No initial value(s) defined for kernel with variable \"" - + convolve.get_args()[0].get_variable().get_complete_name() + "\"") - if sym.block_type == BlockType.INPUT_BUFFER_SPIKE: - el = (el[1], el[0]) - - # find the corresponding kernel object - var = el[0].get_variable() - assert var is not None - kernel = neuron.get_kernel_by_name(var.get_name()) - assert kernel is not None, "In convolution \"convolve(" + str(var.name) + ", " + str( - el[1]) + ")\": no kernel by name \"" + var.get_name() + "\" found in neuron." - - el = (kernel, el[1]) - kernel_buffers.add(el) - - return kernel_buffers - - def replace_variable_names_in_expressions(self, neuron, solver_dicts): - """ - Replace all occurrences of variables names in NESTML format (e.g. `g_ex$''`)` with the ode-toolbox formatted - variable name (e.g. `g_ex__DOLLAR__d__d`). - """ - def replace_var(_expr=None): - if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): - var = _expr.get_variable() - if variable_in_solver(to_ode_toolbox_processed_name(var.get_complete_name()), solver_dicts): - ast_variable = ASTVariable(to_ode_toolbox_processed_name( - var.get_complete_name()), differential_order=0) - ast_variable.set_source_position(var.get_source_position()) - _expr.set_variable(ast_variable) - - elif isinstance(_expr, ASTVariable): - var = _expr - if variable_in_solver(to_ode_toolbox_processed_name(var.get_complete_name()), solver_dicts): - var.set_name(to_ode_toolbox_processed_name(var.get_complete_name())) - var.set_differential_order(0) - - def func(x): - return replace_var(x) - - neuron.accept(ASTHigherOrderVisitor(func)) - - def replace_convolve_calls_with_buffers_(self, neuron, equations_block, kernel_buffers): - r""" - Replace all occurrences of `convolve(kernel[']^n, spike_input_port)` with the corresponding buffer variable, e.g. `g_E__X__spikes_exc[__d]^n` for a kernel named `g_E` and a spike input port named `spikes_exc`. - """ - - def replace_function_call_through_var(_expr=None): - if _expr.is_function_call() and _expr.get_function_call().get_name() == "convolve": - convolve = _expr.get_function_call() - el = (convolve.get_args()[0], convolve.get_args()[1]) - sym = convolve.get_args()[0].get_scope().resolve_to_symbol( - convolve.get_args()[0].get_variable().name, SymbolKind.VARIABLE) - if sym.block_type == BlockType.INPUT_BUFFER_SPIKE: - el = (el[1], el[0]) - var = el[0].get_variable() - spike_input_port = el[1].get_variable() - kernel = neuron.get_kernel_by_name(var.get_name()) - - _expr.set_function_call(None) - buffer_var = construct_kernel_X_spike_buf_name( - var.get_name(), spike_input_port, var.get_differential_order() - 1) - if is_delta_kernel(kernel): - # delta kernel are treated separately, and should be kept out of the dynamics (computing derivates etc.) --> set to zero - _expr.set_variable(None) - _expr.set_numeric_literal(0) - else: - ast_variable = ASTVariable(buffer_var) - ast_variable.set_source_position(_expr.get_source_position()) - _expr.set_variable(ast_variable) - - def func(x): - return replace_function_call_through_var(x) if isinstance(x, ASTSimpleExpression) else True - - equations_block.accept(ASTHigherOrderVisitor(func)) - - def add_timestep_symbol(self, neuron): - assert neuron.get_initial_value( - "__h") is None, "\"__h\" is a reserved name, please do not use variables by this name in your NESTML file" - assert not "__h" in [sym.name for sym in neuron.get_internal_symbols( - )], "\"__h\" is a reserved name, please do not use variables by this name in your NESTML file" - neuron.add_to_internal_block(ModelParser.parse_declaration('__h ms = resolution()'), index=0) - - def analyse_neuron(self, neuron: ASTNeuron) -> List[ASTAssignment]: - """ - Analyse and transform a single neuron. - :param neuron: a single neuron. - :return: spike_updates: list of spike updates, see documentation for get_spike_update_expressions() for more information. - """ - code, message = Messages.get_start_processing_neuron(neuron.get_name()) - Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO) - - equations_block = neuron.get_equations_block() - - if equations_block is None: - # add all declared state variables as none of them are used in equations block - self.non_equations_state_variables[neuron.get_name()] = [] - self.non_equations_state_variables[neuron.get_name()].extend(ASTUtils.all_variables_defined_in_block(neuron.get_initial_values_blocks())) - self.non_equations_state_variables[neuron.get_name()].extend(ASTUtils.all_variables_defined_in_block(neuron.get_state_blocks())) - - return [] - - delta_factors = self.get_delta_factors_(neuron, equations_block) - kernel_buffers = self.generate_kernel_buffers_(neuron, equations_block) - self.replace_convolve_calls_with_buffers_(neuron, equations_block, kernel_buffers) - self.make_inline_expressions_self_contained(equations_block.get_inline_expressions()) - self.replace_inline_expressions_through_defining_expressions( - equations_block.get_ode_equations(), equations_block.get_inline_expressions()) - - analytic_solver, numeric_solver = self.ode_toolbox_analysis(neuron, kernel_buffers) - self.analytic_solver[neuron.get_name()] = analytic_solver - self.numeric_solver[neuron.get_name()] = numeric_solver - - self.non_equations_state_variables[neuron.get_name()] = [] - for decl in neuron.get_initial_values_blocks().get_declarations(): - for var in decl.get_variables(): - # check if this variable is not in equations - if not neuron.get_equations_blocks(): - self.non_equations_state_variables[neuron.get_name()].append(var) - continue - - used_in_eq = False - for ode_eq in neuron.get_equations_blocks().get_ode_equations(): - if ode_eq.get_lhs().get_name() == var.get_name(): - used_in_eq = True - break - for kern in neuron.get_equations_blocks().get_kernels(): - for kern_var in kern.get_variables(): - if kern_var.get_name() == var.get_name(): - used_in_eq = True - break - - if not used_in_eq: - self.non_equations_state_variables[neuron.get_name()].append(var) - - self.remove_initial_values_for_kernels(neuron) - kernels = self.remove_kernel_definitions_from_equations_block(neuron) - self.update_initial_values_for_odes(neuron, [analytic_solver, numeric_solver], kernels) - self.remove_ode_definitions_from_equations_block(neuron) - self.create_initial_values_for_kernels(neuron, [analytic_solver, numeric_solver], kernels) - self.replace_variable_names_in_expressions(neuron, [analytic_solver, numeric_solver]) - self.add_timestep_symbol(neuron) - - if self.analytic_solver[neuron.get_name()] is not None: - neuron = add_declarations_to_internals(neuron, self.analytic_solver[neuron.get_name()]["propagators"]) - - self.update_symbol_table(neuron, kernel_buffers) - spike_updates = self.get_spike_update_expressions( - neuron, kernel_buffers, [analytic_solver, numeric_solver], delta_factors) - - return spike_updates - - def generate_neuron_code(self, neuron: ASTNeuron) -> None: - """ - For a handed over neuron, this method generates the corresponding header and implementation file. - :param neuron: a single neuron object. - """ - if not os.path.isdir(FrontendConfiguration.get_target_path()): - os.makedirs(FrontendConfiguration.get_target_path()) - self.generate_model_h_file(neuron) - self.generate_neuron_cpp_file(neuron) - - def generate_model_h_file(self, neuron: ASTNeuron) -> None: - """ - For a handed over neuron, this method generates the corresponding header file. - :param neuron: a single neuron object. - """ - neuron_h_file = self._template_neuron_h_file.render(self.setup_generation_helpers(neuron)) - with open(str(os.path.join(FrontendConfiguration.get_target_path(), neuron.get_name())) + '.h', 'w+') as f: - f.write(str(neuron_h_file)) - - def generate_neuron_cpp_file(self, neuron: ASTNeuron) -> None: - """ - For a handed over neuron, this method generates the corresponding implementation file. - :param neuron: a single neuron object. - """ - neuron_cpp_file = self._template_neuron_cpp_file.render(self.setup_generation_helpers(neuron)) - with open(str(os.path.join(FrontendConfiguration.get_target_path(), neuron.get_name())) + '.cpp', 'w+') as f: - f.write(str(neuron_cpp_file)) - - def setup_generation_helpers(self, neuron: ASTNeuron) -> Dict: - """ - Returns a standard namespace with often required functionality. - :param neuron: a single neuron instance - :type neuron: ASTNeuron - :return: a map from name to functionality. - :rtype: dict - """ - gsl_converter = GSLReferenceConverter() - gsl_printer = UnitlessExpressionPrinter(gsl_converter) - # helper classes and objects - converter = NESTReferenceConverter(False) - unitless_pretty_printer = UnitlessExpressionPrinter(converter) - - namespace = dict() - - namespace['neuronName'] = neuron.get_name() - namespace['neuron'] = neuron - namespace['moduleName'] = FrontendConfiguration.get_module_name() - namespace['printer'] = NestPrinter(unitless_pretty_printer) - namespace['assignments'] = NestAssignmentsHelper() - namespace['names'] = NestNamesConverter() - namespace['declarations'] = NestDeclarationsHelper() - namespace['utils'] = ASTUtils() - namespace['idemPrinter'] = UnitlessExpressionPrinter() - namespace['outputEvent'] = namespace['printer'].print_output_event(neuron.get_body()) - namespace['is_spike_input'] = ASTUtils.is_spike_input(neuron.get_body()) - namespace['is_current_input'] = ASTUtils.is_current_input(neuron.get_body()) - namespace['odeTransformer'] = OdeTransformer() - namespace['printerGSL'] = gsl_printer - namespace['now'] = datetime.datetime.utcnow() - namespace['tracing'] = FrontendConfiguration.is_dev - - namespace['PredefinedUnits'] = pynestml.symbols.predefined_units.PredefinedUnits - namespace['UnitTypeSymbol'] = pynestml.symbols.unit_type_symbol.UnitTypeSymbol - namespace['SymbolKind'] = pynestml.symbols.symbol.SymbolKind - - namespace['initial_values'] = {} - namespace['uses_analytic_solver'] = neuron.get_name() in self.analytic_solver.keys() \ - and self.analytic_solver[neuron.get_name()] is not None - if namespace['uses_analytic_solver']: - namespace['analytic_state_variables'] = self.analytic_solver[neuron.get_name()]["state_variables"] - namespace['analytic_variable_symbols'] = {sym: neuron.get_equations_block().get_scope().resolve_to_symbol( - sym, SymbolKind.VARIABLE) for sym in namespace['analytic_state_variables']} - namespace['update_expressions'] = {} - for sym, expr in self.analytic_solver[neuron.get_name()]["initial_values"].items(): - namespace['initial_values'][sym] = expr - for sym in namespace['analytic_state_variables']: - expr_str = self.analytic_solver[neuron.get_name()]["update_expressions"][sym] - expr_ast = ModelParser.parse_expression(expr_str) - # pretend that update expressions are in "equations" block, which should always be present, as differential equations must have been defined to get here - expr_ast.update_scope(neuron.get_equations_blocks().get_scope()) - expr_ast.accept(ASTSymbolTableVisitor()) - namespace['update_expressions'][sym] = expr_ast - - namespace['propagators'] = self.analytic_solver[neuron.get_name()]["propagators"] - - # convert variables from ASTVariable instances to strings - _names = self.non_equations_state_variables[neuron.get_name()] - _names = [to_ode_toolbox_processed_name(var.get_complete_name()) for var in _names] - namespace['non_equations_state_variables'] = _names - - namespace['uses_numeric_solver'] = neuron.get_name() in self.analytic_solver.keys() \ - and self.numeric_solver[neuron.get_name()] is not None - if namespace['uses_numeric_solver']: - namespace['numeric_state_variables'] = self.numeric_solver[neuron.get_name()]["state_variables"] - namespace['numeric_variable_symbols'] = {sym: neuron.get_equations_block().get_scope().resolve_to_symbol( - sym, SymbolKind.VARIABLE) for sym in namespace['numeric_state_variables']} - assert not any([sym is None for sym in namespace['numeric_variable_symbols'].values()]) - namespace['numeric_update_expressions'] = {} - for sym, expr in self.numeric_solver[neuron.get_name()]["initial_values"].items(): - namespace['initial_values'][sym] = expr - for sym in namespace['numeric_state_variables']: - expr_str = self.numeric_solver[neuron.get_name()]["update_expressions"][sym] - expr_ast = ModelParser.parse_expression(expr_str) - # pretend that update expressions are in "equations" block, which should always be present, as differential equations must have been defined to get here - expr_ast.update_scope(neuron.get_equations_blocks().get_scope()) - expr_ast.accept(ASTSymbolTableVisitor()) - namespace['numeric_update_expressions'][sym] = expr_ast - - namespace['useGSL'] = namespace['uses_numeric_solver'] - namespace['names'] = GSLNamesConverter() - converter = NESTReferenceConverter(True) - unitless_pretty_printer = UnitlessExpressionPrinter(converter) - namespace['printer'] = NestPrinter(unitless_pretty_printer) - - namespace["spike_updates"] = neuron.spike_updates - - rng_visitor = ASTRandomNumberGeneratorVisitor() - neuron.accept(rng_visitor) - namespace['norm_rng'] = rng_visitor._norm_rng_is_used - - return namespace - - def ode_toolbox_analysis(self, neuron: ASTNeuron, kernel_buffers: Mapping[ASTKernel, ASTInputPort]): - """ - Prepare data for ODE-toolbox input format, invoke ODE-toolbox analysis via its API, and return the output. - """ - assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "only one equation block should be present" - - equations_block = neuron.get_equations_block() - - if len(equations_block.get_kernels()) == 0 and len(equations_block.get_ode_equations()) == 0: - # no equations defined -> no changes to the neuron - return None, None - - code, message = Messages.get_neuron_analyzed(neuron.get_name()) - Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO) - - parameters_block = neuron.get_parameter_blocks() - odetoolbox_indict = self.transform_ode_and_kernels_to_json(neuron, parameters_block, kernel_buffers) - odetoolbox_indict["options"] = {} - odetoolbox_indict["options"]["output_timestep_symbol"] = "__h" - solver_result = analysis(odetoolbox_indict, disable_stiffness_check=True, debug=FrontendConfiguration.logging_level == "DEBUG") - analytic_solver = None - analytic_solvers = [x for x in solver_result if x["solver"] == "analytical"] - assert len(analytic_solvers) <= 1, "More than one analytic solver not presently supported" - if len(analytic_solvers) > 0: - analytic_solver = analytic_solvers[0] - - # if numeric solver is required, generate a stepping function that includes each state variable - numeric_solver = None - numeric_solvers = [x for x in solver_result if x["solver"].startswith("numeric")] - if numeric_solvers: - solver_result = analysis(odetoolbox_indict, disable_stiffness_check=True, - disable_analytic_solver=True, debug=FrontendConfiguration.logging_level == "DEBUG") - numeric_solvers = [x for x in solver_result if x["solver"].startswith("numeric")] - assert len(numeric_solvers) <= 1, "More than one numeric solver not presently supported" - if len(numeric_solvers) > 0: - numeric_solver = numeric_solvers[0] - - return analytic_solver, numeric_solver - - def update_symbol_table(self, neuron, kernel_buffers): - """ - Update symbol table and scope. - """ - SymbolTable.delete_neuron_scope(neuron.get_name()) - symbol_table_visitor = ASTSymbolTableVisitor() - symbol_table_visitor.after_ast_rewrite_ = True - neuron.accept(symbol_table_visitor) - SymbolTable.add_neuron_scope(neuron.get_name(), neuron.get_scope()) - - def remove_initial_values_for_kernels(self, neuron): - """ - Remove initial values for original declarations (e.g. g_in, g_in', V_m); these might conflict with the initial value expressions returned from ODE-toolbox. - """ - assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "only one equation block should be present" - - equations_block = neuron.get_equations_block() - symbols_to_remove = set() - for kernel in equations_block.get_kernels(): - for kernel_var in kernel.get_variables(): - kernel_var_order = kernel_var.get_differential_order() - for order in range(kernel_var_order): - symbol_name = kernel_var.get_name() + "'" * order - symbol = equations_block.get_scope().resolve_to_symbol(symbol_name, SymbolKind.VARIABLE) - symbols_to_remove.add(symbol_name) - - decl_to_remove = set() - for symbol_name in symbols_to_remove: - for decl in neuron.get_initial_blocks().get_declarations(): - if len(decl.get_variables()) == 1: - if decl.get_variables()[0].get_name() == symbol_name: - decl_to_remove.add(decl) - else: - for var in decl.get_variables(): - if var.get_name() == symbol_name: - decl.variables.remove(var) - - for decl in decl_to_remove: - neuron.get_initial_blocks().get_declarations().remove(decl) - - def update_initial_values_for_odes(self, neuron, solver_dicts, kernels): - """ - Update initial values for original ODE declarations (e.g. g_in, V_m', g_ahp'') that are present in the model - before ODE-toolbox processing, with the formatted variable names and initial values returned by ODE-toolbox. - """ - assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "only one equation block should be present" - equations_block = neuron.get_equations_block() - - for iv_decl in neuron.get_initial_blocks().get_declarations(): - for var in iv_decl.get_variables(): - var_name = var.get_complete_name() - if is_ode_variable(var.get_name(), neuron): - assert variable_in_solver(to_ode_toolbox_processed_name(var_name), solver_dicts) - - # replace the left-hand side variable name by the ode-toolbox format - var.set_name(to_ode_toolbox_processed_name(var.get_complete_name())) - var.set_differential_order(0) - - # replace the defining expression by the ode-toolbox result - iv_expr = get_initial_value_from_ode_toolbox_result( - to_ode_toolbox_processed_name(var_name), solver_dicts) - assert iv_expr is not None - iv_expr = ModelParser.parse_expression(iv_expr) - iv_expr.update_scope(neuron.get_initial_blocks().get_scope()) - iv_decl.set_expression(iv_expr) - - def _get_ast_variable(self, neuron, var_name) -> Optional[ASTVariable]: - """ - Grab the ASTVariable corresponding to the initial value by this name - """ - for decl in neuron.get_initial_values_blocks().get_declarations(): - for var in decl.variables: - if var.get_name() == var_name: - return var - return None - - def create_initial_values_for_kernels(self, neuron, solver_dicts, kernels): - """ - Add the variables used in kernels from the ode-toolbox result dictionary as ODEs in NESTML AST - """ - for solver_dict in solver_dicts: - if solver_dict is None: - continue - for var_name in solver_dict["initial_values"].keys(): - if variable_in_kernels(var_name, kernels): - # original initial value expressions should have been removed to make place for ode-toolbox results - assert not declaration_in_initial_values(neuron, var_name) - - for solver_dict in solver_dicts: - if solver_dict is None: - continue - - for var_name, expr in solver_dict["initial_values"].items(): - # here, overwrite is allowed because initial values might be repeated between numeric and analytic solver - if variable_in_kernels(var_name, kernels): - expr = "0" # for kernels, "initial value" returned by ode-toolbox is actually the increment value; the actual initial value is assumed to be 0 - if not declaration_in_initial_values(neuron, var_name): - add_declaration_to_initial_values(neuron, var_name, expr) - - def create_initial_values_for_ode_toolbox_odes(self, neuron, solver_dicts, kernel_buffers, kernels): - """ - Add the variables used in ODEs from the ode-toolbox result dictionary as ODEs in NESTML AST. - """ - for solver_dict in solver_dicts: - if solver_dict is None: - continue - for var_name in solver_dict["initial_values"].keys(): - # original initial value expressions should have been removed to make place for ode-toolbox results - assert not declaration_in_initial_values(neuron, var_name) - - for solver_dict in solver_dicts: - if solver_dict is None: - continue - - for var_name, expr in solver_dict["initial_values"].items(): - # here, overwrite is allowed because initial values might be repeated between numeric and analytic solver - - if variable_in_kernels(var_name, kernels): - expr = "0" # for kernels, "initial value" returned by ode-toolbox is actually the increment value; the actual initial value is assumed to be 0 - - if not declaration_in_initial_values(neuron, var_name): - add_declaration_to_initial_values(neuron, var_name, expr) - - - def get_spike_update_expressions(self, neuron: ASTNeuron, kernel_buffers, solver_dicts, delta_factors) -> List[ASTAssignment]: - """ - Generate the equations that update the dynamical variables when incoming spikes arrive. To be invoked after ode-toolbox. - - For example, a resulting `assignment_str` could be "I_kernel_in += (in_spikes/nS) * 1". The values are taken from the initial values for each corresponding dynamical variable, either from ode-toolbox or directly from user specification in the model. - - Note that for kernels, `initial_values` actually contains the increment upon spike arrival, rather than the initial value of the corresponding ODE dimension. - """ - spike_updates = [] - initial_values = neuron.get_initial_values_blocks() - - for kernel, spike_input_port in kernel_buffers: - if neuron.get_scope().resolve_to_symbol(str(spike_input_port), SymbolKind.VARIABLE) is None: - continue - - buffer_type = neuron.get_scope().resolve_to_symbol(str(spike_input_port), SymbolKind.VARIABLE).get_type_symbol() - - if is_delta_kernel(kernel): - continue - - for kernel_var in kernel.get_variables(): - for var_order in range(get_kernel_var_order_from_ode_toolbox_result(kernel_var.get_name(), solver_dicts)): - kernel_spike_buf_name = construct_kernel_X_spike_buf_name( - kernel_var.get_name(), spike_input_port, var_order) - expr = get_initial_value_from_ode_toolbox_result(kernel_spike_buf_name, solver_dicts) - assert expr is not None, "Initial value not found for kernel " + kernel_var - expr = str(expr) - if expr in ["0", "0.", "0.0"]: - continue # skip adding the statement if we're only adding zero - - assignment_str = kernel_spike_buf_name + " += " - assignment_str += "(" + str(spike_input_port) + ")" - if not expr in ["1.", "1.0", "1"]: - assignment_str += " * (" + \ - self._printer.print_expression(ModelParser.parse_expression(expr)) + ")" - - if not buffer_type.print_nestml_type() in ["1.", "1.0", "1"]: - assignment_str += " / (" + buffer_type.print_nestml_type() + ")" - - ast_assignment = ModelParser.parse_assignment(assignment_str) - ast_assignment.update_scope(neuron.get_scope()) - ast_assignment.accept(ASTSymbolTableVisitor()) - - spike_updates.append(ast_assignment) - - for k, factor in delta_factors.items(): - var = k[0] - inport = k[1] - assignment_str = var.get_name() + "'" * (var.get_differential_order() - 1) + " += " - if not factor in ["1.", "1.0", "1"]: - assignment_str += "(" + self._printer.print_expression(ModelParser.parse_expression(factor)) + ") * " - assignment_str += str(inport) - ast_assignment = ModelParser.parse_assignment(assignment_str) - ast_assignment.update_scope(neuron.get_scope()) - ast_assignment.accept(ASTSymbolTableVisitor()) - - spike_updates.append(ast_assignment) - - return spike_updates - - def remove_kernel_definitions_from_equations_block(self, neuron): - """ - Removes all kernels in this block. - """ - equations_block = neuron.get_equations_block() - - decl_to_remove = set() - for decl in equations_block.get_declarations(): - if type(decl) is ASTKernel: - decl_to_remove.add(decl) - - for decl in decl_to_remove: - equations_block.get_declarations().remove(decl) - - return decl_to_remove - - def remove_ode_definitions_from_equations_block(self, neuron): - """ - Removes all ODEs in this block. - """ - equations_block = neuron.get_equations_block() - - decl_to_remove = set() - for decl in equations_block.get_ode_equations(): - decl_to_remove.add(decl) - - for decl in decl_to_remove: - equations_block.get_declarations().remove(decl) - - def transform_ode_and_kernels_to_json(self, neuron: ASTNeuron, parameters_block, kernel_buffers): - """ - Converts AST node to a JSON representation suitable for passing to ode-toolbox. - - Each kernel has to be generated for each spike buffer convolve in which it occurs, e.g. if the NESTML model code contains the statements - - convolve(G, ex_spikes) - convolve(G, in_spikes) - - then `kernel_buffers` will contain the pairs `(G, ex_spikes)` and `(G, in_spikes)`, from which two ODEs will be generated, with dynamical state (variable) names `G__X__ex_spikes` and `G__X__in_spikes`. - - :param equations_block: ASTEquationsBlock - :return: Dict - """ - odetoolbox_indict = {} - - gsl_converter = ODEToolboxReferenceConverter() - gsl_printer = UnitlessExpressionPrinter(gsl_converter) - - odetoolbox_indict["dynamics"] = [] - equations_block = neuron.get_equations_block() - for equation in equations_block.get_ode_equations(): - # n.b. includes single quotation marks to indicate differential order - lhs = to_ode_toolbox_name(equation.get_lhs().get_complete_name()) - rhs = gsl_printer.print_expression(equation.get_rhs()) - entry = {"expression": lhs + " = " + rhs} - symbol_name = equation.get_lhs().get_name() - symbol = equations_block.get_scope().resolve_to_symbol(symbol_name, SymbolKind.VARIABLE) - - entry["initial_values"] = {} - symbol_order = equation.get_lhs().get_differential_order() - for order in range(symbol_order): - iv_symbol_name = symbol_name + "'" * order - initial_value_expr = neuron.get_initial_value(iv_symbol_name) - if initial_value_expr: - expr = gsl_printer.print_expression(initial_value_expr) - entry["initial_values"][to_ode_toolbox_name(iv_symbol_name)] = expr - odetoolbox_indict["dynamics"].append(entry) - - # write a copy for each (kernel, spike buffer) combination - for kernel, spike_input_port in kernel_buffers: - - if is_delta_kernel(kernel): - # delta function -- skip passing this to ode-toolbox - continue - - for kernel_var in kernel.get_variables(): - expr = get_expr_from_kernel_var(kernel, kernel_var.get_complete_name()) - kernel_order = kernel_var.get_differential_order() - kernel_X_spike_buf_name_ticks = construct_kernel_X_spike_buf_name( - kernel_var.get_name(), spike_input_port, kernel_order, diff_order_symbol="'") - - replace_rhs_variables(expr, kernel_buffers) - - entry = {} - entry["expression"] = kernel_X_spike_buf_name_ticks + " = " + str(expr) - - # initial values need to be declared for order 1 up to kernel order (e.g. none for kernel function f(t) = ...; 1 for kernel ODE f'(t) = ...; 2 for f''(t) = ... and so on) - entry["initial_values"] = {} - for order in range(kernel_order): - iv_sym_name_ode_toolbox = construct_kernel_X_spike_buf_name( - kernel_var.get_name(), spike_input_port, order, diff_order_symbol="'") - symbol_name_ = kernel_var.get_name() + "'" * order - symbol = equations_block.get_scope().resolve_to_symbol(symbol_name_, SymbolKind.VARIABLE) - assert symbol is not None, "Could not find initial value for variable " + symbol_name_ - initial_value_expr = symbol.get_declaring_expression() - assert initial_value_expr is not None, "No initial value found for variable name " + symbol_name_ - entry["initial_values"][iv_sym_name_ode_toolbox] = gsl_printer.print_expression(initial_value_expr) - - odetoolbox_indict["dynamics"].append(entry) - - odetoolbox_indict["parameters"] = {} - if parameters_block is not None: - for decl in parameters_block.get_declarations(): - for var in decl.variables: - odetoolbox_indict["parameters"][var.get_complete_name( - )] = gsl_printer.print_expression(decl.get_expression()) - - return odetoolbox_indict - - def make_inline_expressions_self_contained(self, inline_expressions: List[ASTInlineExpression]) -> List[ASTInlineExpression]: - """ - Make inline_expressions self contained, i.e. without any references to other inline_expressions. - - TODO: it should be a method inside of the ASTInlineExpression - TODO: this should be done by means of a visitor - - :param inline_expressions: A sorted list with entries ASTInlineExpression. - :return: A list with ASTInlineExpressions. Defining expressions don't depend on each other. - """ - for source in inline_expressions: - source_position = source.get_source_position() - for target in inline_expressions: - matcher = re.compile(self._variable_matching_template.format(source.get_variable_name())) - target_definition = str(target.get_expression()) - target_definition = re.sub(matcher, "(" + str(source.get_expression()) + ")", target_definition) - target.expression = ModelParser.parse_expression(target_definition) - target.expression.update_scope(source.get_scope()) - target.expression.accept(ASTSymbolTableVisitor()) - - def log_set_source_position(node): - if node.get_source_position().is_added_source_position(): - node.set_source_position(source_position) - - target.expression.accept(ASTHigherOrderVisitor(visit_funcs=log_set_source_position)) - - return inline_expressions - - def replace_inline_expressions_through_defining_expressions(self, definitions, inline_expressions): - # type: (list(ASTOdeEquation), list(ASTInlineExpression)) -> list(ASTInlineExpression) - """ - Replaces symbols from `inline_expressions` in `definitions` with corresponding defining expressions from `inline_expressions`. - - :param definitions: A sorted list with entries {"symbol": "name", "definition": "expression"} that should be made free from. - :param inline_expressions: A sorted list with entries {"symbol": "name", "definition": "expression"} with inline_expressions which must be replaced in `definitions`. - :return: A list with definitions. Expressions in `definitions` don't depend on inline_expressions from `inline_expressions`. - """ - for m in inline_expressions: - source_position = m.get_source_position() - for target in definitions: - matcher = re.compile(self._variable_matching_template.format(m.get_variable_name())) - target_definition = str(target.get_rhs()) - target_definition = re.sub(matcher, "(" + str(m.get_expression()) + ")", target_definition) - target.rhs = ModelParser.parse_expression(target_definition) - target.update_scope(m.get_scope()) - target.accept(ASTSymbolTableVisitor()) - - def log_set_source_position(node): - if node.get_source_position().is_added_source_position(): - node.set_source_position(source_position) - - target.accept(ASTHigherOrderVisitor(visit_funcs=log_set_source_position)) - - return definitions - - def store_transformed_model(self, ast): - if FrontendConfiguration.store_log: - with open(str(os.path.join(FrontendConfiguration.get_target_path(), '..', 'report', - ast.get_name())) + '.txt', 'w+') as f: - f.write(str(ast)) diff --git a/pynestml/codegeneration/nest_compartmental_code_generator.py b/pynestml/codegeneration/nest_compartmental_code_generator.py new file mode 100644 index 000000000..1110be112 --- /dev/null +++ b/pynestml/codegeneration/nest_compartmental_code_generator.py @@ -0,0 +1,925 @@ +# -*- coding: utf-8 -*- +# +# nest_compartmental_code_generator.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import datetime +import glob +import os + +from typing import Any, Dict, List, Mapping, Optional + +from jinja2 import Environment, FileSystemLoader, TemplateRuntimeError, Template +from odetoolbox import analysis +import pynestml +from pynestml.codegeneration.code_generator import CodeGenerator +from pynestml.codegeneration.nest_assignments_helper import NestAssignmentsHelper +from pynestml.codegeneration.nest_declarations_helper import NestDeclarationsHelper +from pynestml.codegeneration.printers.cpp_expression_printer import CppExpressionPrinter +from pynestml.codegeneration.printers.cpp_types_printer import CppTypesPrinter +from pynestml.codegeneration.printers.gsl_reference_converter import GSLReferenceConverter +from pynestml.codegeneration.printers.nest_local_variables_reference_converter import NESTLocalVariablesReferenceConverter +from pynestml.codegeneration.printers.unitless_expression_printer import UnitlessExpressionPrinter +from pynestml.codegeneration.printers.nest_printer import NestPrinter +from pynestml.codegeneration.printers.nest_reference_converter import NESTReferenceConverter +from pynestml.codegeneration.printers.ode_toolbox_reference_converter import ODEToolboxReferenceConverter +from pynestml.exceptions.invalid_path_exception import InvalidPathException +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_assignment import ASTAssignment +from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.meta_model.ast_input_port import ASTInputPort +from pynestml.meta_model.ast_kernel import ASTKernel +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.ast_channel_information_collector import ASTChannelInformationCollector +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.chan_info_enricher import ChanInfoEnricher +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.utils.model_parser import ModelParser +from pynestml.utils.syns_info_enricher import SynsInfoEnricher +from pynestml.utils.syns_processing import SynsProcessing +from pynestml.visitors.ast_random_number_generator_visitor import ASTRandomNumberGeneratorVisitor +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + + +class NESTCompartmentalCodeGenerator(CodeGenerator): + r""" + Code generator for a C++ NEST extension module. + + Options: + - **neuron_parent_class**: The C++ class from which the generated NESTML neuron class inherits. Examples: ``"ArchivingNode"``, ``"StructuralPlasticityNode"``. Default: ``"ArchivingNode"``. + - **neuron_parent_class_include**: The C++ header filename to include that contains **neuron_parent_class**. Default: ``"archiving_node.h"``. + - **preserve_expressions**: Set to True, or a list of strings corresponding to individual variable names, to disable internal rewriting of expressions, and return same output as input expression where possible. Only applies to variables specified as first-order differential equations. (This parameter is passed to ODE-toolbox.) + - **simplify_expression**: For all expressions ``expr`` that are rewritten by ODE-toolbox: the contents of this parameter string are ``eval()``ed in Python to obtain the final output expression. Override for custom expression simplification steps. Example: ``sympy.simplify(expr)``. Default: ``"sympy.logcombine(sympy.powsimp(sympy.expand(expr)))"``. (This parameter is passed to ODE-toolbox.) + - **templates**: Path containing jinja templates used to generate code for NEST simulator. + - **path**: Path containing jinja templates used to generate code for NEST simulator. + - **model_templates**: A list of the jinja templates or a relative path to a directory containing the templates related to the neuron model(s). + - **module_templates**: A list of the jinja templates or a relative path to a directory containing the templates related to generating the NEST module. + - **nest_version**: A string identifying the version of NEST Simulator to generate code for. The string corresponds to the NEST Simulator git repository tag or git branch name, for instance, ``"v2.20.2"`` or ``"master"``. The default is the empty string, which causes the NEST version to be automatically identified from the ``nest`` Python module. + """ + + _default_options = { + "neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h", + "preserve_expressions": False, + "simplify_expression": "sympy.logcombine(sympy.powsimp(sympy.expand(expr)))", + "templates": { + "path": "cm_neuron", + "model_templates": { + "neuron": [ + "cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2", + "cm_compartmentcurrents_@NEURON_NAME@.h.jinja2", + "@NEURON_NAME@.cpp.jinja2", + "@NEURON_NAME@.h.jinja2", + "cm_tree_@NEURON_NAME@.cpp.jinja2", + "cm_tree_@NEURON_NAME@.h.jinja2"]}, + "module_templates": ["setup"]}, + "nest_version": ""} + + _variable_matching_template = r"(\b)({})(\b)" + _model_templates = dict() + _module_templates = list() + + def __init__(self, options: Optional[Mapping[str, Any]] = None): + super().__init__("NEST_COMPARTMENTAL", options) + + # auto-detect NEST Simulator installed version + if not self.option_exists("nest_version") or not self.get_option("nest_version"): + from pynestml.codegeneration.nest_tools import NESTTools + nest_version = NESTTools.detect_nest_version() + self.set_options({"nest_version": nest_version}) + + self.analytic_solver = {} + self.numeric_solver = {} + # those state variables not defined as an ODE in the equations block + self.non_equations_state_variables = {} + + self.setup_template_env() + + self._types_printer = CppTypesPrinter() + self._gsl_reference_converter = GSLReferenceConverter() + self._nest_reference_converter = NESTReferenceConverter() + + self._printer = CppExpressionPrinter(self._nest_reference_converter) + self._unitless_expression_printer = UnitlessExpressionPrinter( + self._nest_reference_converter) + self._gsl_printer = UnitlessExpressionPrinter( + reference_converter=self._gsl_reference_converter) + + self._nest_printer = NestPrinter( + reference_converter=self._nest_reference_converter, + types_printer=self._types_printer, + expression_printer=self._printer) + + self._unitless_nest_gsl_printer = NestPrinter( + reference_converter=self._nest_reference_converter, + types_printer=self._types_printer, + expression_printer=self._unitless_expression_printer) + + self._local_variables_reference_converter = NESTLocalVariablesReferenceConverter() + self._unitless_local_variables_expression_printer = UnitlessExpressionPrinter( + self._local_variables_reference_converter) + self._unitless_local_variables_nest_gsl_printer = NestPrinter( + reference_converter=self._local_variables_reference_converter, + types_printer=self._types_printer, + expression_printer=self._unitless_local_variables_expression_printer) + + self._ode_toolbox_printer = UnitlessExpressionPrinter( + ODEToolboxReferenceConverter()) + + # maps kernel names to their analytic solutions separately + # this is needed needed for the cm_syns case + self.kernel_name_to_analytic_solver = {} + + def raise_helper(self, msg): + raise TemplateRuntimeError(msg) + + def set_options(self, options: Mapping[str, Any]) -> Mapping[str, Any]: + ret = super().set_options(options) + self.setup_template_env() + + return ret + + def generate_code( + self, + neurons: List[ASTNeuron], + synapses: List[ASTSynapse] = None) -> None: + self.analyse_transform_neurons(neurons) + self.generate_neurons(neurons) + self.generate_module_code(neurons) + + def generate_module_code(self, neurons: List[ASTNeuron]) -> None: + """t + Generates code that is necessary to integrate neuron models into the NEST infrastructure. + :param neurons: a list of neurons + :type neurons: list(ASTNeuron) + """ + namespace = self._get_module_namespace(neurons) + if not os.path.exists(FrontendConfiguration.get_target_path()): + os.makedirs(FrontendConfiguration.get_target_path()) + + for _module_templ in self._module_templates: + file_name_parts = os.path.basename( + _module_templ.filename).split(".") + assert len( + file_name_parts) >= 3, "Template file name should be in the format: ``..jinja2``" + file_extension = file_name_parts[-2] + if file_extension in ["cpp", "h"]: + filename = FrontendConfiguration.get_module_name() + else: + filename = file_name_parts[0] + + file_path = str(os.path.join( + FrontendConfiguration.get_target_path(), filename)) + with open(file_path + "." + file_extension, "w+") as f: + f.write(str(_module_templ.render(namespace))) + + code, message = Messages.get_module_generated( + FrontendConfiguration.get_target_path()) + Logger.log_message(None, code, message, None, LoggingLevel.INFO) + + def _get_module_namespace(self, neurons: List[ASTNeuron]) -> Dict: + """ + Creates a namespace for generating NEST extension module code + :param neurons: List of neurons + :return: a context dictionary for rendering templates + """ + namespace = {"neurons": neurons, + "moduleName": FrontendConfiguration.get_module_name(), + "now": datetime.datetime.utcnow()} + + # auto-detect NEST Simulator installed version + if not self.option_exists("nest_version") or not self.get_option("nest_version"): + from pynestml.codegeneration.nest_tools import NESTTools + nest_version = NESTTools.detect_nest_version() + self.set_options({"nest_version": nest_version}) + + # neuron specific file names in compartmental case + neuron_name_to_filename = dict() + for neuron in neurons: + neuron_name_to_filename[neuron.get_name()] = { + "compartmentcurrents": self.get_cm_syns_compartmentcurrents_file_prefix(neuron), + "main": self.get_cm_syns_main_file_prefix(neuron), + "tree": self.get_cm_syns_tree_file_prefix(neuron) + } + namespace["perNeuronFileNamesCm"] = neuron_name_to_filename + + # compartmental case files that are not neuron specific - currently + # empty + namespace["sharedFileNamesCmSyns"] = { + } + + return namespace + + def get_cm_syns_compartmentcurrents_file_prefix(self, neuron): + return "cm_compartmentcurrents_" + neuron.get_name() + + def get_cm_syns_main_file_prefix(self, neuron): + return neuron.get_name() + + def get_cm_syns_tree_file_prefix(self, neuron): + return "cm_tree_" + neuron.get_name() + + def analyse_transform_neurons(self, neurons: List[ASTNeuron]) -> None: + """ + Analyse and transform a list of neurons. + :param neurons: a list of neurons. + """ + for neuron in neurons: + code, message = Messages.get_analysing_transforming_neuron( + neuron.get_name()) + Logger.log_message(None, code, message, None, LoggingLevel.INFO) + spike_updates = self.analyse_neuron(neuron) + neuron.spike_updates = spike_updates + + def create_ode_indict(self, + neuron: ASTNeuron, + parameters_block: ASTBlockWithVariables, + kernel_buffers: Mapping[ASTKernel, + ASTInputPort]): + odetoolbox_indict = self.transform_ode_and_kernels_to_json( + neuron, parameters_block, kernel_buffers) + odetoolbox_indict["options"] = {} + odetoolbox_indict["options"]["output_timestep_symbol"] = "__h" + return odetoolbox_indict + + def ode_solve_analytically(self, + neuron: ASTNeuron, + parameters_block: ASTBlockWithVariables, + kernel_buffers: Mapping[ASTKernel, + ASTInputPort]): + odetoolbox_indict = self.create_ode_indict( + neuron, parameters_block, kernel_buffers) + full_solver_result = analysis( + odetoolbox_indict, + disable_stiffness_check=True, + preserve_expressions=self.get_option("preserve_expressions"), + simplify_expression=self.get_option("simplify_expression"), + log_level=FrontendConfiguration.logging_level) + analytic_solver = None + analytic_solvers = [ + x for x in full_solver_result if x["solver"] == "analytical"] + assert len( + analytic_solvers) <= 1, "More than one analytic solver not presently supported" + if len(analytic_solvers) > 0: + analytic_solver = analytic_solvers[0] + + return full_solver_result, analytic_solver + + def ode_toolbox_anaysis_cm_syns( + self, neuron: ASTNeuron, kernel_buffers: Mapping[ASTKernel, ASTInputPort]): + """ + Prepare data for ODE-toolbox input format, invoke ODE-toolbox analysis via its API, and return the output. + """ + assert isinstance(neuron.get_equations_blocks( + ), ASTEquationsBlock), "only one equation block should be present" + + equations_block = neuron.get_equations_block() + + if len(equations_block.get_kernels()) == 0 and len( + equations_block.get_ode_equations()) == 0: + # no equations defined -> no changes to the neuron + return None, None + + parameters_block = neuron.get_parameter_blocks() + + kernel_name_to_analytic_solver = dict() + for kernel_buffer in kernel_buffers: + _, analytic_result = self.ode_solve_analytically( + neuron, parameters_block, set([tuple(kernel_buffer)])) + kernel_name = kernel_buffer[0].get_variables()[0].get_name() + kernel_name_to_analytic_solver[kernel_name] = analytic_result + + return kernel_name_to_analytic_solver + + def ode_toolbox_analysis(self, neuron: ASTNeuron, + kernel_buffers: Mapping[ASTKernel, ASTInputPort]): + """ + Prepare data for ODE-toolbox input format, invoke ODE-toolbox analysis via its API, and return the output. + """ + assert isinstance(neuron.get_equations_blocks( + ), ASTEquationsBlock), "only one equation block should be present" + + equations_block = neuron.get_equations_block() + + if len(equations_block.get_kernels()) == 0 and len( + equations_block.get_ode_equations()) == 0: + # no equations defined -> no changes to the neuron + return None, None + + parameters_block = neuron.get_parameter_blocks() + + solver_result, analytic_solver = self.ode_solve_analytically( + neuron, parameters_block, kernel_buffers) + + # if numeric solver is required, generate a stepping function that + # includes each state variable + numeric_solver = None + numeric_solvers = [ + x for x in solver_result if x["solver"].startswith("numeric")] + + if numeric_solvers: + odetoolbox_indict = self.create_ode_indict( + neuron, parameters_block, kernel_buffers) + solver_result = analysis( + odetoolbox_indict, + disable_stiffness_check=True, + disable_analytic_solver=True, + preserve_expressions=self.get_option("preserve_expressions"), + simplify_expression=self.get_option("simplify_expression"), + log_level=FrontendConfiguration.logging_level) + numeric_solvers = [ + x for x in solver_result if x["solver"].startswith("numeric")] + assert len( + numeric_solvers) <= 1, "More than one numeric solver not presently supported" + if len(numeric_solvers) > 0: + numeric_solver = numeric_solvers[0] + + return analytic_solver, numeric_solver + + def find_non_equations_state_variables(self, neuron: ASTNeuron): + non_equations_state_variables = [] + for decl in neuron.get_state_blocks().get_declarations(): + for var in decl.get_variables(): + # check if this variable is not in equations + + # if there is no equations, all variables are not in equations + if not neuron.get_equations_blocks(): + non_equations_state_variables.append(var) + continue + + # check if equation name is also a state variable + used_in_eq = False + for ode_eq in neuron.get_equations_blocks().get_ode_equations(): + if ode_eq.get_lhs().get_name() == var.get_name(): + used_in_eq = True + break + + # check for any state variables being used by a kernel + for kern in neuron.get_equations_blocks().get_kernels(): + for kern_var in kern.get_variables(): + if kern_var.get_name() == var.get_name(): + used_in_eq = True + break + + # if no usage found at this point, we have a non-equation state + # variable + if not used_in_eq: + non_equations_state_variables.append(var) + return non_equations_state_variables + + def analyse_neuron(self, neuron: ASTNeuron) -> List[ASTAssignment]: + """ + Analyse and transform a single neuron. + :param neuron: a single neuron. + :return: spike_updates: list of spike updates, see documentation for get_spike_update_expressions() for more information. + """ + code, message = Messages.get_start_processing_model(neuron.get_name()) + Logger.log_message(neuron, code, message, + neuron.get_source_position(), LoggingLevel.INFO) + + equations_block = neuron.get_equations_block() + + if equations_block is None: + # add all declared state variables as none of them are used in + # equations block + self.non_equations_state_variables[neuron.get_name()] = [] + self.non_equations_state_variables[neuron.get_name()].extend( + ASTUtils.all_variables_defined_in_block(neuron.get_state_blocks())) + + return [] + + # goes through all convolve() inside ode's from equations block + # if they have delta kernels, use sympy to expand the expression, then + # find the convolve calls and replace them with constant value 1 + # then return every subexpression that had that convolve() replaced + delta_factors = ASTUtils.get_delta_factors_(neuron, equations_block) + + # goes through all convolve() inside equations block + # extracts what kernel is paired with what spike buffer + # returns pairs (kernel, spike_buffer) + kernel_buffers = ASTUtils.generate_kernel_buffers_( + neuron, equations_block) + + # replace convolve(g_E, spikes_exc) with g_E__X__spikes_exc[__d] + # done by searching for every ASTSimpleExpression inside equations_block + # which is a convolve call and substituting that call with + # newly created ASTVariable kernel__X__spike_buffer + ASTUtils.replace_convolve_calls_with_buffers_(neuron, equations_block) + + # substitute inline expressions with each other + # such that no inline expression references another inline expression + ASTUtils.make_inline_expressions_self_contained( + equations_block.get_inline_expressions()) + + # dereference inline_expressions inside ode equations + ASTUtils.replace_inline_expressions_through_defining_expressions( + equations_block.get_ode_equations(), equations_block.get_inline_expressions()) + + # generate update expressions using ode toolbox + # for each equation in the equation block attempt to solve analytically + # then attempt to solve numerically + # "update_expressions" key in those solvers contains a mapping + # {expression1: update_expression1, expression2: update_expression2} + analytic_solver, numeric_solver = self.ode_toolbox_analysis( + neuron, kernel_buffers) + + # separate analytic solutions by kernel + # this is is needed for the synaptic case + self.kernel_name_to_analytic_solver[neuron.get_name( + )] = self.ode_toolbox_anaysis_cm_syns(neuron, kernel_buffers) + self.analytic_solver[neuron.get_name()] = analytic_solver + self.numeric_solver[neuron.get_name()] = numeric_solver + + # get all variables from state block that are not found in equations + self.non_equations_state_variables[neuron.get_name()] = \ + self.find_non_equations_state_variables(neuron) + + # gather all variables used by kernels and delete their declarations + # they will be inserted later again, but this time with values redefined + # by odetoolbox, higher order variables don't get deleted here + ASTUtils.remove_initial_values_for_kernels(neuron) + + # delete all kernels as they are all converted into buffers + # and corresponding update formulas calculated by odetoolbox + # Remember them in a variable though + kernels = ASTUtils.remove_kernel_definitions_from_equations_block( + neuron) + + # Every ODE variable (a variable of order > 0) is renamed according to ODE-toolbox conventions + # their initial values are replaced by expressions suggested by ODE-toolbox. + # Differential order can now be set to 0, becase they can directly represent the value of the derivative now. + # initial value can be the same value as the originally stated one but + # it doesn't have to be + ASTUtils.update_initial_values_for_odes( + neuron, [analytic_solver, numeric_solver]) + + # remove differential equations from equations block + # those are now resolved into zero order variables and their + # corresponding updates + ASTUtils.remove_ode_definitions_from_equations_block(neuron) + + # restore state variables that were referenced by kernels + # and set their initial values by those suggested by ODE-toolbox + ASTUtils.create_initial_values_for_kernels( + neuron, [analytic_solver, numeric_solver], kernels) + + # Inside all remaining expressions, translate all remaining variable names + # according to the naming conventions of ODE-toolbox. + ASTUtils.replace_variable_names_in_expressions( + neuron, [analytic_solver, numeric_solver]) + + # find all inline kernels defined as ASTSimpleExpression + # that have a single kernel convolution aliasing variable ('__X__') + # translate all remaining variable names according to the naming + # conventions of ODE-toolbox + ASTUtils.replace_convolution_aliasing_inlines(neuron) + + # add variable __h to internals block + ASTUtils.add_timestep_symbol(neuron) + + # add propagator variables calculated by odetoolbox into internal + # blocks + if self.analytic_solver[neuron.get_name()] is not None: + neuron = ASTUtils.add_declarations_to_internals( + neuron, self.analytic_solver[neuron.get_name()]["propagators"]) + + # generate how to calculate the next spike update + self.update_symbol_table(neuron, kernel_buffers) + # find any spike update expressions defined by the user + spike_updates = self.get_spike_update_expressions( + neuron, kernel_buffers, [analytic_solver, numeric_solver], delta_factors) + + return spike_updates + + def compute_name_of_generated_file(self, jinja_file_name, neuron): + file_name_no_extension = os.path.basename( + jinja_file_name).split(".")[0] + + file_name_calculators = { + "CompartmentCurrents": self.get_cm_syns_compartmentcurrents_file_prefix, + "Tree": self.get_cm_syns_tree_file_prefix, + "Main": self.get_cm_syns_main_file_prefix, + } + + def compute_prefix(file_name): + for indication, file_prefix_calculator in file_name_calculators.items(): + if file_name.lower().startswith(indication.lower()): + return file_prefix_calculator(neuron) + return file_name_no_extension.lower() + "_" + neuron.get_name() + + file_extension = "" + if file_name_no_extension.lower().endswith("class"): + file_extension = "cpp" + elif file_name_no_extension.lower().endswith("header"): + file_extension = "h" + else: + file_extension = "unknown" + + return str( + os.path.join( + FrontendConfiguration.get_target_path(), + compute_prefix(file_name_no_extension))) + "." + file_extension + + def getUniqueSuffix(self, neuron: ASTNeuron): + ret = neuron.get_name().capitalize() + underscore_pos = ret.find("_") + while underscore_pos != -1: + ret = ret[:underscore_pos] + ret[underscore_pos + 1:].capitalize() + underscore_pos = ret.find("_") + return ret + + def _get_neuron_model_namespace(self, neuron: ASTNeuron) -> Dict: + """ + Returns a standard namespace for generating neuron code for NEST + :param neuron: a single neuron instance + :return: a context dictionary for rendering templates + :rtype: dict + """ + namespace = dict() + + namespace["nest_version"] = self.get_option("nest_version") + + namespace["neuronName"] = neuron.get_name() + namespace["neuron"] = neuron + namespace["moduleName"] = FrontendConfiguration.get_module_name() + namespace["printer"] = self._unitless_nest_gsl_printer + namespace["local_variables_printer"] = self._unitless_local_variables_nest_gsl_printer + namespace["nest_printer"] = self._nest_printer + namespace["assignments"] = NestAssignmentsHelper() + namespace["names"] = self._nest_reference_converter + namespace["declarations"] = NestDeclarationsHelper(self._types_printer) + namespace["utils"] = ASTUtils + namespace["idemPrinter"] = self._printer + namespace["outputEvent"] = namespace["printer"].print_output_event( + neuron.get_body()) + namespace["has_spike_input"] = ASTUtils.has_spike_input( + neuron.get_body()) + namespace["has_continuous_input"] = ASTUtils.has_continuous_input( + neuron.get_body()) + namespace["printerGSL"] = self._gsl_printer + namespace["now"] = datetime.datetime.utcnow() + namespace["tracing"] = FrontendConfiguration.is_dev + + namespace["neuron_parent_class"] = self.get_option( + "neuron_parent_class") + namespace["neuron_parent_class_include"] = self.get_option( + "neuron_parent_class_include") + + namespace["PredefinedUnits"] = pynestml.symbols.predefined_units.PredefinedUnits + namespace["UnitTypeSymbol"] = pynestml.symbols.unit_type_symbol.UnitTypeSymbol + namespace["SymbolKind"] = pynestml.symbols.symbol.SymbolKind + + namespace["initial_values"] = {} + namespace["uses_analytic_solver"] = neuron.get_name() in self.analytic_solver.keys( + ) and self.analytic_solver[neuron.get_name()] is not None + if namespace["uses_analytic_solver"]: + namespace["analytic_state_variables"] = self.analytic_solver[neuron.get_name( + )]["state_variables"] + namespace["analytic_variable_symbols"] = { + sym: neuron.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["analytic_state_variables"]} + namespace["update_expressions"] = {} + for sym, expr in self.analytic_solver[neuron.get_name( + )]["initial_values"].items(): + namespace["initial_values"][sym] = expr + for sym in namespace["analytic_state_variables"]: + expr_str = self.analytic_solver[neuron.get_name( + )]["update_expressions"][sym] + expr_ast = ModelParser.parse_expression(expr_str) + # pretend that update expressions are in "equations" block, + # which should always be present, as differential equations + # must have been defined to get here + expr_ast.update_scope( + neuron.get_equations_blocks().get_scope()) + expr_ast.accept(ASTSymbolTableVisitor()) + namespace["update_expressions"][sym] = expr_ast + + namespace["propagators"] = self.analytic_solver[neuron.get_name() + ]["propagators"] + + # convert variables from ASTVariable instances to strings + _names = self.non_equations_state_variables[neuron.get_name()] + _names = [ASTUtils.to_ode_toolbox_processed_name( + var.get_complete_name()) for var in _names] + namespace["non_equations_state_variables"] = _names + + namespace["uses_numeric_solver"] = neuron.get_name() in self.numeric_solver.keys( + ) and self.numeric_solver[neuron.get_name()] is not None + if namespace["uses_numeric_solver"]: + namespace["numeric_state_variables"] = self.numeric_solver[neuron.get_name( + )]["state_variables"] + namespace["numeric_variable_symbols"] = { + sym: neuron.get_equations_block().get_scope().resolve_to_symbol( + sym, SymbolKind.VARIABLE) for sym in namespace["numeric_state_variables"]} + assert not any( + [sym is None for sym in namespace["numeric_variable_symbols"].values()]) + namespace["numeric_update_expressions"] = {} + for sym, expr in self.numeric_solver[neuron.get_name( + )]["initial_values"].items(): + namespace["initial_values"][sym] = expr + for sym in namespace["numeric_state_variables"]: + expr_str = self.numeric_solver[neuron.get_name( + )]["update_expressions"][sym] + expr_ast = ModelParser.parse_expression(expr_str) + # pretend that update expressions are in "equations" block, + # which should always be present, as differential equations + # must have been defined to get here + expr_ast.update_scope( + neuron.get_equations_blocks().get_scope()) + expr_ast.accept(ASTSymbolTableVisitor()) + namespace["numeric_update_expressions"][sym] = expr_ast + + namespace["useGSL"] = namespace["uses_numeric_solver"] + namespace["names"] = self._gsl_reference_converter + namespace["spike_updates"] = neuron.spike_updates + + namespace["recordable_state_variables"] = [ + sym for sym in neuron.get_state_symbols() if namespace["declarations"].get_domain_from_type( + sym.get_type_symbol()) == "double" and sym.is_recordable and not ASTUtils.is_delta_kernel( + neuron.get_kernel_by_name( + sym.name))] + namespace["recordable_inline_expressions"] = [ + sym for sym in neuron.get_inline_expression_symbols() if namespace["declarations"].get_domain_from_type( + sym.get_type_symbol()) == "double" and sym.is_recordable] + + # parameter symbols with initial values + namespace["parameter_syms_with_iv"] = [sym for sym in neuron.get_parameter_symbols( + ) if sym.has_declaring_expression() and (not neuron.get_kernel_by_name(sym.name))] + + rng_visitor = ASTRandomNumberGeneratorVisitor() + neuron.accept(rng_visitor) + namespace["norm_rng"] = rng_visitor._norm_rng_is_used + + namespace["cm_unique_suffix"] = self.getUniqueSuffix(neuron) + namespace["chan_info"] = ASTChannelInformationCollector.get_chan_info( + neuron) + namespace["chan_info"] = ChanInfoEnricher.enrich_with_additional_info( + neuron, namespace["chan_info"]) + + namespace["syns_info"] = SynsProcessing.get_syns_info(neuron) + syns_info_enricher = SynsInfoEnricher(neuron) + namespace["syns_info"] = syns_info_enricher.enrich_with_additional_info( + neuron, namespace["syns_info"], self.kernel_name_to_analytic_solver) + + # maybe log this on DEBUG? + # print("syns_info: ") + # syns_info_enricher.prettyPrint(namespace['syns_info']) + # print("chan_info: ") + # syns_info_enricher.prettyPrint(namespace['chan_info']) + + neuron_specific_filenames = { + "compartmentcurrents": self.get_cm_syns_compartmentcurrents_file_prefix(neuron), + "main": self.get_cm_syns_main_file_prefix(neuron), + "tree": self.get_cm_syns_tree_file_prefix(neuron)} + + namespace["neuronSpecificFileNamesCmSyns"] = neuron_specific_filenames + + # there is no shared files any more + namespace["sharedFileNamesCmSyns"] = { + } + + namespace["types_printer"] = self._types_printer + + return namespace + + def update_symbol_table(self, neuron, kernel_buffers): + """ + Update symbol table and scope. + """ + SymbolTable.delete_neuron_scope(neuron.get_name()) + symbol_table_visitor = ASTSymbolTableVisitor() + symbol_table_visitor.after_ast_rewrite_ = True + neuron.accept(symbol_table_visitor) + SymbolTable.add_neuron_scope(neuron.get_name(), neuron.get_scope()) + + def _get_ast_variable(self, neuron, var_name) -> Optional[ASTVariable]: + """ + Grab the ASTVariable corresponding to the initial value by this name + """ + for decl in neuron.get_state_blocks().get_declarations(): + for var in decl.variables: + if var.get_name() == var_name: + return var + return None + + def create_initial_values_for_ode_toolbox_odes( + self, neuron, solver_dicts, kernel_buffers, kernels): + """ + Add the variables used in ODEs from the ode-toolbox result dictionary as ODEs in NESTML AST. + """ + for solver_dict in solver_dicts: + if solver_dict is None: + continue + for var_name in solver_dict["initial_values"].keys(): + # original initial value expressions should have been removed + # to make place for ode-toolbox results + assert not ASTUtils.declaration_in_state_block( + neuron, var_name) + + for solver_dict in solver_dicts: + if solver_dict is None: + continue + + for var_name, expr in solver_dict["initial_values"].items(): + # here, overwrite is allowed because initial values might be + # repeated between numeric and analytic solver + + if ASTUtils.variable_in_kernels(var_name, kernels): + expr = "0" # for kernels, "initial value" returned by ode-toolbox is actually the increment value; the actual initial value is assumed to be 0 + + if not ASTUtils.declaration_in_state_block(neuron, var_name): + ASTUtils.add_declaration_to_state_block( + neuron, var_name, expr) + + def get_spike_update_expressions( + self, + neuron: ASTNeuron, + kernel_buffers, + solver_dicts, + delta_factors) -> List[ASTAssignment]: + """ + Generate the equations that update the dynamical variables when incoming spikes arrive. To be invoked after ode-toolbox. + + For example, a resulting `assignment_str` could be "I_kernel_in += (in_spikes/nS) * 1". The values are taken from the initial values for each corresponding dynamical variable, either from ode-toolbox or directly from user specification in the model. + + Note that for kernels, `initial_values` actually contains the increment upon spike arrival, rather than the initial value of the corresponding ODE dimension. + + XXX: TODO: update this function signature (+ templates) to match NESTCodegenerator::get_spike_update_expressions(). + + + """ + spike_updates = [] + + for kernel, spike_input_port in kernel_buffers: + if neuron.get_scope().resolve_to_symbol( + str(spike_input_port), SymbolKind.VARIABLE) is None: + continue + + buffer_type = neuron.get_scope().resolve_to_symbol( + str(spike_input_port), SymbolKind.VARIABLE).get_type_symbol() + + if ASTUtils.is_delta_kernel(kernel): + continue + + for kernel_var in kernel.get_variables(): + for var_order in range( + ASTUtils.get_kernel_var_order_from_ode_toolbox_result( + kernel_var.get_name(), solver_dicts)): + kernel_spike_buf_name = ASTUtils.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_input_port, var_order) + expr = ASTUtils.get_initial_value_from_ode_toolbox_result( + kernel_spike_buf_name, solver_dicts) + assert expr is not None, "Initial value not found for kernel " + kernel_var + expr = str(expr) + if expr in ["0", "0.", "0.0"]: + continue # skip adding the statement if we're only adding zero + + assignment_str = kernel_spike_buf_name + " += " + assignment_str += "(" + str(spike_input_port) + ")" + if expr not in ["1.", "1.0", "1"]: + assignment_str += " * (" + expr + ")" + + if not buffer_type.print_nestml_type() in [ + "1.", "1.0", "1"]: + assignment_str += " / (" + \ + buffer_type.print_nestml_type() + ")" + + ast_assignment = ModelParser.parse_assignment( + assignment_str) + ast_assignment.update_scope(neuron.get_scope()) + ast_assignment.accept(ASTSymbolTableVisitor()) + + spike_updates.append(ast_assignment) + + for k, factor in delta_factors.items(): + var = k[0] + inport = k[1] + assignment_str = var.get_name() + "'" * (var.get_differential_order() - 1) + " += " + if factor not in ["1.", "1.0", "1"]: + assignment_str += "(" + self._printer.print_expression( + ModelParser.parse_expression(factor)) + ") * " + assignment_str += str(inport) + ast_assignment = ModelParser.parse_assignment(assignment_str) + ast_assignment.update_scope(neuron.get_scope()) + ast_assignment.accept(ASTSymbolTableVisitor()) + + spike_updates.append(ast_assignment) + + return spike_updates + + def transform_ode_and_kernels_to_json( + self, + neuron: ASTNeuron, + parameters_block, + kernel_buffers): + """ + Converts AST node to a JSON representation suitable for passing to ode-toolbox. + + Each kernel has to be generated for each spike buffer convolve in which it occurs, e.g. if the NESTML model code contains the statements + + convolve(G, ex_spikes) + convolve(G, in_spikes) + + then `kernel_buffers` will contain the pairs `(G, ex_spikes)` and `(G, in_spikes)`, from which two ODEs will be generated, with dynamical state (variable) names `G__X__ex_spikes` and `G__X__in_spikes`. + + :param parameters_block: ASTBlockWithVariables + :return: Dict + """ + odetoolbox_indict = {} + + gsl_converter = ODEToolboxReferenceConverter() + gsl_printer = UnitlessExpressionPrinter(gsl_converter) + + odetoolbox_indict["dynamics"] = [] + equations_block = neuron.get_equations_block() + for equation in equations_block.get_ode_equations(): + # n.b. includes single quotation marks to indicate differential + # order + lhs = ASTUtils.to_ode_toolbox_name( + equation.get_lhs().get_complete_name()) + rhs = gsl_printer.print_expression(equation.get_rhs()) + entry = {"expression": lhs + " = " + rhs} + symbol_name = equation.get_lhs().get_name() + symbol = equations_block.get_scope().resolve_to_symbol( + symbol_name, SymbolKind.VARIABLE) + + entry["initial_values"] = {} + symbol_order = equation.get_lhs().get_differential_order() + for order in range(symbol_order): + iv_symbol_name = symbol_name + "'" * order + initial_value_expr = neuron.get_initial_value(iv_symbol_name) + if initial_value_expr: + expr = gsl_printer.print_expression(initial_value_expr) + entry["initial_values"][ASTUtils.to_ode_toolbox_name( + iv_symbol_name)] = expr + odetoolbox_indict["dynamics"].append(entry) + + # write a copy for each (kernel, spike buffer) combination + for kernel, spike_input_port in kernel_buffers: + + if ASTUtils.is_delta_kernel(kernel): + # delta function -- skip passing this to ode-toolbox + continue + + for kernel_var in kernel.get_variables(): + expr = ASTUtils.get_expr_from_kernel_var( + kernel, kernel_var.get_complete_name()) + kernel_order = kernel_var.get_differential_order() + kernel_X_spike_buf_name_ticks = ASTUtils.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_input_port, kernel_order, diff_order_symbol="'") + + ASTUtils.replace_rhs_variables(expr, kernel_buffers) + + entry = {} + entry["expression"] = kernel_X_spike_buf_name_ticks + \ + " = " + str(expr) + + # initial values need to be declared for order 1 up to kernel + # order (e.g. none for kernel function f(t) = ...; 1 for kernel + # ODE f'(t) = ...; 2 for f''(t) = ... and so on) + entry["initial_values"] = {} + for order in range(kernel_order): + iv_sym_name_ode_toolbox = ASTUtils.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_input_port, order, diff_order_symbol="'") + symbol_name_ = kernel_var.get_name() + "'" * order + symbol = equations_block.get_scope().resolve_to_symbol( + symbol_name_, SymbolKind.VARIABLE) + assert symbol is not None, "Could not find initial value for variable " + symbol_name_ + initial_value_expr = symbol.get_declaring_expression() + assert initial_value_expr is not None, "No initial value found for variable name " + symbol_name_ + entry["initial_values"][iv_sym_name_ode_toolbox] = gsl_printer.print_expression( + initial_value_expr) + + odetoolbox_indict["dynamics"].append(entry) + + odetoolbox_indict["parameters"] = {} + if parameters_block is not None: + for decl in parameters_block.get_declarations(): + for var in decl.variables: + odetoolbox_indict["parameters"][var.get_complete_name( + )] = gsl_printer.print_expression(decl.get_expression()) + + return odetoolbox_indict diff --git a/pynestml/codegeneration/nest_declarations_helper.py b/pynestml/codegeneration/nest_declarations_helper.py index 397984954..82727b60a 100644 --- a/pynestml/codegeneration/nest_declarations_helper.py +++ b/pynestml/codegeneration/nest_declarations_helper.py @@ -18,24 +18,48 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.codegeneration.pynestml_2_nest_type_converter import PyNestml2NestTypeConverter + +from pynestml.codegeneration.printers.types_printer import TypesPrinter from pynestml.meta_model.ast_declaration import ASTDeclaration from pynestml.symbols.symbol import SymbolKind from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages -class NestDeclarationsHelper(object): - """ +class NestDeclarationsHelper: + r""" This class contains several methods as used during generation of code. """ - def __init__(self): + def __init__(self, types_printer: TypesPrinter): """ Initialized the declaration helper. """ - self.nestml_2_nest_type_converter = PyNestml2NestTypeConverter() - return + self.types_printer = types_printer + + def get_domain_from_type(self, type_symbol): + """ + Returns the domain for the handed over type symbol + :param type_symbol: a single type symbol + :type type_symbol: type_symbol + :return: the corresponding domain + :rtype: str + """ + return self.types_printer.convert(type_symbol) + + def print_variable_type(self, variable_symbol): + """ + Prints the type of the variable symbol to a corresponding nest representation. + :param variable_symbol: a single variable symbol + :type variable_symbol: variable_symbol + :return: a string presentation of the variable symbol's type + :rtype: str + """ + if variable_symbol.has_vector_parameter(): + return 'std::vector< ' + self.types_printer.convert(variable_symbol.get_type_symbol()) + \ + ' > ' + + return self.types_printer.convert(variable_symbol.get_type_symbol()) @classmethod def get_variables(cls, ast_declaration): @@ -61,20 +85,6 @@ def get_variables(cls, ast_declaration): error_position=ast_declaration.get_source_position(), log_level=LoggingLevel.ERROR) return ret - def print_variable_type(self, variable_symbol): - """ - Prints the type of the variable symbol to a corresponding nest representation. - :param variable_symbol: a single variable symbol - :type variable_symbol: variable_symbol - :return: a string presentation of the variable symbol's type - :rtype: str - """ - if variable_symbol.has_vector_parameter(): - return 'std::vector< ' + self.nestml_2_nest_type_converter.convert(variable_symbol.get_type_symbol()) + \ - ' > ' - else: - return self.nestml_2_nest_type_converter.convert(variable_symbol.get_type_symbol()) - @classmethod def print_size_parameter(cls, ast_declaration): """ @@ -85,13 +95,3 @@ def print_size_parameter(cls, ast_declaration): :rtype: str """ return ast_declaration.get_size_parameter() - - def get_domain_from_type(self, type_symbol): - """ - Returns the domain for the handed over type symbol - :param type_symbol: a single type symbol - :type type_symbol: type_symbol - :return: the corresponding domain - :rtype: str - """ - return self.nestml_2_nest_type_converter.convert(type_symbol) diff --git a/pynestml/codegeneration/nest_names_converter.py b/pynestml/codegeneration/nest_names_converter.py deleted file mode 100644 index 3f5817d75..000000000 --- a/pynestml/codegeneration/nest_names_converter.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -# -# nest_names_converter.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.symbols.variable_symbol import VariableSymbol - - -class NestNamesConverter(object): - """ - This class provides several methods which can be used to convert names of objects to the corresponding - nest representation. - """ - - @classmethod - def name(cls, node): - """ - Returns for the handed over element the corresponding nest processable string. - :param node: a single variable symbol or variable - :type node: VariableSymbol or ASTVariable - :return: the corresponding string representation - :rtype: str - """ - if isinstance(node, VariableSymbol): - return cls.convert_to_cpp_name(node.get_symbol_name()) - else: - return cls.convert_to_cpp_name(node.get_complete_name()) - - @classmethod - def getter(cls, variable_symbol): - """ - Converts for a handed over symbol the corresponding name of the getter to a nest processable format. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding representation as a string - :rtype: str - """ - assert isinstance(variable_symbol, VariableSymbol), \ - '(PyNestML.CodeGeneration.NamesConverter) No or wrong type of variable symbol provided (%s)!' % type( - variable_symbol) - return 'get_' + cls.convert_to_cpp_name(variable_symbol.get_symbol_name()) - - @classmethod - def buffer_value(cls, variable_symbol): - """ - Converts for a handed over symbol the corresponding name of the buffer to a nest processable format. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding representation as a string - :rtype: str - """ - assert isinstance(variable_symbol, VariableSymbol), \ - '(PyNestML.CodeGeneration.NamesConverter) No or wrong type of variable symbol provided (%s)!' % type( - variable_symbol) - return variable_symbol.get_symbol_name() + '_grid_sum_' - - @classmethod - def setter(cls, variable_symbol): - """ - Converts for a handed over symbol the corresponding name of the setter to a nest processable format. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding representation as a string - :rtype: str - """ - assert isinstance(variable_symbol, VariableSymbol), \ - '(PyNestML.CodeGeneration.NamesConverter) No or wrong type of variable symbol provided (%s)!' % type( - variable_symbol) - return 'set_' + cls.convert_to_cpp_name(variable_symbol.get_symbol_name()) - - @classmethod - def convert_to_cpp_name(cls, variable_name): - """ - Converts a handed over name to the corresponding NEST/C++ naming guideline. This is chosen to be compatible with the naming strategy for ode-toolbox, such that the variable name in a NESTML statement like "G_ahp' += 1" will be converted into "G_ahp__d". - - :param variable_name: a single name. - :type variable_name: str - :return: the corresponding transformed name. - :rtype: str - """ - differential_order = variable_name.count('\'') - if differential_order > 0: - return variable_name.replace('\'', '').replace("$", "__DOLLAR") + '__' + 'd' * differential_order - else: - return variable_name.replace("$", "__DOLLAR") diff --git a/pynestml/codegeneration/nest_reference_converter.py b/pynestml/codegeneration/nest_reference_converter.py deleted file mode 100644 index 77a6dac33..000000000 --- a/pynestml/codegeneration/nest_reference_converter.py +++ /dev/null @@ -1,373 +0,0 @@ -# -*- coding: utf-8 -*- -# -# nest_reference_converter.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -from pynestml.codegeneration.gsl_names_converter import GSLNamesConverter -from pynestml.codegeneration.i_reference_converter import IReferenceConverter -from pynestml.codegeneration.nest_names_converter import NestNamesConverter -from pynestml.codegeneration.unit_converter import UnitConverter -from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator -from pynestml.meta_model.ast_bit_operator import ASTBitOperator -from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator -from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.predefined_variables import PredefinedVariables -from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.unit_type_symbol import UnitTypeSymbol -from pynestml.utils.ast_utils import ASTUtils -from pynestml.utils.logger import Logger, LoggingLevel -from pynestml.utils.messages import Messages - - -class NESTReferenceConverter(IReferenceConverter): - """ - This concrete reference converter is used to transfer internal names to counter-pieces in NEST. - """ - - def __init__(self, uses_gsl=False): - """ - Standard constructor. - :param uses_gsl: indicates whether GSL is used. - :type uses_gsl: bool - """ - self.uses_gsl = uses_gsl - return - - @classmethod - def convert_binary_op(cls, binary_operator): - """ - Converts a single binary operator to nest processable format. - :param binary_operator: a single binary operator string. - :type binary_operator: AST_ - :return: the corresponding nest representation - :rtype: str - """ - if isinstance(binary_operator, ASTArithmeticOperator): - return cls.convert_arithmetic_operator(binary_operator) - if isinstance(binary_operator, ASTBitOperator): - return cls.convert_bit_operator(binary_operator) - if isinstance(binary_operator, ASTComparisonOperator): - return cls.convert_comparison_operator(binary_operator) - if isinstance(binary_operator, ASTLogicalOperator): - return cls.convert_logical_operator(binary_operator) - else: - raise RuntimeError('Cannot determine binary operator!') - - @classmethod - def convert_function_call(cls, function_call, prefix=''): - """ - Converts a single handed over function call to C++ NEST API syntax. - - Parameters - ---------- - function_call : ASTFunctionCall - The function call node to convert. - prefix : str - Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". - - Predefined functions will not be prefixed. - - Returns - ------- - s : str - The function call string in C++ syntax. - """ - function_name = function_call.get_name() - - if function_name == 'and': - return '&&' - - if function_name == 'or': - return '||' - - if function_name == PredefinedFunctions.TIME_RESOLUTION: - return 'nest::Time::get_resolution().get_ms()' - - if function_name == PredefinedFunctions.TIME_STEPS: - return 'nest::Time(nest::Time::ms((double) ({!s}))).get_steps()' - - if function_name == PredefinedFunctions.CLIP: - # warning: the arguments of this function must swapped and - # are therefore [v_max, v_min, v], hence its structure - return 'std::min({2!s}, std::max({1!s}, {0!s}))' - - if function_name == PredefinedFunctions.MAX: - return 'std::max({!s}, {!s})' - - if function_name == PredefinedFunctions.MIN: - return 'std::min({!s}, {!s})' - - if function_name == PredefinedFunctions.EXP: - return 'std::exp({!s})' - - if function_name == PredefinedFunctions.LN: - return 'std::log({!s})' - - if function_name == PredefinedFunctions.LOG10: - return 'std::log10({!s})' - - if function_name == PredefinedFunctions.COSH: - return 'std::cosh({!s})' - - if function_name == PredefinedFunctions.SINH: - return 'std::sinh({!s})' - - if function_name == PredefinedFunctions.TANH: - return 'std::tanh({!s})' - - if function_name == PredefinedFunctions.EXPM1: - return 'numerics::expm1({!s})' - - if function_name == PredefinedFunctions.RANDOM_NORMAL: - return '(({!s}) + ({!s}) * ' + prefix + 'normal_dev_( nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() ) ))' - - if function_name == PredefinedFunctions.RANDOM_UNIFORM: - return '(({!s}) + ({!s}) * nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() )->drand())' - - if function_name == PredefinedFunctions.EMIT_SPIKE: - return 'set_spiketime(nest::Time::step(origin.get_steps()+lag+1));\n' \ - 'nest::SpikeEvent se;\n' \ - 'nest::kernel().event_delivery_manager.send(*this, se, lag)' - - # suppress prefix for misc. predefined functions - # check if function is "predefined" purely based on the name, as we don't have access to the function symbol here - function_is_predefined = PredefinedFunctions.get_function(function_name) - if function_is_predefined: - prefix = '' - - if ASTUtils.needs_arguments(function_call): - n_args = len(function_call.get_args()) - return prefix + function_name + '(' + ', '.join(['{!s}' for _ in range(n_args)]) + ')' - return prefix + function_name + '()' - - def convert_name_reference(self, variable, prefix=''): - """ - Converts a single variable to nest processable format. - :param variable: a single variable. - :type variable: ASTVariable - :return: a nest processable format. - :rtype: str - """ - from pynestml.codegeneration.nest_printer import NestPrinter - assert (variable is not None and isinstance(variable, ASTVariable)), \ - '(PyNestML.CodeGeneration.NestReferenceConverter) No or wrong type of uses-gsl provided (%s)!' % type( - variable) - variable_name = NestNamesConverter.convert_to_cpp_name(variable.get_complete_name()) - - if variable_name == PredefinedVariables.E_CONSTANT: - return 'numerics::e' - - assert variable.get_scope() is not None, "Undeclared variable: " + variable.get_complete_name() - - symbol = variable.get_scope().resolve_to_symbol(variable_name, SymbolKind.VARIABLE) - if symbol is None: - # test if variable name can be resolved to a type - if PredefinedUnits.is_unit(variable.get_complete_name()): - return str(UnitConverter.get_factor(PredefinedUnits.get_unit(variable.get_complete_name()).get_unit())) - - code, message = Messages.get_could_not_resolve(variable_name) - Logger.log_message(log_level=LoggingLevel.ERROR, code=code, message=message, - error_position=variable.get_source_position()) - return '' - - if symbol.is_local(): - return variable_name + ('[i]' if symbol.has_vector_parameter() else '') - - if symbol.is_buffer(): - if isinstance(symbol.get_type_symbol(), UnitTypeSymbol): - units_conversion_factor = UnitConverter.get_factor(symbol.get_type_symbol().unit.unit) - else: - units_conversion_factor = 1 - s = "" - if not units_conversion_factor == 1: - s += "(" + str(units_conversion_factor) + " * " - s += NestPrinter.print_origin(symbol, prefix=prefix) + NestNamesConverter.buffer_value(symbol) - if symbol.has_vector_parameter(): - s += '[i]' - if not units_conversion_factor == 1: - s += ")" - return s - - if symbol.is_function: - return 'get_' + variable_name + '()' + ('[i]' if symbol.has_vector_parameter() else '') - - if symbol.is_kernel(): - print("Printing node " + str(symbol.name)) - - if symbol.is_init_values(): - temp = NestPrinter.print_origin(symbol, prefix=prefix) - if self.uses_gsl: - temp += GSLNamesConverter.name(symbol) - else: - temp += NestNamesConverter.name(symbol) - temp += ('[i]' if symbol.has_vector_parameter() else '') - return temp - - return NestPrinter.print_origin(symbol, prefix=prefix) + \ - NestNamesConverter.name(symbol) + \ - ('[i]' if symbol.has_vector_parameter() else '') - - @classmethod - def convert_constant(cls, constant_name): - """ - Converts a single handed over constant. - :param constant_name: a constant as string. - :type constant_name: str - :return: the corresponding nest representation - :rtype: str - """ - if constant_name == 'inf': - return 'std::numeric_limits::infinity()' - else: - return constant_name - - @classmethod - def convert_unary_op(cls, unary_operator): - """ - Depending on the concretely used operator, a string is returned. - :param unary_operator: a single operator. - :type unary_operator: ASTUnaryOperator - :return: the same operator - :rtype: str - """ - if unary_operator.is_unary_plus: - return '(' + '+' + '%s' + ')' - elif unary_operator.is_unary_minus: - return '(' + '-' + '%s' + ')' - elif unary_operator.is_unary_tilde: - return '(' + '~' + '%s' + ')' - else: - raise RuntimeError('Cannot determine unary operator!', LoggingLevel.ERROR) - - @classmethod - def convert_encapsulated(cls): - """ - Converts the encapsulating parenthesis to NEST style. - :return: a set of parenthesis - :rtype: str - """ - return '(%s)' - - @classmethod - def convert_logical_not(cls): - """ - Returns a representation of the logical not in NEST. - :return: a string representation - :rtype: str - """ - return '(' + '!' + '%s' + ')' - - @classmethod - def convert_logical_operator(cls, op): - """ - Prints a logical operator in NEST syntax. - :param op: a logical operator object - :type op: ASTLogicalOperator - :return: a string representation - :rtype: str - """ - if op.is_logical_and: - return '%s' + '&&' + '%s' - elif op.is_logical_or: - return '%s' + '||' + '%s' - else: - raise RuntimeError('Cannot determine logical operator!', LoggingLevel.ERROR) - - @classmethod - def convert_comparison_operator(cls, op): - """ - Prints a logical operator in NEST syntax. - :param op: a logical operator object - :type op: ASTComparisonOperator - :return: a string representation - :rtype: str - """ - if op.is_lt: - return '%s' + '<' + '%s' - elif op.is_le: - return '%s' + '<=' + '%s' - elif op.is_eq: - return '%s' + '==' + '%s' - elif op.is_ne or op.is_ne2: - return '%s' + '!=' + '%s' - elif op.is_ge: - return '%s' + '>=' + '%s' - elif op.is_gt: - return '%s' + '>' + '%s' - else: - raise RuntimeError('Cannot determine comparison operator!') - - @classmethod - def convert_bit_operator(cls, op): - """ - Prints a logical operator in NEST syntax. - :param op: a logical operator object - :type op: ASTBitOperator - :return: a string representation - :rtype: str - """ - if op.is_bit_shift_left: - return '%s' + '<<' '%s' - if op.is_bit_shift_right: - return '%s' + '>>' + '%s' - if op.is_bit_and: - return '%s' + '&' + '%s' - if op.is_bit_or: - return '%s' + '|' + '%s' - if op.is_bit_xor: - return '%s' + '^' + '%s' - else: - raise RuntimeError('Cannot determine bit operator!') - - @classmethod - def convert_arithmetic_operator(cls, op): - """ - Prints a logical operator in NEST syntax. - :param op: a logical operator object - :type op: ASTArithmeticOperator - :return: a string representation - :rtype: str - """ - if op.is_plus_op: - return '%s' + ' + ' + '%s' - if op.is_minus_op: - return '%s' + ' - ' + '%s' - if op.is_times_op: - return '%s' + ' * ' + '%s' - if op.is_div_op: - return '%s' + ' / ' + '%s' - if op.is_modulo_op: - return '%s' + ' % ' + '%s' - if op.is_pow_op: - return 'pow' + '(%s, %s)' - raise RuntimeError('Cannot determine arithmetic operator!') - - @classmethod - def convert_ternary_operator(cls): - """ - Prints a ternary operator in NEST syntax. - :return: a string representation - :rtype: str - """ - return '(' + '%s' + ') ? (' + '%s' + ') : (' + '%s' + ')' diff --git a/pynestml/codegeneration/nest_tools.py b/pynestml/codegeneration/nest_tools.py new file mode 100644 index 000000000..268c1de99 --- /dev/null +++ b/pynestml/codegeneration/nest_tools.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# +# nest_tools.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import multiprocessing as mp +import sys + +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel + + +def _detect_nest_version(user_args): + try: + import nest + + vt = nest.Create("volume_transmitter") + + try: + neuron = nest.Create('hh_psc_alpha_clopath') + except Exception: + pass + + if "DataConnect" in dir(nest): + nest_version = "v2.20.2" + elif "kernel_status" not in dir(nest): # added in v3.1 + nest_version = "v3.0" + elif "prepared" in nest.GetKernelStatus().keys(): # "prepared" key was added after v3.3 release + nest_version = "master" + elif "tau_u_bar_minus" in neuron.get().keys(): # added in v3.3 + nest_version = "v3.3" + elif "tau_Ca" in vt.get().keys(): # removed in v3.2 + nest_version = "v3.1" + else: + nest_version = "v3.2" + + except ModuleNotFoundError: + nest_version = "" + + return nest_version + + +class NESTTools: + r"""Helper functions for NEST Simulator""" + + @classmethod + def detect_nest_version(cls) -> str: + r"""Auto-detect NEST Simulator installed version. The returned string corresponds to a git tag or git branch name. + + Do this in a separate process to avoid potential side-effects of import the ``nest`` Python module. + + .. admonition:: + + NEST version detection needs improvement. See https://github.com/nest/nest-simulator/issues/2116 + """ + + p = mp.Pool(processes=1) + nest_version = p.map(_detect_nest_version, [None])[0] + p.close() + + if nest_version == "": + Logger.log_message(None, -1, "An error occurred while importing the `nest` module in Python. Please check your NEST installation-related environment variables and paths, or specify ``nest_version`` manually in the code generator options.", None, LoggingLevel.ERROR) + sys.exit(1) + + Logger.log_message(None, -1, "The NEST Simulator version was automatically detected as: " + nest_version, None, LoggingLevel.INFO) + + return nest_version diff --git a/pynestml/codegeneration/printers/__init__.py b/pynestml/codegeneration/printers/__init__.py new file mode 100644 index 000000000..03ace8088 --- /dev/null +++ b/pynestml/codegeneration/printers/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# +# __init__.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +__all__ = ['cpp_reference_converter.py', 'cpp_types_printer.py', 'debug_types_printer.py', 'expression_printer.py', 'gsl_reference_converter.py', 'latex_expression_printer.py', 'latex_reference_converter.py', 'nest2_gsl_reference_converter.py', 'nest2_reference_converter.py', 'nestml_reference_converter.py', 'nest_printer.py', 'nest_reference_converter.py', 'ode_toolbox_reference_converter.py', 'python_types_printer.py', 'reference_converter.py', 'types_printer.py', 'unit_converter.py', 'unitless_expression_printer.py'] diff --git a/pynestml/codegeneration/printers/cpp_expression_printer.py b/pynestml/codegeneration/printers/cpp_expression_printer.py new file mode 100644 index 000000000..2b3a3a8d0 --- /dev/null +++ b/pynestml/codegeneration/printers/cpp_expression_printer.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +# +# cpp_expression_printer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Tuple + +from pynestml.codegeneration.printers.expression_printer import ExpressionPrinter +from pynestml.codegeneration.printers.nest_reference_converter import NESTReferenceConverter +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_expression_node import ASTExpressionNode +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.utils.ast_utils import ASTUtils + + +class CppExpressionPrinter(ExpressionPrinter): + r""" + Expressions printer for C++. + """ + + def print_expression(self, node: ASTExpressionNode, prefix: str = "", with_origins=True): + """Print an expression. + + Parameters + ---------- + node : ASTExpressionNode + The expression node to print. + prefix : str + *See documentation for the function print_function_call().* + + Returns + ------- + s : str + The expression string. + """ + if (node.get_implicit_conversion_factor() is not None) \ + and (not node.get_implicit_conversion_factor() == 1): + return str(node.get_implicit_conversion_factor()) + " * (" + self.__do_print(node, prefix=prefix, with_origins=with_origins) + ")" + + return self.__do_print(node, prefix=prefix, with_origins=with_origins) + + def __do_print(self, node: ASTExpressionNode, prefix: str = "", with_origins=True) -> str: + if isinstance(node, ASTSimpleExpression): + if node.has_unit(): + if isinstance(self.reference_converter, NESTReferenceConverter): + # NESTReferenceConverter takes the extra with_origins parameter + # which is used in compartmental models + return str(node.get_numeric_literal()) + "*" + self.reference_converter.convert_name_reference(node.get_variable(), prefix=prefix, with_origins=with_origins) + + return str(node.get_numeric_literal()) + "*" + self.reference_converter.convert_name_reference(node.get_variable(), prefix=prefix) + + if node.is_numeric_literal(): + return str(node.get_numeric_literal()) + + if node.is_inf_literal: + return self.reference_converter.convert_constant("inf") + + if node.is_string(): + return str(node.get_string()) + + if node.is_boolean_true: + return self.reference_converter.convert_constant("true") + + if node.is_delay_variable(): + return self.reference_converter.convert_delay_variable(node.get_variable(), prefix=prefix) + + if node.is_boolean_false: + return self.reference_converter.convert_constant("false") + + if node.is_variable(): + if isinstance(self.reference_converter, NESTReferenceConverter): + # NESTReferenceConverter takes the extra with_origins parameter + # which is used in compartmental models + return self.reference_converter.convert_name_reference(node.get_variable(), prefix=prefix, with_origins=with_origins) + + return self.reference_converter.convert_name_reference(node.get_variable(), prefix=prefix) + + if node.is_function_call(): + return self.print_function_call(node.get_function_call(), prefix=prefix, with_origins=with_origins) + + raise Exception("Unknown node type") + + if isinstance(node, ASTExpression): + # a unary operator + if node.is_unary_operator(): + op = self.reference_converter.convert_unary_op( + node.get_unary_operator()) + rhs = self.print_expression( + node.get_expression(), prefix=prefix, with_origins=with_origins) + return op % rhs + + # encapsulated in brackets + if node.is_encapsulated: + return self.reference_converter.convert_encapsulated() % self.print_expression(node.get_expression(), + prefix=prefix, with_origins=with_origins) + + # logical not + if node.is_logical_not: + op = self.reference_converter.convert_logical_not() + rhs = self.print_expression( + node.get_expression(), prefix=prefix, with_origins=with_origins) + return op % rhs + + # compound rhs with lhs + rhs + if node.is_compound_expression(): + lhs = self.print_expression( + node.get_lhs(), prefix=prefix, with_origins=with_origins) + op = self.reference_converter.convert_binary_op( + node.get_binary_operator()) + rhs = self.print_expression( + node.get_rhs(), prefix=prefix, with_origins=with_origins) + return op % (lhs, rhs) + + if node.is_ternary_operator(): + condition = self.print_expression( + node.get_condition(), prefix=prefix, with_origins=with_origins) + if_true = self.print_expression( + node.get_if_true(), prefix=prefix, with_origins=with_origins) + if_not = self.print_expression( + node.if_not, prefix=prefix, with_origins=with_origins) + return self.reference_converter.convert_ternary_operator() % (condition, if_true, if_not) + + raise Exception("Unknown node type") + + raise RuntimeError( + "Tried to print unknown expression: \"%s\"" % str(node)) + + def print_function_call(self, function_call: ASTFunctionCall, prefix: str = "", with_origins=True) -> str: + """Print a function call, including bracketed arguments list. + + Parameters + ---------- + node + The function call node to print. + prefix + Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". + + Predefined functions will not be prefixed. + + Returns + ------- + s + The function call string. + """ + function_name = self.reference_converter.convert_function_call( + function_call, prefix=prefix) + if ASTUtils.needs_arguments(function_call): + if function_call.get_name() == PredefinedFunctions.PRINT or function_call.get_name() == PredefinedFunctions.PRINTLN: + return function_name.format(self.reference_converter.convert_print_statement(function_call)) + + return function_name.format(*self.print_function_call_argument_list(function_call, prefix=prefix, with_origins=with_origins)) + + return function_name + + def print_function_call_argument_list(self, function_call: ASTFunctionCall, prefix: str = "", with_origins=True) -> Tuple[str, ...]: + ret = [] + + for arg in function_call.get_args(): + ret.append(self.print_expression( + arg, prefix=prefix, with_origins=with_origins)) + + return tuple(ret) diff --git a/pynestml/codegeneration/printers/cpp_reference_converter.py b/pynestml/codegeneration/printers/cpp_reference_converter.py new file mode 100644 index 000000000..451280cca --- /dev/null +++ b/pynestml/codegeneration/printers/cpp_reference_converter.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# +# cpp_reference_converter.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Union + +from pynestml.codegeneration.printers.reference_converter import ReferenceConverter +from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator +from pynestml.meta_model.ast_bit_operator import ASTBitOperator +from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator +from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator +from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.variable_symbol import VariableSymbol + + +class CppReferenceConverter(ReferenceConverter): + def convert_to_cpp_name(self, variable_name: str) -> str: + """ + Converts a handed over name to the corresponding NEST/C++ naming guideline. This is chosen to be compatible with the naming strategy for ode-toolbox, such that the variable name in a NESTML statement like "G_ahp" += 1" will be converted into "G_ahp__d". + + :param variable_name: a single name. + :return: a string representation + """ + differential_order = variable_name.count("\"") + if differential_order > 0: + return variable_name.replace("\"", "").replace("$", "__DOLLAR") + "__" + "d" * differential_order + + return variable_name.replace("$", "__DOLLAR") + + def getter(self, variable_symbol: VariableSymbol) -> str: + """ + Converts for a handed over symbol the corresponding name of the getter to a nest processable format. + :param variable_symbol: a single variable symbol. + :return: a string representation + """ + return 'get_' + self.convert_to_cpp_name(variable_symbol.get_symbol_name()) + + def setter(self, variable_symbol: VariableSymbol) -> str: + """ + Converts for a handed over symbol the corresponding name of the setter to a nest processable format. + :param variable_symbol: a single variable symbol. + :return: a string representation + """ + return 'set_' + self.convert_to_cpp_name(variable_symbol.get_symbol_name()) + + def name(self, node: Union[VariableSymbol, ASTVariable]) -> str: + """ + Returns for the handed over element the corresponding nest processable string. + :param node: a single variable symbol or variable + :return: a string representation + """ + if isinstance(node, VariableSymbol): + return self.convert_to_cpp_name(node.get_symbol_name()) + + return self.convert_to_cpp_name(node.get_complete_name()) + + def convert_constant(self, const: Union[str, float, int]) -> str: + """ + Converts a single handed over constant. + :param const: a constant as string, float or int. + :return: a string representation + """ + if const == 'inf': + return 'std::numeric_limits::infinity()' + + if const == 'true': + return 'true' + + if const == 'false': + return 'false' + + if isinstance(const, float) or isinstance(const, int): + return str(const) + + return const + + def convert_unary_op(self, unary_operator: ASTUnaryOperator) -> str: + """ + Converts a unary operator. + :param unary_operator: an operator object + :return: a string representation + """ + if unary_operator.is_unary_plus: + return '(' + '+' + '(%s)' + ')' + + if unary_operator.is_unary_minus: + return '(' + '-' + '(%s)' + ')' + + if unary_operator.is_unary_tilde: + return '(' + '~' + '(%s)' + ')' + + raise RuntimeError('Cannot determine unary operator!') + + def convert_encapsulated(self) -> str: + """ + Converts the encapsulating parenthesis of an expression. + :return: a string representation + """ + return '(%s)' + + def convert_logical_not(self) -> str: + """ + Converts a logical NOT operator. + :return: a string representation + """ + return '(' + '!' + '%s' + ')' + + def convert_logical_operator(self, op: ASTLogicalOperator) -> str: + """ + Converts a logical operator. + :param op: a logical operator object + :return: a string representation + """ + if op.is_logical_and: + return '%s' + '&&' + '%s' + + if op.is_logical_or: + return '%s' + '||' + '%s' + + raise RuntimeError('Cannot determine logical operator!') + + def convert_comparison_operator(self, op: ASTComparisonOperator) -> str: + """ + Converts a comparison operator. + :param op: a comparison operator object + :return: a string representation + """ + if op.is_lt: + return '%s' + '<' + '%s' + + if op.is_le: + return '%s' + '<=' + '%s' + + if op.is_eq: + return '%s' + '==' + '%s' + + if op.is_ne or op.is_ne2: + return '%s' + '!=' + '%s' + + if op.is_ge: + return '%s' + '>=' + '%s' + + if op.is_gt: + return '%s' + '>' + '%s' + + raise RuntimeError('Cannot determine comparison operator!') + + def convert_bit_operator(self, op: ASTBitOperator) -> str: + """ + Converts a bit operator in NEST syntax. + :param op: a bit operator object + :return: a string representation + """ + if op.is_bit_shift_left: + return '%s' + '<<' '%s' + + if op.is_bit_shift_right: + return '%s' + '>>' + '%s' + + if op.is_bit_and: + return '%s' + '&' + '%s' + + if op.is_bit_or: + return '%s' + '|' + '%s' + + if op.is_bit_xor: + return '%s' + '^' + '%s' + + raise RuntimeError('Cannot determine bit operator!') + + def convert_arithmetic_operator(self, op: ASTArithmeticOperator) -> str: + """ + Converts an arithmetic operator. + :param op: an arithmetic operator object + :return: a string representation + """ + if op.is_plus_op: + return '%s' + ' + ' + '%s' + + if op.is_minus_op: + return '%s' + ' - ' + '%s' + + if op.is_times_op: + return '%s' + ' * ' + '%s' + + if op.is_div_op: + return '%s' + ' / ' + '%s' + + if op.is_modulo_op: + return '%s' + ' %% ' + '%s' + + if op.is_pow_op: + return 'pow' + '(%s, %s)' + + raise RuntimeError('Cannot determine arithmetic operator!') + + def convert_ternary_operator(self) -> str: + """ + Converts a ternary operator. + :return: a string representation + """ + return '(' + '%s' + ') ? (' + '%s' + ') : (' + '%s' + ')' + + def convert_binary_op(self, binary_operator: Union[ASTArithmeticOperator, ASTBitOperator, ASTComparisonOperator, ASTLogicalOperator]) -> str: + """ + Converts a binary operator. + :param binary_operator: a binary operator object + :return: a string representation + """ + if isinstance(binary_operator, ASTArithmeticOperator): + return self.convert_arithmetic_operator(binary_operator) + + if isinstance(binary_operator, ASTBitOperator): + return self.convert_bit_operator(binary_operator) + + if isinstance(binary_operator, ASTComparisonOperator): + return self.convert_comparison_operator(binary_operator) + + if isinstance(binary_operator, ASTLogicalOperator): + return self.convert_logical_operator(binary_operator) + + raise RuntimeError('Cannot determine binary operator!') + + def buffer_value(self, variable_symbol: VariableSymbol) -> str: + """ + Converts for a handed over symbol the corresponding name of the buffer to a nest processable format. + :param variable_symbol: a single variable symbol. + :return: the corresponding representation as a string + """ + return variable_symbol.get_symbol_name() + '_grid_sum_' diff --git a/pynestml/codegeneration/pynestml_2_nest_type_converter.py b/pynestml/codegeneration/printers/cpp_types_printer.py similarity index 61% rename from pynestml/codegeneration/pynestml_2_nest_type_converter.py rename to pynestml/codegeneration/printers/cpp_types_printer.py index 220409b9a..f9ee86e08 100644 --- a/pynestml/codegeneration/pynestml_2_nest_type_converter.py +++ b/pynestml/codegeneration/printers/cpp_types_printer.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# pynestml_2_nest_type_converter.py +# cpp_types_printer.py # # This file is part of NEST. # @@ -18,6 +18,8 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from pynestml.codegeneration.printers.types_printer import TypesPrinter from pynestml.symbols.type_symbol import TypeSymbol from pynestml.symbols.real_type_symbol import RealTypeSymbol from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol @@ -29,41 +31,44 @@ from pynestml.symbols.error_type_symbol import ErrorTypeSymbol -class PyNestml2NestTypeConverter(object): +class CppTypesPrinter(TypesPrinter): """ - This class contains a single operation as used to convert nestml types to nest centerpieces. + Returns a C++ syntax version of the handed over type. """ - @classmethod - def convert(cls, type_symbol): - # type: (TypeSymbol) -> str + def convert(self, type_symbol: TypeSymbol) -> str: """ Converts the name of the type symbol to a corresponding nest representation. :param type_symbol: a single type symbol - :type type_symbol: TypeSymbol :return: the corresponding string representation. - :rtype: str """ assert isinstance(type_symbol, TypeSymbol) if type_symbol.is_buffer: - return 'nest::RingBuffer' + return "nest::RingBuffer" if isinstance(type_symbol, RealTypeSymbol): - return 'double' - elif isinstance(type_symbol, BooleanTypeSymbol): - return 'bool' - elif isinstance(type_symbol, IntegerTypeSymbol): - return 'long' - elif isinstance(type_symbol, StringTypeSymbol): - return 'std::string' - elif isinstance(type_symbol, VoidTypeSymbol): - return 'void' - elif isinstance(type_symbol, UnitTypeSymbol): - return 'double' - elif isinstance(type_symbol, NESTTimeTypeSymbol): - return 'nest::Time' - elif isinstance(type_symbol, ErrorTypeSymbol): - return 'ERROR' - else: - raise Exception('Unknown NEST type') + return "double" + + if isinstance(type_symbol, BooleanTypeSymbol): + return "bool" + + if isinstance(type_symbol, IntegerTypeSymbol): + return "long" + + if isinstance(type_symbol, StringTypeSymbol): + return "std::string" + + if isinstance(type_symbol, VoidTypeSymbol): + return "void" + + if isinstance(type_symbol, UnitTypeSymbol): + return "double" + + if isinstance(type_symbol, NESTTimeTypeSymbol): + return "nest::Time" + + if isinstance(type_symbol, ErrorTypeSymbol): + return "ERROR" + + raise Exception("Unknown NEST type") diff --git a/pynestml/codegeneration/debug_type_converter.py b/pynestml/codegeneration/printers/debug_types_printer.py similarity index 86% rename from pynestml/codegeneration/debug_type_converter.py rename to pynestml/codegeneration/printers/debug_types_printer.py index 9064f2869..554c21328 100644 --- a/pynestml/codegeneration/debug_type_converter.py +++ b/pynestml/codegeneration/printers/debug_types_printer.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# debug_type_converter.py +# debug_types_printer.py # # This file is part of NEST. # @@ -19,6 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from pynestml.codegeneration.printers.types_printer import TypesPrinter from pynestml.symbols.type_symbol import TypeSymbol from pynestml.symbols.real_type_symbol import RealTypeSymbol from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol @@ -31,21 +32,20 @@ from pynestml.utils.either import Either -class DebugTypeConverter(): +class DebugTypesPrinter(TypesPrinter): """ - Convert NESTML types to a string format that is suitable for info/warning/error messages. + Returns a string format that is suitable for info/warning/error messages. """ - @classmethod - def convert(cls, type_symbol: TypeSymbol) -> str: + def convert(self, type_symbol: TypeSymbol) -> str: """ - Converts the name of the type symbol to a corresponding string representation. + Converts the name of the type symbol to a corresponding nest representation. :param type_symbol: a single type symbol :return: the corresponding string representation. """ if isinstance(type_symbol, Either): if type_symbol.is_value(): - return cls.convert(type_symbol.get_value()) + return self.convert(type_symbol.get_value()) else: assert type_symbol.is_error() return type_symbol.get_error() @@ -69,7 +69,7 @@ def convert(cls, type_symbol: TypeSymbol) -> str: return 'void' if isinstance(type_symbol, UnitTypeSymbol): - return type_symbol.get_value().unit.unit + return type_symbol.unit.unit.to_string() if isinstance(type_symbol, NESTTimeTypeSymbol): return 'nest::Time' diff --git a/pynestml/codegeneration/printers/expression_printer.py b/pynestml/codegeneration/printers/expression_printer.py new file mode 100644 index 000000000..0a925b82e --- /dev/null +++ b/pynestml/codegeneration/printers/expression_printer.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# +# expression_printer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from abc import ABCMeta, abstractmethod + +from pynestml.codegeneration.printers.reference_converter import ReferenceConverter +from pynestml.meta_model.ast_expression_node import ASTExpressionNode + + +class ExpressionPrinter(metaclass=ABCMeta): + r""" + Converts expressions to the executable platform dependent code. + + This class is used to transform only parts of the grammar and not NESTML as a whole. + """ + + def __init__(self, reference_converter: ReferenceConverter): + self.reference_converter = reference_converter + + @abstractmethod + def print_expression(self, node: ASTExpressionNode, prefix: str = ""): + """Print an expression. + + Parameters + ---------- + node : ASTExpressionNode + The expression node to print. + prefix : str + *See documentation for the function print_function_call().* + + Returns + ------- + s : str + The expression string. + """ + pass diff --git a/pynestml/codegeneration/printers/gsl_reference_converter.py b/pynestml/codegeneration/printers/gsl_reference_converter.py new file mode 100644 index 000000000..642edb80c --- /dev/null +++ b/pynestml/codegeneration/printers/gsl_reference_converter.py @@ -0,0 +1,230 @@ +# -*- coding: utf-8 -*- +# +# gsl_reference_converter.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.codegeneration.printers.cpp_reference_converter import CppReferenceConverter +from pynestml.codegeneration.printers.unit_converter import UnitConverter +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.symbols.variable_symbol import VariableSymbol +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages + + +class GSLReferenceConverter(CppReferenceConverter): + r""" + Reference converter for C++ syntax and using the GSL (GNU Scientific Library) API. + """ + maximal_exponent = 10. + + def __init__(self, is_upper_bound=False): + """ + Standard constructor. + :param is_upper_bound: Indicates whether an upper bound for the exponent shall be used. + :type is_upper_bound: bool + """ + self.is_upper_bound = is_upper_bound + + def convert_name_reference(self, variable: ASTVariable, prefix: str = '') -> str: + """ + Converts a single name reference to a gsl processable format. + :param ast_variable: a single variable + :return: a gsl processable format of the variable + """ + + if variable.get_name() == PredefinedVariables.E_CONSTANT: + return 'numerics::e' + + symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE) + if symbol is None: + # test if variable name can be resolved to a type + if PredefinedUnits.is_unit(variable.get_complete_name()): + return str(UnitConverter.get_factor(PredefinedUnits.get_unit(variable.get_complete_name()).get_unit())) + + code, message = Messages.get_could_not_resolve(variable.get_name()) + Logger.log_message(log_level=LoggingLevel.ERROR, code=code, message=message, + error_position=variable.get_source_position()) + return "" + + if symbol.is_state(): + return self.name(symbol) + + if symbol.is_buffer(): + if isinstance(symbol.get_type_symbol(), UnitTypeSymbol): + units_conversion_factor = UnitConverter.get_factor(symbol.get_type_symbol().unit.unit) + else: + units_conversion_factor = 1 + s = "" + if not units_conversion_factor == 1: + s += "(" + str(units_conversion_factor) + " * " + s += prefix + 'B_.' + self.buffer_value(symbol) + if symbol.has_vector_parameter(): + s += "[i]" + if not units_conversion_factor == 1: + s += ")" + return s + + variable_name = self.convert_to_cpp_name(variable.get_name()) + + if symbol.is_local() or symbol.is_inline_expression: + return variable_name + + if symbol.has_vector_parameter(): + return prefix + "get_" + variable_name + "()[i]" + + return prefix + "get_" + variable_name + "()" + + def convert_delay_variable(self, variable: ASTVariable, prefix: str =""): + """ + Converts a delay variable to GSL processable format + :param variable: variable to be converted + :return: GSL processable format of the delay variable + """ + symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE) + if symbol: + if symbol.is_state() and symbol.has_delay_parameter(): + return prefix + "get_delayed_" + variable.get_name() + "()" + raise RuntimeError(f"Cannot find the corresponding symbol for variable {variable.get_name()}") + + def convert_function_call(self, function_call: ASTFunctionCall, prefix: str = '') -> str: + """Convert a single function call to C++ GSL API syntax. + + Parameters + ---------- + function_call + The function call node to convert. + prefix + Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". + + Predefined functions will not be prefixed. + + Returns + ------- + s + The function call string in C++ syntax. + """ + function_name = function_call.get_name() + + if function_name == PredefinedFunctions.TIME_RESOLUTION: + # context dependent; we assume the template contains the necessary definitions + return "__resolution" + + if function_name == PredefinedFunctions.TIME_STEPS: + return "nest::Time(nest::Time::ms((double) {!s})).get_steps()" + + if function_name == PredefinedFunctions.MAX: + return "std::max({!s}, {!s})" + + if function_name == PredefinedFunctions.MIN: + return "std::min({!s}, {!s})" + + if function_name == PredefinedFunctions.CLIP: + # warning: the arguments of this function have been swapped and + # are therefore [v_max, v_min, v], hence its structure + return "std::min({2!s}, std::max({1!s}, {0!s}))" + + if function_name == PredefinedFunctions.EXP: + if self.is_upper_bound: + return "std::exp(std::min({!s}," + str(self.maximal_exponent) + "))" + else: + return "std::exp({!s})" + + if function_name == PredefinedFunctions.COSH: + if self.is_upper_bound: + return "std::cosh(std::min(std::abs({!s})," + str(self.maximal_exponent) + "))" + else: + return "std::cosh({!s})" + + if function_name == PredefinedFunctions.SINH: + if self.is_upper_bound: + return "std::sinh(({!s} > 0 ? 1 : -1)*std::min(std::abs({!s})," + str(self.maximal_exponent) + "))" + else: + return "std::sinh({!s})" + + if function_name == PredefinedFunctions.TANH: + return 'std::tanh({!s})' + + if function_name == PredefinedFunctions.LN: + return "std::log({!s})" + + if function_name == PredefinedFunctions.LOG10: + return "std::log10({!s})" + + if function_name == PredefinedFunctions.EXPM1: + return "numerics::expm1({!s})" + + if function_name == PredefinedFunctions.RANDOM_NORMAL: + return "(({!s}) + ({!s}) * " + prefix + "normal_dev_( nest::get_vp_specific_rng( " + prefix + "get_thread() ) ))" + + if function_name == PredefinedFunctions.RANDOM_UNIFORM: + return "(({!s}) + ({!s}) * nest::get_vp_specific_rng( " + prefix + "get_thread() )->drand())" + + if function_name == PredefinedFunctions.EMIT_SPIKE: + return "set_spiketime(nest::Time::step(origin.get_steps()+lag+1));\n" \ + "nest::SpikeEvent se;\n" \ + "nest::kernel().event_delivery_manager.send(*this, se, lag)" + + if function_name == PredefinedFunctions.DELIVER_SPIKE: + return '''set_delay( {1!s} ); +const long __delay_steps = nest::Time::delay_ms_to_steps( get_delay() ); +set_delay_steps(__delay_steps); +e.set_receiver( *__target ); +e.set_weight( {0!s} ); +// use accessor functions (inherited from Connection< >) to obtain delay in steps and rport +e.set_delay_steps( get_delay_steps() ); +e.set_rport( get_rport() ); +e();''' + + # suppress prefix for misc. predefined functions + # check if function is "predefined" purely based on the name, as we don't have access to the function symbol here + function_is_predefined = PredefinedFunctions.get_function(function_name) + if function_is_predefined: + prefix = '' + + if ASTUtils.needs_arguments(function_call): + n_args = len(function_call.get_args()) + return prefix + function_name + "(" + ", ".join(["{!s}" for _ in range(n_args)]) + ")" + + return prefix + function_name + "()" + + def array_index(self, symbol: VariableSymbol) -> str: + """ + Transforms the haded over symbol to a GSL processable format. + :param symbol: a single variable symbol + :return: the corresponding string format + """ + return "State_::" + self.convert_to_cpp_name(symbol.get_symbol_name()) + + def name(self, symbol: VariableSymbol) -> str: + """ + Transforms the given symbol to a format that can be processed by GSL. + :param symbol: a single variable symbol + :return: the corresponding string format + """ + if symbol.is_state() and not symbol.is_inline_expression: + return "ode_state[State_::" + self.convert_to_cpp_name(symbol.get_symbol_name()) + "]" + + return super().name(symbol) diff --git a/pynestml/codegeneration/latex_expression_printer.py b/pynestml/codegeneration/printers/latex_expression_printer.py similarity index 58% rename from pynestml/codegeneration/latex_expression_printer.py rename to pynestml/codegeneration/printers/latex_expression_printer.py index 2b477bdc9..b05d9ecd4 100644 --- a/pynestml/codegeneration/latex_expression_printer.py +++ b/pynestml/codegeneration/printers/latex_expression_printer.py @@ -18,7 +18,10 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.codegeneration.latex_reference_converter import LatexReferenceConverter + +from typing import Tuple + +from pynestml.codegeneration.printers.expression_printer import ExpressionPrinter from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_expression_node import ASTExpressionNode from pynestml.meta_model.ast_function_call import ASTFunctionCall @@ -27,71 +30,73 @@ from pynestml.utils.ast_utils import ASTUtils -class LatexExpressionPrinter(): - """ - Pretty printer for LaTeX. Assumes to be printing in a LaTeX environment where math mode is already on. +class LatexExpressionPrinter(ExpressionPrinter): + r""" + Expressions printer for LaTeX. Assumes to be printing in a LaTeX environment where math mode is already on. """ - def __init__(self, reference_converter=None, types_printer=None): - # type: (IReferenceConverter,TypesPrinter) -> None - # todo by kp: this should expect a ITypesPrinter as the second arg - self.reference_converter = LatexReferenceConverter() - if types_printer is not None: - self.types_printer = types_printer - else: - self.types_printer = TypesPrinter() - - def print_expression(self, node): - # type: (ASTExpressionNode) -> str - return self.__do_print(node) - if node.get_implicit_conversion_factor() is not None: - return str(node.get_implicit_conversion_factor()) + ' * (' + self.__do_print(node) + ')' - else: - return self.__do_print(node) - - def __do_print(self, node): - # type: (ASTExpressionNode) -> str + def print_expression(self, node: ASTExpressionNode, prefix: str = ""): + if node.get_implicit_conversion_factor() is not None \ + and str(node.get_implicit_conversion_factor()) not in ["1.", "1.0", "1"]: + return str(node.get_implicit_conversion_factor()) + " * (" + self.__do_print(node, prefix=prefix) + ")" + + return self.__do_print(node, prefix=prefix) + + def __do_print(self, node: ASTExpressionNode, prefix="") -> str: if isinstance(node, ASTVariable): return self.reference_converter.convert_name_reference(node) - elif isinstance(node, ASTSimpleExpression): + + if isinstance(node, ASTSimpleExpression): if node.has_unit(): - # todo by kp: this should not be done in the typesPrinter, obsolete s = "" if node.get_numeric_literal() != 1: s += "{0:E}".format(node.get_numeric_literal()) s += r"\cdot" s += self.reference_converter.convert_name_reference(node.get_variable()) return s - elif node.is_numeric_literal(): + + if node.is_numeric_literal(): return str(node.get_numeric_literal()) - elif node.is_inf_literal: + + if node.is_inf_literal: return r"\infty" - elif node.is_string(): - return self.types_printer.pretty_print(node.get_string()) - elif node.is_boolean_true: - return self.types_printer.pretty_print(True) - elif node.is_boolean_false: - return self.types_printer.pretty_print(False) - elif node.is_variable(): + + if node.is_string(): + return node.get_string() + + if node.is_boolean_true: + return self.reference_converter.convert_constant("true") + + if node.is_boolean_false: + return self.reference_converter.convert_constant("false") + + if node.is_variable(): return self.reference_converter.convert_name_reference(node.get_variable()) - elif node.is_function_call(): + + if node.is_function_call(): return self.print_function_call(node.get_function_call()) - elif isinstance(node, ASTExpression): + + raise Exception("Unknown node type") + + if isinstance(node, ASTExpression): # a unary operator if node.is_unary_operator(): op = self.reference_converter.convert_unary_op(node.get_unary_operator()) rhs = self.print_expression(node.get_expression()) return op % rhs + # encapsulated in brackets - elif node.is_encapsulated: + if node.is_encapsulated: return self.reference_converter.convert_encapsulated() % self.print_expression(node.get_expression()) + # logical not - elif node.is_logical_not: + if node.is_logical_not: op = self.reference_converter.convert_logical_not() rhs = self.print_expression(node.get_expression()) return op % rhs + # compound rhs with lhs + rhs - elif node.is_compound_expression(): + if node.is_compound_expression(): lhs = self.print_expression(node.get_lhs()) rhs = self.print_expression(node.get_rhs()) wide = False @@ -101,42 +106,27 @@ def __do_print(self, node): wide = True op = self.reference_converter.convert_binary_op(node.get_binary_operator(), wide=wide) return op % ({"lhs": lhs, "rhs": rhs}) - elif node.is_ternary_operator(): + + if node.is_ternary_operator(): condition = self.print_expression(node.get_condition()) if_true = self.print_expression(node.get_if_true()) if_not = self.print_expression(node.if_not) return self.reference_converter.convert_ternary_operator() % (condition, if_true, if_not) - else: - raise RuntimeError('Unsupported rhs in rhs pretty printer!') - def print_function_call(self, function_call): - # type: (ASTFunctionCall) -> str + raise Exception("Unknown node type") + + raise RuntimeError("Tried to print unknown expression: \"%s\"" % str(node)) + + def print_function_call(self, function_call: ASTFunctionCall) -> str: function_name = self.reference_converter.convert_function_call(function_call) if ASTUtils.needs_arguments(function_call): return function_name % self.print_function_call_argument_list(function_call) - else: - return function_name - def print_function_call_argument_list(self, function_call): - # type: (ASTFunctionCall) -> tuple of str + return function_name + + def print_function_call_argument_list(self, function_call: ASTFunctionCall) -> Tuple[str, ...]: ret = [] for arg in function_call.get_args(): ret.append(self.print_expression(arg)) - return tuple(ret) - -class TypesPrinter(object): - """ - Returns a processable format of the handed over element. - """ - - @classmethod - def pretty_print(cls, element): - assert (element is not None), \ - '(PyNestML.CodeGeneration.PrettyPrinter) No element provided (%s)!' % element - if isinstance(element, bool) and element: - return 'true' - elif isinstance(element, bool) and not element: - return 'false' - elif isinstance(element, int) or isinstance(element, float): - return str(element) + return tuple(ret) diff --git a/pynestml/codegeneration/latex_reference_converter.py b/pynestml/codegeneration/printers/latex_reference_converter.py similarity index 82% rename from pynestml/codegeneration/latex_reference_converter.py rename to pynestml/codegeneration/printers/latex_reference_converter.py index df6e8bc74..089087976 100644 --- a/pynestml/codegeneration/latex_reference_converter.py +++ b/pynestml/codegeneration/printers/latex_reference_converter.py @@ -18,40 +18,37 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + import re -from pynestml.codegeneration.i_reference_converter import IReferenceConverter -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.utils.ast_utils import ASTUtils +from pynestml.codegeneration.printers.reference_converter import ReferenceConverter from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.utils.ast_utils import ASTUtils -class LatexReferenceConverter(IReferenceConverter): +class LatexReferenceConverter(ReferenceConverter): """ ReferenceConverter for the LaTeX target. """ - def convert_unary_op(self, ast_unary_operator): + def convert_unary_op(self, ast_unary_operator) -> str: """ Convert unary operator. :param ast_unary_operator: a unary operator :type ast_unary_operator: ASTUnaryOperator - :return: pretty-printed format string - :rtype: str + :return: the corresponding string representation """ return str(ast_unary_operator) + '%s' - def convert_name_reference(self, ast_variable): + def convert_name_reference(self, ast_variable) -> str: """ Convert name reference. :param ast_variable: a single variable :type ast_variable: ASTVariable - :return: pretty-printed format string - :rtype: str + :return: the corresponding string representation """ var_name = ast_variable.get_name() var_complete_name = ast_variable.get_complete_name() @@ -118,20 +115,18 @@ def convert_name_reference(self, ast_variable): "Omega": r"\\Omega" } for symbol_find, symbol_replace in symbols.items(): - before = var_name var_name = re.sub(r"(? str: """ Convert function call. :param function_call: a function call :type function_call: ASTFunctionCall - :return: pretty-printed format string - :rtype: str + :return: the corresponding string representation """ result = function_call.get_name() @@ -151,14 +146,13 @@ def convert_function_call(self, function_call): return result - def convert_binary_op(self, ast_binary_operator, wide=False): + def convert_binary_op(self, ast_binary_operator, wide=False) -> str: """ Convert binary operator. :param ast_binary_operator: a single binary operator :type ast_binary_operator: ASTBinaryOperator - :return: pretty-printed format string - :rtype: str + :return: the corresponding string representation """ if ast_binary_operator.is_div_op: if wide: @@ -172,40 +166,38 @@ def convert_binary_op(self, ast_binary_operator, wide=False): else: return r'%(lhs)s' + str(ast_binary_operator) + r'%(rhs)s' - def convert_constant(self, constant_name): + def convert_constant(self, constant_name) -> str: """ Convert constant. :param constant_name: a constant name :type constant_name: str - :return: pretty-printed format string - :rtype: str + :return: the corresponding string representation """ return constant_name - def convert_ternary_operator(self): + def convert_ternary_operator(self) -> str: """ Convert ternary operator. - :return: pretty-printed format string - :rtype: str + :return: the corresponding string representation """ return '(' + '%s' + ')?(' + '%s' + '):(' + '%s' + ')' - def convert_logical_operator(self, op): + def convert_logical_operator(self, op) -> str: return str(op) - def convert_arithmetic_operator(self, op): + def convert_arithmetic_operator(self, op) -> str: return str(op) - def convert_encapsulated(self): + def convert_encapsulated(self) -> str: return '(%s)' - def convert_comparison_operator(self, op): + def convert_comparison_operator(self, op) -> str: return str(op) - def convert_logical_not(self): + def convert_logical_not(self) -> str: return "\neg" - def convert_bit_operator(self, op): + def convert_bit_operator(self, op) -> str: return str(op) diff --git a/pynestml/codegeneration/printers/nest2_gsl_reference_converter.py b/pynestml/codegeneration/printers/nest2_gsl_reference_converter.py new file mode 100644 index 000000000..d3fd75349 --- /dev/null +++ b/pynestml/codegeneration/printers/nest2_gsl_reference_converter.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# +# nest2_gsl_reference_converter.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.codegeneration.printers.gsl_reference_converter import GSLReferenceConverter +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.symbols.predefined_functions import PredefinedFunctions + + +class NEST2GSLReferenceConverter(GSLReferenceConverter): + """ + This class is used to convert operators and constant to the GSL (GNU Scientific Library) processable format. + """ + + def convert_function_call(self, function_call: ASTFunctionCall, prefix: str = ''): + r"""Convert a single function call to C++ GSL API syntax. + + Parameters + ---------- + function_call : ASTFunctionCall + The function call node to convert. + prefix : str + Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". + + Predefined functions will not be prefixed. + + Returns + ------- + s : str + The function call string in C++ syntax. + """ + function_name = function_call.get_name() + + if function_name == PredefinedFunctions.RANDOM_NORMAL: + return '(({!s}) + ({!s}) * ' + prefix + 'normal_dev_( nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() ) ))' + + if function_name == PredefinedFunctions.RANDOM_UNIFORM: + return '(({!s}) + ({!s}) * nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() )->drand())' + + return super().convert_function_call(function_call, prefix=prefix) diff --git a/pynestml/codegeneration/printers/nest2_reference_converter.py b/pynestml/codegeneration/printers/nest2_reference_converter.py new file mode 100644 index 000000000..360571f25 --- /dev/null +++ b/pynestml/codegeneration/printers/nest2_reference_converter.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# +# nest2_reference_converter.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.codegeneration.printers.nest_reference_converter import NESTReferenceConverter +from pynestml.symbols.predefined_functions import PredefinedFunctions + + +class NEST2ReferenceConverter(NESTReferenceConverter): + """ + This concrete reference converter is used to transfer internal names to NEST 2 syntax. + """ + + def convert_function_call(self, function_call, prefix='') -> str: + r""" + Converts a single handed over function call to C++ NEST API syntax. + + Parameters + ---------- + function_call : ASTFunctionCall + The function call node to convert. + prefix : str + Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". + + Predefined functions will not be prefixed. + + Returns + ------- + s : str + The function call string in C++ syntax. + """ + function_name = function_call.get_name() + + if function_name == PredefinedFunctions.RANDOM_NORMAL: + return '(({!s}) + ({!s}) * ' + prefix + 'normal_dev_( nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() ) ))' + + if function_name == PredefinedFunctions.RANDOM_UNIFORM: + return '(({!s}) + ({!s}) * nest::kernel().rng_manager.get_rng( ' + prefix + 'get_thread() )->drand())' + + return super().convert_function_call(function_call, prefix=prefix) diff --git a/pynestml/codegeneration/printers/nest_local_variables_reference_converter.py b/pynestml/codegeneration/printers/nest_local_variables_reference_converter.py new file mode 100644 index 000000000..6d9c86de9 --- /dev/null +++ b/pynestml/codegeneration/printers/nest_local_variables_reference_converter.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# +# nest_local_variables_reference_converter.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import re + +from pynestml.codegeneration.printers.cpp_reference_converter import CppReferenceConverter +from pynestml.codegeneration.printers.nest_reference_converter import NESTReferenceConverter +from pynestml.codegeneration.printers.unit_converter import UnitConverter +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.meta_model.ast_external_variable import ASTExternalVariable +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.symbol_table.scope import Scope +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.symbols.variable_symbol import BlockType +from pynestml.symbols.variable_symbol import VariableSymbol +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages + + +class NESTLocalVariablesReferenceConverter(NESTReferenceConverter): + r""" + Reference converter that converts state variables into names rather than getter method calls. + """ + + def convert_name_reference(self, variable: ASTVariable, prefix: str = '', with_origins=True) -> str: + """ + Converts a single variable to nest processable format. + :param variable: a single variable. + :return: a nest processable format. + """ + symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE) + if symbol is not None: + if symbol.is_state(): + temp = "" + temp += self.convert_to_cpp_name(symbol.get_symbol_name()) + temp += ('[' + variable.get_vector_parameter() + ']' if symbol.has_vector_parameter() else '') + return temp + + return super().convert_name_reference(variable, prefix, with_origins) diff --git a/pynestml/codegeneration/nest_printer.py b/pynestml/codegeneration/printers/nest_printer.py similarity index 56% rename from pynestml/codegeneration/nest_printer.py rename to pynestml/codegeneration/printers/nest_printer.py index 8df3d2daf..312ae39d3 100644 --- a/pynestml/codegeneration/nest_printer.py +++ b/pynestml/codegeneration/printers/nest_printer.py @@ -18,23 +18,16 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.codegeneration.expressions_pretty_printer import ExpressionsPrettyPrinter -from pynestml.codegeneration.nest_names_converter import NestNamesConverter -from pynestml.codegeneration.pynestml_2_nest_type_converter import PyNestml2NestTypeConverter -from pynestml.codegeneration.i_reference_converter import IReferenceConverter -from pynestml.meta_model.ast_body import ASTBody -from pynestml.meta_model.ast_expression_node import ASTExpressionNode -from pynestml.meta_model.ast_for_stmt import ASTForStmt -from pynestml.meta_model.ast_function import ASTFunction -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.variable_symbol import VariableSymbol, BlockType + +from pynestml.codegeneration.printers.expression_printer import ExpressionPrinter +from pynestml.codegeneration.printers.printer import Printer +from pynestml.codegeneration.printers.reference_converter import ReferenceConverter +from pynestml.codegeneration.printers.types_printer import TypesPrinter from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_bit_operator import ASTBitOperator from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables -from pynestml.meta_model.ast_body import ASTBody from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_data_type import ASTDataType @@ -43,6 +36,7 @@ from pynestml.meta_model.ast_else_clause import ASTElseClause from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_expression_node import ASTExpressionNode from pynestml.meta_model.ast_for_stmt import ASTForStmt from pynestml.meta_model.ast_function import ASTFunction from pynestml.meta_model.ast_function_call import ASTFunctionCall @@ -54,6 +48,7 @@ from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody from pynestml.meta_model.ast_ode_equation import ASTOdeEquation from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_kernel import ASTKernel @@ -68,110 +63,120 @@ from pynestml.meta_model.ast_update_block import ASTUpdateBlock from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_while_stmt import ASTWhileStmt +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import VariableSymbol -class NestPrinter(object): - """ - This class contains all methods as required to transform +class NestPrinter(Printer): + r""" + Printer for NEST C++ syntax. """ - def __init__(self, expression_pretty_printer, reference_convert=None): - """ - The standard constructor. - :param reference_convert: a single reference converter - :type reference_convert: IReferenceConverter - """ - if expression_pretty_printer is not None: - self.expression_pretty_printer = expression_pretty_printer - else: - self.expression_pretty_printer = ExpressionsPrettyPrinter(reference_convert) - return + def __init__(self, + reference_converter: ReferenceConverter, + types_printer: TypesPrinter, + expression_printer: ExpressionPrinter): + super().__init__(reference_converter=reference_converter, + types_printer=types_printer) + self._expression_printer = expression_printer - def print_node(self, node): - ret = '' + def print_node(self, node) -> str: if isinstance(node, ASTArithmeticOperator): - ret = self.print_arithmetic_operator(node) + return self.print_arithmetic_operator(node) if isinstance(node, ASTAssignment): - ret = self.print_assignment(node) + return self.print_assignment(node) if isinstance(node, ASTBitOperator): - ret = self.print_bit_operator(node) + return self.print_bit_operator(node) if isinstance(node, ASTBlock): - ret = self.print_block(node) + return self.print_block(node) if isinstance(node, ASTBlockWithVariables): - ret = self.print_block_with_variables(node) - if isinstance(node, ASTBody): - ret = self.print_body(node) + return self.print_block_with_variables(node) + if isinstance(node, ASTNeuronOrSynapseBody): + return self.print_neuron_or_synapse_body(node) if isinstance(node, ASTComparisonOperator): - ret = self.print_comparison_operator(node) + return self.print_comparison_operator(node) if isinstance(node, ASTCompoundStmt): - ret = self.print_compound_stmt(node) + return self.print_compound_stmt(node) if isinstance(node, ASTDataType): - ret = self.print_data_type(node) + return self.print_data_type(node) if isinstance(node, ASTDeclaration): - ret = self.print_declaration(node) + return self.print_declaration(node) if isinstance(node, ASTElifClause): - ret = self.print_elif_clause(node) + return self.print_elif_clause(node) if isinstance(node, ASTElseClause): - ret = self.print_else_clause(node) + return self.print_else_clause(node) if isinstance(node, ASTEquationsBlock): - ret = self.print_equations_block(node) + return self.print_equations_block(node) if isinstance(node, ASTExpression): - ret = self.print_expression(node) + return self.print_expression(node) if isinstance(node, ASTForStmt): - ret = self.print_for_stmt(node) + return self.print_for_stmt(node) if isinstance(node, ASTFunction): - ret = self.print_function(node) + return self.print_function(node) if isinstance(node, ASTFunctionCall): - ret = self.print_function_call(node) + return self.print_function_call(node) if isinstance(node, ASTIfClause): - ret = self.print_if_clause(node) + return self.print_if_clause(node) if isinstance(node, ASTIfStmt): - ret = self.print_if_stmt(node) + return self.print_if_stmt(node) if isinstance(node, ASTInputBlock): - ret = self.print_input_block(node) + return self.print_input_block(node) if isinstance(node, ASTInputPort): - ret = self.print_input_port(node) + return self.print_input_port(node) if isinstance(node, ASTInputQualifier): - ret = self.print_input_qualifier(node) + return self.print_input_qualifier(node) if isinstance(node, ASTLogicalOperator): - ret = self.print_logical_operator(node) + return self.print_logical_operator(node) if isinstance(node, ASTNestMLCompilationUnit): - ret = self.print_compilation_unit(node) + return self.print_compilation_unit(node) if isinstance(node, ASTNeuron): - ret = self.print_neuron(node) + return self.print_neuron(node) if isinstance(node, ASTOdeEquation): - ret = self.print_ode_equation(node) + return self.print_ode_equation(node) if isinstance(node, ASTInlineExpression): - ret = self.print_inline_expression(node) + return self.print_inline_expression(node) if isinstance(node, ASTKernel): - ret = self.print_kernel(node) + return self.print_kernel(node) if isinstance(node, ASTOutputBlock): - ret = self.print_output_block(node) + return self.print_output_block(node) if isinstance(node, ASTParameter): - ret = self.print_parameter(node) + return self.print_parameter(node) if isinstance(node, ASTReturnStmt): - ret = self.print_return_stmt(node) + return self.print_return_stmt(node) if isinstance(node, ASTSimpleExpression): - ret = self.print_simple_expression(node) + return self.print_simple_expression(node) if isinstance(node, ASTSmallStmt): - ret = self.print_small_stmt(node) + return self.print_small_stmt(node) if isinstance(node, ASTUnaryOperator): - ret = self.print_unary_operator(node) + return self.print_unary_operator(node) if isinstance(node, ASTUnitType): - ret = self.print_unit_type(node) + return self.print_unit_type(node) if isinstance(node, ASTUpdateBlock): - ret = self.print_update_block(node) + return self.print_update_block(node) if isinstance(node, ASTVariable): - ret = self.print_variable(node) + return self.print_variable(node) if isinstance(node, ASTWhileStmt): - ret = self.print_while_stmt(node) + return self.print_while_stmt(node) if isinstance(node, ASTStmt): - ret = self.print_stmt(node) - return ret + return self.print_stmt(node) + return '' + + def print_simple_expression(self, node, prefix=""): + return self.print_expression(node, prefix=prefix) + + def print_small_stmt(self, node, prefix="") -> str: + if node.is_assignment(): + return self.print_assignment(node.assignment, prefix=prefix) - def print_assignment(self, node, prefix=""): - # type: (ASTAssignment) -> str - ret = self.print_node(node.lhs) + ' ' + def print_stmt(self, node, prefix="") -> str: + if node.is_small_stmt: + return self.print_small_stmt(node.small_stmt, prefix=prefix) + + def print_assignment(self, node, prefix="") -> str: + symbol = node.get_scope().resolve_to_symbol( + node.lhs.get_complete_name(), SymbolKind.VARIABLE) + ret = self.reference_converter.print_origin( + symbol) + self.reference_converter.name(symbol) + ' ' if node.is_compound_quotient: ret += '/=' elif node.is_compound_product: @@ -185,166 +190,105 @@ def print_assignment(self, node, prefix=""): ret += ' ' + self.print_node(node.rhs) return ret - def print_variable(self, node): - # type: (ASTVariable) -> str - ret = node.name + def print_variable(self, node: ASTVariable) -> str: + symbol = node.get_scope().resolve_to_symbol( + node.lhs.get_complete_name(), SymbolKind.VARIABLE) + ret = self.reference_converter.print_origin(symbol) + node.name for i in range(1, node.differential_order + 1): ret += "__d" return ret - def print_expression(self, node, prefix=""): - # type: (ASTExpressionNode) -> str - """ - Pretty Prints the handed over rhs to a nest readable format. - :param node: a single meta_model node. - :type node: ASTExpressionNode - :return: the corresponding string representation - :rtype: str - """ - return self.expression_pretty_printer.print_expression(node, prefix=prefix) - - def print_method_call(self, node): - # type: (ASTFunctionCall) -> str - """ - Prints a single handed over function call. - :param node: a single function call. - :type node: ASTFunctionCall - :return: the corresponding string representation. - :rtype: str - """ - return self.expression_pretty_printer.print_function_call(node) - - @classmethod - def print_comparison_operator(cls, for_stmt): + def print_comparison_operator(self, for_stmt) -> str: """ Prints a single handed over comparison operator for a for stmt to a Nest processable format. :param for_stmt: a single for stmt :type for_stmt: ASTForStmt :return: a string representation - :rtype: str """ step = for_stmt.get_step() if step < 0: return '>' - elif step > 0: + + if step > 0: return '<' - else: - return '!=' - @classmethod - def print_step(cls, for_stmt): + return '!=' + + def print_step(self, for_stmt) -> str: """ Prints the step length to a nest processable format. :param for_stmt: a single for stmt :type for_stmt: ASTForStmt :return: a string representation - :rtype: str """ assert isinstance(for_stmt, ASTForStmt), \ '(PyNestML.CodeGenerator.Printer) No or wrong type of for-stmt provided (%s)!' % type(for_stmt) return for_stmt.get_step() - @classmethod - def print_origin(cls, variable_symbol, prefix=''): - """ - Returns a prefix corresponding to the origin of the variable symbol. - :param variable_symbol: a single variable symbol. - :type variable_symbol: VariableSymbol - :return: the corresponding prefix - :rtype: str - """ - assert isinstance(variable_symbol, VariableSymbol), \ - '(PyNestML.CodeGenerator.Printer) No or wrong type of variable symbol provided (%s)!' % type( - variable_symbol) - - if variable_symbol.block_type == BlockType.STATE: - return prefix + 'S_.' - - if variable_symbol.block_type == BlockType.INITIAL_VALUES: - return prefix + 'S_.' - - if variable_symbol.block_type == BlockType.EQUATION: - return prefix + 'S_.' - - if variable_symbol.block_type == BlockType.PARAMETERS: - return prefix + 'P_.' - - if variable_symbol.block_type == BlockType.INTERNALS: - return prefix + 'V_.' - - if variable_symbol.block_type == BlockType.INPUT_BUFFER_CURRENT: - return prefix + 'B_.' - - if variable_symbol.block_type == BlockType.INPUT_BUFFER_SPIKE: - return prefix + 'B_.' - - return '' - - @classmethod - def print_output_event(cls, ast_body): + def print_output_event(self, ast_body: ASTNeuronOrSynapseBody) -> str: """ - For the handed over neuron, this operations checks of output event shall be preformed. + For the handed over neuron, print its defined output type. :param ast_body: a single neuron body - :type ast_body: ASTBody :return: the corresponding representation of the event - :rtype: str """ - assert (ast_body is not None and isinstance(ast_body, ASTBody)), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of body provided (%s)!' % type(ast_body) + assert (ast_body is not None and isinstance(ast_body, ASTNeuronOrSynapseBody)), \ + '(PyNestML.CodeGeneration.Printer) No or wrong type of body provided (%s)!' % type( + ast_body) outputs = ast_body.get_output_blocks() - if len(outputs) > 0: - output = outputs[0] - if output.is_spike(): - return 'nest::SpikeEvent' - elif output.is_current(): - return 'nest::CurrentEvent' - else: - raise RuntimeError('Unexpected output type. Must be current or spike, is %s.' % str(output)) - else: + if len(outputs) == 0: # no output port defined in the model: pretend dummy spike output port to obtain usable model return 'nest::SpikeEvent' - @classmethod - def print_buffer_initialization(cls, variable_symbol): + output = outputs[0] + if output.is_spike(): + return 'nest::SpikeEvent' + + if output.is_continuous(): + return 'nest::CurrentEvent' + + raise RuntimeError( + 'Unexpected output type. Must be continuous or spike, is %s.' % str(output)) + + def print_buffer_initialization(self, variable_symbol) -> str: """ Prints the buffer initialization. :param variable_symbol: a single variable symbol. :type variable_symbol: VariableSymbol :return: a buffer initialization - :rtype: str """ return 'get_' + variable_symbol.get_symbol_name() + '().clear(); //includes resize' - @classmethod - def print_function_declaration(cls, ast_function): + def print_function_declaration(self, ast_function) -> str: """ Returns a nest processable function declaration head, i.e. the part which appears in the .h file. :param ast_function: a single function. :type ast_function: ASTFunction :return: the corresponding string representation. - :rtype: str """ from pynestml.meta_model.ast_function import ASTFunction from pynestml.symbols.symbol import SymbolKind assert (ast_function is not None and isinstance(ast_function, ASTFunction)), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_function provided (%s)!' % type(ast_function) - function_symbol = ast_function.get_scope().resolve_to_symbol(ast_function.get_name(), SymbolKind.FUNCTION) + '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_function provided (%s)!' % type( + ast_function) + function_symbol = ast_function.get_scope().resolve_to_symbol( + ast_function.get_name(), SymbolKind.FUNCTION) if function_symbol is None: - raise RuntimeError('Cannot resolve the method ' + ast_function.get_name()) + raise RuntimeError( + 'Cannot resolve the method ' + ast_function.get_name()) declaration = ast_function.print_comment('//') + '\n' - declaration += PyNestml2NestTypeConverter.convert(function_symbol.get_return_type()).replace('.', '::') + declaration += self.types_printer.convert( + function_symbol.get_return_type()).replace('.', '::') declaration += ' ' declaration += ast_function.get_name() + '(' for typeSym in function_symbol.get_parameter_types(): - declaration += PyNestml2NestTypeConverter.convert(typeSym) + declaration += self.types_printer.convert(typeSym) if function_symbol.get_parameter_types().index(typeSym) < len( function_symbol.get_parameter_types()) - 1: declaration += ', ' declaration += ') const\n' return declaration - @classmethod - def print_function_definition(cls, ast_function, namespace): + def print_function_definition(self, ast_function, namespace) -> str: """ Returns a nest processable function definition, i.e. the part which appears in the .cpp file. :param ast_function: a single function. @@ -352,28 +296,32 @@ def print_function_definition(cls, ast_function, namespace): :param namespace: the namespace in which this function is defined in :type namespace: str :return: the corresponding string representation. - :rtype: str """ assert isinstance(ast_function, ASTFunction), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_function provided (%s)!' % type(ast_function) + '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_function provided (%s)!' % type( + ast_function) assert isinstance(namespace, str), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of namespace provided (%s)!' % type(namespace) - function_symbol = ast_function.get_scope().resolve_to_symbol(ast_function.get_name(), SymbolKind.FUNCTION) + '(PyNestML.CodeGeneration.Printer) No or wrong type of namespace provided (%s)!' % type( + namespace) + function_symbol = ast_function.get_scope().resolve_to_symbol( + ast_function.get_name(), SymbolKind.FUNCTION) if function_symbol is None: - raise RuntimeError('Cannot resolve the method ' + ast_function.get_name()) + raise RuntimeError( + 'Cannot resolve the method ' + ast_function.get_name()) # first collect all parameters params = list() for param in ast_function.get_parameters(): params.append(param.get_name()) declaration = ast_function.print_comment('//') + '\n' - declaration += PyNestml2NestTypeConverter.convert(function_symbol.get_return_type()).replace('.', '::') + declaration += self.types_printer.convert( + function_symbol.get_return_type()).replace('.', '::') declaration += ' ' if namespace is not None: declaration += namespace + '::' declaration += ast_function.get_name() + '(' for typeSym in function_symbol.get_parameter_types(): # create the type name combination, e.g. double Tau - declaration += PyNestml2NestTypeConverter.convert(typeSym) + ' ' + \ + declaration += self.types_printer.convert(typeSym) + ' ' + \ params[function_symbol.get_parameter_types().index(typeSym)] # if not the last component, separate by ',' if function_symbol.get_parameter_types().index(typeSym) < \ @@ -382,25 +330,25 @@ def print_function_definition(cls, ast_function, namespace): declaration += ') const\n' return declaration - def print_buffer_array_getter(self, ast_buffer): + def print_buffer_array_getter(self, ast_buffer) -> str: """ Returns a string containing the nest declaration for a multi-receptor spike buffer. :param ast_buffer: a single buffer Variable Symbol :type ast_buffer: VariableSymbol :return: a string representation of the getter - :rtype: str """ assert (ast_buffer is not None and isinstance(ast_buffer, VariableSymbol)), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type(ast_buffer) - if ast_buffer.is_spike_buffer() and ast_buffer.is_inhibitory() and ast_buffer.is_excitatory(): - return 'inline ' + PyNestml2NestTypeConverter.convert(ast_buffer.get_type_symbol()) + '&' + ' get_' \ + '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type( + ast_buffer) + if ast_buffer.is_spike_input_port() and ast_buffer.is_inhibitory() and ast_buffer.is_excitatory(): + return 'inline ' + self.types_printer.convert(ast_buffer.get_type_symbol()) + '&' + ' get_' \ + ast_buffer.get_symbol_name() + '() {' + \ - ' return spike_inputs_[' + ast_buffer.get_symbol_name().upper() + ' - 1]; }' + ' return spike_inputs_[' + \ + ast_buffer.get_symbol_name().upper() + ' - 1]; }' else: return self.print_buffer_getter(ast_buffer, True) - @classmethod - def print_buffer_getter(cls, ast_buffer, is_in_struct=False): + def print_buffer_getter(self, ast_buffer, is_in_struct=False) -> str: """ Returns a string representation declaring a buffer getter as required in nest. :param ast_buffer: a single variable symbol representing a buffer. @@ -408,19 +356,21 @@ def print_buffer_getter(cls, ast_buffer, is_in_struct=False): :param is_in_struct: indicates whether this getter is used in a struct or not :type is_in_struct: bool :return: a string representation of the getter. - :rtype: str """ assert (ast_buffer is not None and isinstance(ast_buffer, VariableSymbol)), \ - '(PyNestMl.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type(ast_buffer) + '(PyNestMl.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type( + ast_buffer) assert (is_in_struct is not None and isinstance(is_in_struct, bool)), \ '(PyNestMl.CodeGeneration.Printer) No or wrong type of is-in-struct provided (%s)!' % type(is_in_struct) declaration = 'inline ' if ast_buffer.has_vector_parameter(): declaration += 'std::vector<' - declaration += PyNestml2NestTypeConverter.convert(ast_buffer.get_type_symbol()) + declaration += self.types_printer.convert( + ast_buffer.get_type_symbol()) declaration += '> &' else: - declaration += PyNestml2NestTypeConverter.convert(ast_buffer.get_type_symbol()) + '&' + declaration += self.types_printer.convert( + ast_buffer.get_type_symbol()) + '&' declaration += ' get_' + ast_buffer.get_symbol_name() + '() {' if is_in_struct: declaration += 'return ' + ast_buffer.get_symbol_name() + ';' @@ -429,49 +379,122 @@ def print_buffer_getter(cls, ast_buffer, is_in_struct=False): declaration += '}' return declaration - @classmethod - def print_buffer_declaration_value(cls, ast_buffer): + def print_buffer_declaration_value(self, ast_buffer: VariableSymbol) -> str: """ Returns a string representation for the declaration of a buffer's value. :param ast_buffer: a single buffer variable symbol - :type ast_buffer: VariableSymbol :return: the corresponding string representation - :rtype: str """ - assert isinstance(ast_buffer, VariableSymbol), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type(ast_buffer) if ast_buffer.has_vector_parameter(): - return 'std::vector ' + NestNamesConverter.buffer_value(ast_buffer) - else: - return 'double ' + NestNamesConverter.buffer_value(ast_buffer) + return 'std::vector ' + self.reference_converter.buffer_value(ast_buffer) + + return 'double ' + self.reference_converter.buffer_value(ast_buffer) - @classmethod - def print_buffer_declaration(cls, ast_buffer): + def print_buffer_declaration(self, ast_buffer) -> str: """ Returns a string representation for the declaration of a buffer. :param ast_buffer: a single buffer variable symbol :type ast_buffer: VariableSymbol :return: the corresponding string representation - :rtype: str """ assert isinstance(ast_buffer, VariableSymbol), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type(ast_buffer) + '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type( + ast_buffer) if ast_buffer.has_vector_parameter(): - buffer_type = 'std::vector< ' + PyNestml2NestTypeConverter.convert(ast_buffer.get_type_symbol()) + ' >' + buffer_type = 'std::vector< ' + \ + self.types_printer.convert(ast_buffer.get_type_symbol()) + ' >' else: - buffer_type = PyNestml2NestTypeConverter.convert(ast_buffer.get_type_symbol()) + buffer_type = self.types_printer.convert( + ast_buffer.get_type_symbol()) buffer_type.replace(".", "::") return buffer_type + " " + ast_buffer.get_symbol_name() - @classmethod - def print_buffer_declaration_header(cls, ast_buffer): + def print_buffer_declaration_header(self, ast_buffer) -> str: """ Prints the comment as stated over the buffer declaration. :param ast_buffer: a single buffer variable symbol. - :type ast_buffer: VariableSymbol :return: the corresponding string representation - :rtype: str """ assert isinstance(ast_buffer, VariableSymbol), \ - '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type(ast_buffer) - return '//!< Buffer incoming ' + ast_buffer.get_type_symbol().get_symbol_name() + 's through delay, as sum' + '(PyNestML.CodeGeneration.Printer) No or wrong type of ast_buffer symbol provided (%s)!' % type( + ast_buffer) + return '//!< Buffer for input (type: ' + ast_buffer.get_type_symbol().get_symbol_name() + ')' + + def print_vector_size_parameter(self, variable: VariableSymbol) -> str: + """ + Prints NEST compatible vector size parameter + :param variable: Vector variable + :return: vector size parameter + """ + vector_parameter = variable.get_vector_parameter() + vector_parameter_var = ASTVariable( + vector_parameter, scope=variable.get_corresponding_scope()) + symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(), + SymbolKind.VARIABLE) + vector_param = "" + if symbol is not None: + # size parameter is a variable + vector_param += self.reference_converter.print_origin( + symbol) + vector_parameter + else: + # size parameter is an integer + vector_param += vector_parameter + + return vector_param + + def print_vector_declaration(self, variable: VariableSymbol) -> str: + """ + Prints the vector declaration + :param variable: Vector variable + :return: the corresponding vector declaration statement + """ + assert isinstance(variable, VariableSymbol), \ + '(PyNestML.CodeGeneration.Printer) No or wrong type of variable symbol provided (%s)!' % type( + variable) + + decl_str = self.reference_converter.print_origin(variable) + variable.get_symbol_name() + \ + ".resize(" + self.print_vector_size_parameter(variable) + ", " + \ + self.print_expression(variable.get_declaring_expression()) + \ + ");" + + return decl_str + + def print_delay_parameter(self, variable: VariableSymbol) -> str: + """ + Prints the delay parameter + :param variable: Variable with delay parameter + :return: the corresponding delay parameter + """ + assert isinstance(variable, VariableSymbol), \ + '(PyNestML.CodeGeneration.Printer) No or wrong type of variable symbol provided (%s)!' % type( + variable) + delay_parameter = variable.get_delay_parameter() + delay_parameter_var = ASTVariable( + delay_parameter, scope=variable.get_corresponding_scope()) + symbol = delay_parameter_var.get_scope().resolve_to_symbol(delay_parameter_var.get_complete_name(), + SymbolKind.VARIABLE) + if symbol is not None: + # delay parameter is a variable + return self.reference_converter.print_origin(symbol) + delay_parameter + return delay_parameter + + def print_expression(self, node: ASTExpressionNode, prefix: str = "", with_origins=True) -> str: + """ + Prints the handed over rhs to a nest readable format. + :param node: a single meta_model node. + :type node: ASTExpressionNode + :return: the corresponding string representation + """ + return self._expression_printer.print_expression(node, prefix=prefix, with_origins=with_origins) + + def print_function_call(self, node: ASTFunctionCall) -> str: + """ + Prints a single handed over function call. + :param node: a single function call. + :type node: ASTFunctionCall + :return: the corresponding string representation. + """ + return self._expression_printer.print_function_call(node) + + def print_origin(self, variable_symbol, prefix='') -> str: + return self.reference_converter.print_origin(variable_symbol) diff --git a/pynestml/codegeneration/printers/nest_reference_converter.py b/pynestml/codegeneration/printers/nest_reference_converter.py new file mode 100644 index 000000000..23c3619dc --- /dev/null +++ b/pynestml/codegeneration/printers/nest_reference_converter.py @@ -0,0 +1,315 @@ +# -*- coding: utf-8 -*- +# +# nest_reference_converter.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import re + +from pynestml.codegeneration.printers.cpp_reference_converter import CppReferenceConverter +from pynestml.codegeneration.printers.unit_converter import UnitConverter +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.meta_model.ast_external_variable import ASTExternalVariable +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.symbol_table.scope import Scope +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.symbols.variable_symbol import BlockType +from pynestml.symbols.variable_symbol import VariableSymbol +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages + + +class NESTReferenceConverter(CppReferenceConverter): + r""" + Reference converter for C++ syntax and using the NEST API. + """ + + def convert_function_call(self, function_call: ASTFunctionCall, prefix: str = '') -> str: + """ + Converts a single handed over function call to C++ NEST API syntax. + + Parameters + ---------- + function_call + The function call node to convert. + prefix + Optional string that will be prefixed to the function call. For example, to refer to a function call in the class "node", use a prefix equal to "node." or "node->". + + Predefined functions will not be prefixed. + + Returns + ------- + s + The function call string in C++ syntax. + """ + function_name = function_call.get_name() + + if function_name == 'and': + return '&&' + + if function_name == 'or': + return '||' + + if function_name == PredefinedFunctions.TIME_RESOLUTION: + # context dependent; we assume the template contains the necessary definitions + return '__resolution' + + if function_name == PredefinedFunctions.TIME_STEPS: + return 'nest::Time(nest::Time::ms((double) ({!s}))).get_steps()' + + if function_name == PredefinedFunctions.CLIP: + # warning: the arguments of this function must swapped and + # are therefore [v_max, v_min, v], hence its structure + return 'std::min({2!s}, std::max({1!s}, {0!s}))' + + if function_name == PredefinedFunctions.MAX: + return 'std::max({!s}, {!s})' + + if function_name == PredefinedFunctions.MIN: + return 'std::min({!s}, {!s})' + + if function_name == PredefinedFunctions.EXP: + return 'std::exp({!s})' + + if function_name == PredefinedFunctions.LN: + return 'std::log({!s})' + + if function_name == PredefinedFunctions.LOG10: + return 'std::log10({!s})' + + if function_name == PredefinedFunctions.COSH: + return 'std::cosh({!s})' + + if function_name == PredefinedFunctions.SINH: + return 'std::sinh({!s})' + + if function_name == PredefinedFunctions.TANH: + return 'std::tanh({!s})' + + if function_name == PredefinedFunctions.EXPM1: + return 'numerics::expm1({!s})' + + if function_name == PredefinedFunctions.RANDOM_NORMAL: + return '(({!s}) + ({!s}) * ' + prefix + 'normal_dev_( nest::get_vp_specific_rng( ' + prefix + 'get_thread() ) ))' + + if function_name == PredefinedFunctions.RANDOM_UNIFORM: + return '(({!s}) + ({!s}) * nest::get_vp_specific_rng( ' + prefix + 'get_thread() )->drand())' + + if function_name == PredefinedFunctions.EMIT_SPIKE: + return 'set_spiketime(nest::Time::step(origin.get_steps()+lag+1));\n' \ + 'nest::SpikeEvent se;\n' \ + 'nest::kernel().event_delivery_manager.send(*this, se, lag)' + + if function_name == PredefinedFunctions.PRINT: + return 'std::cout << {!s}' + + if function_name == PredefinedFunctions.PRINTLN: + return 'std::cout << {!s} << std::endl' + + if function_name == PredefinedFunctions.DELIVER_SPIKE: + return ''' + set_delay( {1!s} ); + const long __delay_steps = nest::Time::delay_ms_to_steps( get_delay() ); + set_delay_steps(__delay_steps); + e.set_receiver( *__target ); + e.set_weight( {0!s} ); + // use accessor functions (inherited from Connection< >) to obtain delay in steps and rport + e.set_delay_steps( get_delay_steps() ); + e.set_rport( get_rport() ); +e(); +''' + + # suppress prefix for misc. predefined functions + # check if function is "predefined" purely based on the name, as we don't have access to the function symbol here + function_is_predefined = PredefinedFunctions.get_function(function_name) + if function_is_predefined: + prefix = '' + + if ASTUtils.needs_arguments(function_call): + n_args = len(function_call.get_args()) + return prefix + function_name + '(' + ', '.join(['{!s}' for _ in range(n_args)]) + ')' + return prefix + function_name + '()' + + def convert_name_reference(self, variable: ASTVariable, prefix: str = '', with_origins=True) -> str: + """ + Converts a single variable to nest processable format. + :param variable: a single variable. + :return: a nest processable format. + """ + if isinstance(variable, ASTExternalVariable): + _name = str(variable) + if variable.get_alternate_name(): + # the disadvantage of this approach is that the time the value is to be obtained is not explicitly specified, so we will actually get the value at the end of the min_delay timestep + return "((POST_NEURON_TYPE*)(__target))->get_" + variable.get_alternate_name() + "()" + + return "((POST_NEURON_TYPE*)(__target))->get_" + _name + "(_tr_t)" + + if variable.get_name() == PredefinedVariables.E_CONSTANT: + return "numerics::e" + + symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE) + if symbol is None: + # test if variable name can be resolved to a type + if PredefinedUnits.is_unit(variable.get_complete_name()): + return str(UnitConverter.get_factor(PredefinedUnits.get_unit(variable.get_complete_name()).get_unit())) + + code, message = Messages.get_could_not_resolve(variable.get_name()) + Logger.log_message(log_level=LoggingLevel.ERROR, code=code, message=message, + error_position=variable.get_source_position()) + return "" + + vector_param = "" + if symbol.has_vector_parameter(): + vector_param = "[" + variable.get_vector_parameter() + "]" + + # if symbol.is_local(): + # return variable.get_name() + vector_param + + if symbol.is_buffer(): + if isinstance(symbol.get_type_symbol(), UnitTypeSymbol): + units_conversion_factor = UnitConverter.get_factor(symbol.get_type_symbol().unit.unit) + else: + units_conversion_factor = 1 + s = "" + if not units_conversion_factor == 1: + s += "(" + str(units_conversion_factor) + " * " + if with_origins: + s += self.print_origin(symbol, prefix=prefix) + s += vector_param + s += self.buffer_value(symbol) + if not units_conversion_factor == 1: + s += ")" + return s + + if symbol.is_inline_expression: + return self.getter(symbol) + "()" + vector_param + + assert not symbol.is_kernel(), "NEST reference converter cannot print kernel; kernel should have been " \ + "converted during code generation code generation " + + if symbol.is_state() or symbol.is_inline_expression: + return self.getter(symbol) + "()" + vector_param + + variable_name = self.convert_to_cpp_name(variable.get_complete_name()) + if symbol.is_local(): + return variable_name + vector_param + + return (self.print_origin(symbol, prefix=prefix) if with_origins else '') + \ + self.name(symbol) + vector_param + + def convert_delay_variable(self, variable: ASTVariable, prefix=''): + """ + Converts a delay variable to NEST processable format + :param variable: + :return: + """ + symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE) + if symbol: + if symbol.is_state() and symbol.has_delay_parameter(): + return "get_delayed_" + variable.get_name() + "()" + return "" + + def __get_unit_name(self, variable: ASTVariable): + assert variable.get_scope() is not None, "Undeclared variable: " + variable.get_complete_name() + + variable_name = self.convert_to_cpp_name(variable.get_complete_name()) + symbol = variable.get_scope().resolve_to_symbol(variable_name, SymbolKind.VARIABLE) + if isinstance(symbol.get_type_symbol(), UnitTypeSymbol): + return symbol.get_type_symbol().unit.unit.to_string() + + return '' + + def convert_print_statement(self, function_call: ASTFunctionCall) -> str: + r""" + A wrapper function to convert arguments of a print or println functions + :param function_call: print function call + :return: the converted print string with corresponding variables, if any + """ + stmt = function_call.get_args()[0].get_string() + stmt = stmt[stmt.index('"') + 1: stmt.rindex('"')] # Remove the double quotes from the string + scope = function_call.get_scope() + return self.__convert_print_statement_str(stmt, scope) + + def __convert_print_statement_str(self, stmt: str, scope: Scope) -> str: + r""" + Converts the string argument of the print or println function to NEST processable format + Variables are resolved to NEST processable format and printed with physical units as mentioned in model, separated by a space + + .. code-block:: nestml + + print("Hello World") + + .. code-block:: C++ + + std::cout << "Hello World"; + + .. code-block:: nestml + + print("Membrane potential = {V_m}") + + .. code-block:: C++ + + std::cout << "Membrane potential = " << V_m << " mV"; + + :param stmt: argument to the print or println function + :param scope: scope of the variables in the argument, if any + :return: the converted string to NEST + """ + pattern = re.compile(r'\{[a-zA-Z_][a-zA-Z0-9_]*\}') # Match the variables enclosed within '{ }' + match = pattern.search(stmt) + if match: + var_name = match.group(0)[match.group(0).find('{') + 1:match.group(0).find('}')] + left, right = stmt.split(match.group(0), 1) # Split on the first occurrence of a variable + fun_left = (lambda l: self.__convert_print_statement_str(l, scope) + ' << ' if l else '') + fun_right = (lambda r: ' << ' + self.__convert_print_statement_str(r, scope) if r else '') + ast_var = ASTVariable(var_name, scope=scope) + right = ' ' + self.__get_unit_name(ast_var) + right # concatenate unit separated by a space with the right part of the string + return fun_left(left) + self.convert_name_reference(ast_var) + fun_right(right) + + return '"' + stmt + '"' # format bare string in C++ (add double quotes) + + def print_origin(self, variable_symbol: VariableSymbol, prefix: str = '') -> str: + """ + Returns a prefix corresponding to the origin of the variable symbol. + :param variable_symbol: a single variable symbol. + :return: the corresponding prefix + """ + if variable_symbol.block_type == BlockType.STATE: + return prefix + 'S_.' + + if variable_symbol.block_type == BlockType.EQUATION: + return prefix + 'S_.' + + if variable_symbol.block_type == BlockType.PARAMETERS: + return prefix + 'P_.' + + if variable_symbol.block_type == BlockType.COMMON_PARAMETERS: + return prefix + 'cp.' + + if variable_symbol.block_type == BlockType.INTERNALS: + return prefix + 'V_.' + + if variable_symbol.block_type == BlockType.INPUT: + return prefix + 'B_.' + + return '' diff --git a/pynestml/utils/ast_nestml_printer.py b/pynestml/codegeneration/printers/nestml_printer.py similarity index 76% rename from pynestml/utils/ast_nestml_printer.py rename to pynestml/codegeneration/printers/nestml_printer.py index 2c5c6099c..588872757 100644 --- a/pynestml/utils/ast_nestml_printer.py +++ b/pynestml/codegeneration/printers/nestml_printer.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# ast_nestml_printer.py +# nestml_printer.py # # This file is part of NEST. # @@ -19,12 +19,12 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from pynestml.codegeneration.printers.printer import Printer from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_bit_operator import ASTBitOperator from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables -from pynestml.meta_model.ast_body import ASTBody from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_data_type import ASTDataType @@ -44,15 +44,18 @@ from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody from pynestml.meta_model.ast_ode_equation import ASTOdeEquation from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_output_block import ASTOutputBlock from pynestml.meta_model.ast_parameter import ASTParameter +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock from pynestml.meta_model.ast_return_stmt import ASTReturnStmt from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator from pynestml.meta_model.ast_unit_type import ASTUnitType from pynestml.meta_model.ast_update_block import ASTUpdateBlock @@ -60,10 +63,9 @@ from pynestml.meta_model.ast_while_stmt import ASTWhileStmt -class ASTNestMLPrinter(object): - """ - This class can be used to print any ast node to a human readable and NestML conform syntax. The entry point is - the print_node() operation. +class NESTMLPrinter(Printer): + r""" + This class can be used to print any ASTNode to NESTML syntax. """ tab_size = 2 # type: int # the indentation level, change if required @@ -75,87 +77,132 @@ def print_node(self, node): ret = '' if isinstance(node, ASTArithmeticOperator): ret = self.print_arithmetic_operator(node) + if isinstance(node, ASTAssignment): ret = self.print_assignment(node) + if isinstance(node, ASTBitOperator): ret = self.print_bit_operator(node) + if isinstance(node, ASTBlock): ret = self.print_block(node) + if isinstance(node, ASTBlockWithVariables): ret = self.print_block_with_variables(node) - if isinstance(node, ASTBody): - ret = self.print_body(node) + + if isinstance(node, ASTNeuronOrSynapseBody): + ret = self.print_neuron_or_synapse_body(node) + if isinstance(node, ASTComparisonOperator): ret = self.print_comparison_operator(node) + if isinstance(node, ASTCompoundStmt): ret = self.print_compound_stmt(node) + if isinstance(node, ASTDataType): ret = self.print_data_type(node) + if isinstance(node, ASTDeclaration): ret = self.print_declaration(node) + if isinstance(node, ASTElifClause): ret = self.print_elif_clause(node) + if isinstance(node, ASTElseClause): ret = self.print_else_clause(node) + if isinstance(node, ASTEquationsBlock): ret = self.print_equations_block(node) + if isinstance(node, ASTExpression): ret = self.print_expression(node) + if isinstance(node, ASTForStmt): ret = self.print_for_stmt(node) + if isinstance(node, ASTFunction): ret = self.print_function(node) + if isinstance(node, ASTFunctionCall): ret = self.print_function_call(node) + if isinstance(node, ASTIfClause): ret = self.print_if_clause(node) + if isinstance(node, ASTIfStmt): ret = self.print_if_stmt(node) + if isinstance(node, ASTInputBlock): ret = self.print_input_block(node) + if isinstance(node, ASTInputPort): ret = self.print_input_port(node) + if isinstance(node, ASTInputQualifier): ret = self.print_input_qualifier(node) + if isinstance(node, ASTLogicalOperator): ret = self.print_logical_operator(node) + if isinstance(node, ASTNestMLCompilationUnit): ret = self.print_compilation_unit(node) + if isinstance(node, ASTNeuron): ret = self.print_neuron(node) + + if isinstance(node, ASTSynapse): + ret = self.print_synapse(node) + if isinstance(node, ASTOdeEquation): ret = self.print_ode_equation(node) + if isinstance(node, ASTInlineExpression): ret = self.print_inline_expression(node) + if isinstance(node, ASTKernel): ret = self.print_kernel(node) + if isinstance(node, ASTOutputBlock): ret = self.print_output_block(node) + if isinstance(node, ASTParameter): ret = self.print_parameter(node) + if isinstance(node, ASTReturnStmt): ret = self.print_return_stmt(node) + if isinstance(node, ASTSimpleExpression): ret = self.print_simple_expression(node) + if isinstance(node, ASTSmallStmt): ret = self.print_small_stmt(node) + if isinstance(node, ASTUnaryOperator): ret = self.print_unary_operator(node) + if isinstance(node, ASTUnitType): ret = self.print_unit_type(node) + if isinstance(node, ASTUpdateBlock): ret = self.print_update_block(node) + + if isinstance(node, ASTOnReceiveBlock): + ret = self.print_on_receive_block(node) + if isinstance(node, ASTVariable): ret = self.print_variable(node) + if isinstance(node, ASTWhileStmt): ret = self.print_while_stmt(node) + if isinstance(node, ASTStmt): ret = self.print_stmt(node) + ret = filter_subsequent_whitespaces(ret) + return ret - def print_neuron(self, node): - # type: (ASTNeuron) -> str + def print_neuron(self, node: ASTNeuron) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) self.inc_indent() ret += 'neuron ' + node.get_name() + ':' + print_sl_comment(node.in_comment) @@ -164,26 +211,37 @@ def print_neuron(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - @classmethod - def print_arithmetic_operator(cls, node): - # type: (ASTArithmeticOperator) -> str + def print_synapse(self, node: ASTNeuron) -> str: + ret = print_ml_comments(node.pre_comments, self.indent, False) + self.inc_indent() + ret += 'synapse ' + node.get_name() + ':' + print_sl_comment(node.in_comment) + ret += '\n' + self.print_node(node.get_body()) + 'end' + '\n' + self.dec_indent() + ret += print_ml_comments(node.post_comments, self.indent, True) + return ret + + def print_arithmetic_operator(celf, node: ASTArithmeticOperator) -> str: if node.is_times_op: return ' * ' - elif node.is_div_op: + + if node.is_div_op: return ' / ' - elif node.is_modulo_op: + + if node.is_modulo_op: return ' % ' - elif node.is_plus_op: + + if node.is_plus_op: return ' + ' - elif node.is_minus_op: + + if node.is_minus_op: return ' - ' - elif node.is_pow_op: + + if node.is_pow_op: return ' ** ' - else: - raise RuntimeError('(PyNestML.ArithmeticOperator.Print) Arithmetic operator not specified.') - def print_assignment(self, node): - # type: (ASTAssignment) -> str + raise RuntimeError('(PyNestML.ArithmeticOperator.Print) Arithmetic operator not specified.') + + def print_assignment(self, node: ASTAssignment) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + self.print_node(node.lhs) + ' ' if node.is_compound_quotient: @@ -198,36 +256,39 @@ def print_assignment(self, node): ret += '=' ret += ' ' + self.print_node(node.rhs) + print_sl_comment(node.in_comment) + '\n' ret += print_ml_comments(node.post_comments, self.indent, True) + return ret - @classmethod - def print_bit_operator(cls, node): - # type: (ASTBitOperator) -> str + def print_bit_operator(self, node: ASTBitOperator) -> str: if node.is_bit_and: return ' & ' - elif node.is_bit_or: + + if node.is_bit_or: return ' ^ ' - elif node.is_bit_or: + + if node.is_bit_or: return ' | ' - elif node.is_bit_shift_left: + + if node.is_bit_shift_left: return ' << ' - elif node.is_bit_shift_right: + + if node.is_bit_shift_right: return ' >> ' - else: - raise RuntimeError('(PyNestML.BitOperator.Print) Type of bit operator not specified!') - def print_block(self, node): - # type: (ASTBlock) -> str + raise RuntimeError('(PyNestML.BitOperator.Print) Type of bit operator not specified!') + + def print_block(self, node: ASTBlock) -> str: ret = '' # print_ml_comments(node.pre_comments, self.indent, False) self.inc_indent() for stmt in node.stmts: ret += self.print_node(stmt) + self.dec_indent() # ret += print_ml_comments(node.post_comments, self.indent, True) + return ret - def print_block_with_variables(self, node): - # type: (ASTBlockWithVariables) -> str + def print_block_with_variables(self, node: ASTBlockWithVariables) -> str: temp_indent = self.indent self.inc_indent() ret = print_ml_comments(node.pre_comments, temp_indent, False) @@ -236,10 +297,9 @@ def print_block_with_variables(self, node): ret += 'state' elif node.is_parameters: ret += 'parameters' - elif node.is_internals: - ret += 'internals' else: - ret += 'initial_values' + assert node.is_internals + ret += 'internals' ret += ':' + print_sl_comment(node.in_comment) + '\n' if node.get_declarations() is not None: for decl in node.get_declarations(): @@ -249,69 +309,77 @@ def print_block_with_variables(self, node): self.dec_indent() return ret - def print_body(self, node: ASTBody) -> str: + def print_neuron_or_synapse_body(self, node: ASTNeuronOrSynapseBody) -> str: ret = '' for elem in node.body_elements: ret += self.print_node(elem) ret += '\n' return ret - @classmethod - def print_comparison_operator(cls, node): - # type: (ASTComparisonOperator) -> str + def print_comparison_operator(self, node: ASTComparisonOperator) -> str: if node.is_lt: return ' < ' - elif node.is_le: + + if node.is_le: return ' <= ' - elif node.is_eq: + + if node.is_eq: return ' == ' - elif node.is_ne: + + if node.is_ne: return ' != ' - elif node.is_ne2: + + if node.is_ne2: return ' <> ' - elif node.is_ge: + + if node.is_ge: return ' >= ' - elif node.is_gt: + + if node.is_gt: return ' > ' - else: - raise RuntimeError('(PyNestML.ComparisonOperator.Print) Type of comparison operator not specified!') - def print_compound_stmt(self, node): - # type: (ASTCompoundStmt) -> str + raise RuntimeError('(PyNestML.ComparisonOperator.Print) Type of comparison operator not specified!') + + def print_compound_stmt(self, node: ASTCompoundStmt) -> str: if node.is_if_stmt(): return self.print_node(node.get_if_stmt()) - elif node.is_for_stmt(): + + if node.is_for_stmt(): return self.print_node(node.get_for_stmt()) - elif node.is_while_stmt(): + + if node.is_while_stmt(): return self.print_node(node.get_while_stmt()) - else: - raise RuntimeError('(PyNestML.CompoundStmt.Print) Type of compound statement not specified!') - def print_data_type(self, node): - # type: (ASTDataType) -> str + raise RuntimeError('(PyNestML.CompoundStmt.Print) Type of compound statement not specified!') + + def print_data_type(self, node: ASTDataType) -> str: if node.is_void: return 'void' - elif node.is_string: + + if node.is_string: return 'string' - elif node.is_boolean: + + if node.is_boolean: return 'boolean' - elif node.is_integer: + + if node.is_integer: return 'integer' - elif node.is_real: + + if node.is_real: return 'real' - elif node.is_unit_type(): + + if node.is_unit_type(): return self.print_node(node.get_unit_type()) - else: - raise RuntimeError('Type of datatype not specified!') - def print_declaration(self, node): - # type: (ASTDeclaration) -> str + raise RuntimeError('Type of datatype not specified!') + + def print_declaration(self, node: ASTDeclaration) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) if node.is_recordable: ret += 'recordable ' - if node.is_function: - ret += 'function ' + if node.is_inline_expression: + ret += 'inline ' for var in node.get_variables(): ret += self.print_node(var) if node.get_variables().index(var) < len(node.get_variables()) - 1: @@ -327,17 +395,14 @@ def print_declaration(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_elif_clause(self, node): - # type: (ASTElifClause) -> str + def print_elif_clause(self, node: ASTElifClause) -> str: return (print_n_spaces(self.indent) + 'elif ' + self.print_node(node.get_condition()) + ':\n' + self.print_node(node.get_block())) - def print_else_clause(self, node): - # type: (ASTElseClause) -> str + def print_else_clause(self, node: ASTElseClause) -> str: return print_n_spaces(self.indent) + 'else:\n' + self.print_node(node.get_block()) - def print_equations_block(self, node): - # type: (ASTEquationsBlock) -> str + def print_equations_block(self, node: ASTEquationsBlock) -> str: temp_indent = self.indent self.inc_indent() ret = print_ml_comments(node.pre_comments, temp_indent, False) @@ -350,8 +415,7 @@ def print_equations_block(self, node): ret += print_ml_comments(node.post_comments, temp_indent, True) return ret - def print_expression(self, node): - # type: (ASTExpression) -> str + def print_expression(self, node: ASTExpression) -> str: ret = '' if node.is_expression(): if node.is_encapsulated: @@ -372,18 +436,17 @@ def print_expression(self, node): node.get_if_true()) + ':' + self.print_node(node.get_if_not()) return ret - def print_for_stmt(self, node): - # type: (ASTForStmt) -> str + def print_for_stmt(self, node: ASTForStmt) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) + ret += print_n_spaces(self.indent) ret += ('for ' + node.get_variable() + ' in ' + self.print_node(node.get_start_from()) + '...' + self.print_node(node.get_end_at()) + ' step ' + str(node.get_step()) + ':' + print_sl_comment(node.in_comment) + '\n') - ret += self.print_node(node.get_block()) + 'end\n' + ret += self.print_node(node.get_block()) + print_n_spaces(self.indent) + 'end\n' ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_function(self, node): - # type: (ASTFunction) -> str + def print_function(self, node: ASTFunction) -> str: ret = print_ml_comments(node.pre_comments, self.indent) ret += 'function ' + node.get_name() + '(' if node.has_parameters(): @@ -397,8 +460,7 @@ def print_function(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_function_call(self, node): - # type: (ASTFunctionCall) -> str + def print_function_call(self, node: ASTFunctionCall) -> str: ret = str(node.get_name()) + '(' for i in range(0, len(node.get_args())): ret += self.print_node(node.get_args()[i]) @@ -407,8 +469,7 @@ def print_function_call(self, node): ret += ')' return ret - def print_if_clause(self, node): - # type: (ASTIfClause) -> str + def print_if_clause(self, node: ASTIfClause) -> str: ret = print_ml_comments(node.pre_comments, self.indent) ret += print_n_spaces(self.indent) + 'if ' + self.print_node(node.get_condition()) + ':' ret += print_sl_comment(node.in_comment) + '\n' @@ -416,8 +477,7 @@ def print_if_clause(self, node): ret += print_ml_comments(node.post_comments, self.indent) return ret - def print_if_stmt(self, node): - # type: (ASTIfStmt) -> str + def print_if_stmt(self, node: ASTIfStmt) -> str: ret = self.print_node(node.get_if_clause()) if node.get_elif_clauses() is not None: for clause in node.get_elif_clauses(): @@ -427,8 +487,7 @@ def print_if_stmt(self, node): ret += print_n_spaces(self.indent) + 'end\n' return ret - def print_input_block(self, node): - # type: (ASTInputBlock) -> str + def print_input_block(self, node: ASTInputBlock) -> str: temp_indent = self.indent self.inc_indent() ret = print_ml_comments(node.pre_comments, temp_indent, False) @@ -441,8 +500,7 @@ def print_input_block(self, node): self.dec_indent() return ret - def print_input_port(self, node): - # type: (ASTInputPort) -> str + def print_input_port(self, node: ASTInputPort) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + node.get_name() if node.has_datatype(): @@ -461,32 +519,30 @@ def print_input_port(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - @classmethod - def print_input_qualifier(cls, node): - # type: (ASTInputQualifier) -> str + def print_input_qualifier(self, node: ASTInputQualifier) -> str: if node.is_inhibitory: return 'inhibitory' - else: + if node.is_excitatory: return 'excitatory' + return '' - @classmethod - def print_logical_operator(cls, node): - # type: (ASTLogicalOperator) -> str + def print_logical_operator(self, node: ASTLogicalOperator) -> str: if node.is_logical_and: return ' and ' - else: + + if node.is_logical_or: return ' or ' - def print_compilation_unit(self, node): - # type: (ASTNestMLCompilationUnit) -> str + raise Exception("Unknown logical operator") + + def print_compilation_unit(self, node: ASTNestMLCompilationUnit) -> str: ret = '' if node.get_neuron_list() is not None: for neuron in node.get_neuron_list(): ret += self.print_node(neuron) + '\n' return ret - def print_ode_equation(self, node): - # type: (ASTOdeEquation) -> str + def print_ode_equation(self, node: ASTOdeEquation) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += (print_n_spaces(self.indent) + self.print_node(node.get_lhs()) + '=' + self.print_node(node.get_rhs()) @@ -494,8 +550,7 @@ def print_ode_equation(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_inline_expression(self, node): - # type: (ASTInlineExpression) -> str + def print_inline_expression(self, node: ASTInlineExpression) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) if node.is_recordable: ret += 'recordable' @@ -505,8 +560,7 @@ def print_inline_expression(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_kernel(self, node): - # type: (ASTKernel) -> str + def print_kernel(self, node: ASTKernel) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) ret += 'kernel ' @@ -520,8 +574,7 @@ def print_kernel(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_output_block(self, node): - # type: (ASTOutputBlock) -> str + def print_output_block(self, node: ASTOutputBlock) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + 'output: ' + ('spike' if node.is_spike() else 'current') ret += print_sl_comment(node.in_comment) @@ -529,40 +582,42 @@ def print_output_block(self, node): ret += print_ml_comments(node.post_comments, self.indent, True) return ret - def print_parameter(self, node): - # type: (ASTParameter) -> str + def print_parameter(self, node: ASTParameter) -> str: return node.get_name() + ' ' + self.print_node(node.get_data_type()) - def print_return_stmt(self, node): - # type: (ASTReturnStmt) -> str + def print_return_stmt(self, node: ASTReturnStmt): ret = print_n_spaces(self.indent) ret += 'return ' + (self.print_node(node.get_expression()) if node.has_expression() else '') return ret - def print_simple_expression(self, node): - # type: (ASTSimpleExpression) -> str + def print_simple_expression(self, node: ASTSimpleExpression) -> str: if node.is_function_call(): return self.print_node(node.function_call) - elif node.is_boolean_true: + + if node.is_boolean_true: return 'true' - elif node.is_boolean_false: + + if node.is_boolean_false: return 'false' - elif node.is_inf_literal: + + if node.is_inf_literal: return 'inf' - elif node.is_numeric_literal(): + + if node.is_numeric_literal(): if node.variable is not None: return str(node.numeric_literal) + self.print_node(node.variable) - else: - return str(node.numeric_literal) - elif node.is_variable(): + + return str(node.numeric_literal) + + if node.is_variable(): return self.print_node(node.variable) - elif node.is_string(): + + if node.is_string(): return node.get_string() - else: - raise RuntimeError('Simple rhs at %s not specified!' % str(node.get_source_position())) - def print_small_stmt(self, node): - # type: (ASTSmallStmt) -> str + raise RuntimeError('Simple rhs at %s not specified!' % str(node.get_source_position())) + + def print_small_stmt(self, node: ASTSmallStmt) -> str: if node.is_assignment(): ret = self.print_node(node.get_assignment()) elif node.is_function_call(): @@ -578,59 +633,62 @@ def print_small_stmt(self, node): ret = self.print_node(node.get_return_stmt()) return ret - def print_stmt(self, node): - # type: (ASTStmt) -> str + def print_stmt(self, node: ASTStmt): if node.is_small_stmt(): return self.print_node(node.small_stmt) - else: - return self.print_node(node.compound_stmt) - @classmethod - def print_unary_operator(cls, node): - # type: (ASTUnaryOperator) -> str + return self.print_node(node.compound_stmt) + + def print_unary_operator(self, node: ASTUnaryOperator) -> str: if node.is_unary_plus: return '+' - elif node.is_unary_minus: + + if node.is_unary_minus: return '-' - elif node.is_unary_tilde: + + if node.is_unary_tilde: return '~' - else: - raise RuntimeError('Type of unary operator not specified!') - def print_unit_type(self, node): - # type: (ASTUnitType) -> str + raise RuntimeError('Type of unary operator not specified!') + + def print_unit_type(self, node: ASTUnitType) -> str: if node.is_encapsulated: return '(' + self.print_node(node.compound_unit) + ')' - elif node.is_pow: + + if node.is_pow: return self.print_node(node.base) + '**' + str(node.exponent) - elif node.is_arithmetic_expression(): + + if node.is_arithmetic_expression(): t_lhs = ( self.print_node(node.get_lhs()) if isinstance(node.get_lhs(), ASTUnitType) else str(node.get_lhs())) if node.is_times: return t_lhs + '*' + self.print_node(node.get_rhs()) else: return t_lhs + '/' + self.print_node(node.get_rhs()) - else: - return node.unit - def print_update_block(self, node): - # type: (ASTUpdateBlock) -> str + return node.unit + + def print_on_receive_block(self, node: ASTOnReceiveBlock) -> str: + ret = print_ml_comments(node.pre_comments, self.indent, False) + ret += print_n_spaces(self.indent) + 'onReceive(' + node.port_name + '):' + print_sl_comment(node.in_comment) + '\n' + ret += (self.print_node(node.get_block()) + print_n_spaces(self.indent) + 'end\n') + ret += print_ml_comments(node.post_comments, self.indent, True) + return ret + + def print_update_block(self, node: ASTUpdateBlock): ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + 'update:' + print_sl_comment(node.in_comment) + '\n' ret += (self.print_node(node.get_block()) + print_n_spaces(self.indent) + 'end\n') ret += print_ml_comments(node.post_comments, self.indent, True) return ret - @classmethod - def print_variable(cls, node): - # type: (ASTVariable) -> str + def print_variable(self, node: ASTVariable): ret = node.name for i in range(1, node.differential_order + 1): ret += "'" return ret - def print_while_stmt(self, node): - # type: (ASTWhileStmt) -> str + def print_while_stmt(self, node: ASTWhileStmt) -> str: temp_indent = self.indent self.inc_indent() ret = print_ml_comments(node.pre_comments, temp_indent, False) @@ -648,48 +706,45 @@ def dec_indent(self): self.indent -= self.tab_size -def print_n_spaces(n): +def print_n_spaces(n) -> str: return ' ' * n -def print_ml_comments(comments, indent=0, is_post=False): +def print_ml_comments(comments, indent=0, newline=False) -> str: if comments is None or len(list(comments)) == 0: return '' ret = '' - if len(comments) > 0 and not is_post: - ret += '\n' for comment in comments: - ret += print_n_spaces(indent) + '/*' + if "\"\"\"" in comment: + return comment + '\n' for c_line in comment.splitlines(True): if c_line == '\n': - ret += print_n_spaces(indent) + '*' + '\n' + ret += print_n_spaces(indent) + '#' + '\n' continue elif c_line.lstrip() == '': continue - if comment.splitlines(True).index(c_line) != 0: - ret += print_n_spaces(indent) - ret += ('* ' if c_line[len(c_line) - len(c_line.lstrip())] != '*' and len( - comment.splitlines(True)) > 1 else '') - ret += c_line + ret += print_n_spaces(indent) + if c_line[len(c_line) - len(c_line.lstrip())] != '#': + ret += '#' + ret += c_line + '\n' if len(comment.splitlines(True)) > 1: ret += print_n_spaces(indent) - ret += '*/\n' - if len(comments) > 0 and is_post: + if len(comments) > 0 and newline: ret += '\n' + return ret -def print_sl_comment(comment): +def print_sl_comment(comment) -> str: if comment is not None: return ' # ' + comment.lstrip() - else: - return '' + + return '' -def filter_subsequent_whitespaces(string): - # type: (str) -> str +def filter_subsequent_whitespaces(string: str) -> str: """ - This filter reduces more then one newlines to exactly one, e.g.: + This filter reduces more than one newline to exactly one, e.g.: l1 \n \n diff --git a/pynestml/codegeneration/nestml_reference_converter.py b/pynestml/codegeneration/printers/nestml_reference_converter.py similarity index 69% rename from pynestml/codegeneration/nestml_reference_converter.py rename to pynestml/codegeneration/printers/nestml_reference_converter.py index 3cffe4b9f..2ad4486d1 100644 --- a/pynestml/codegeneration/nestml_reference_converter.py +++ b/pynestml/codegeneration/printers/nestml_reference_converter.py @@ -19,50 +19,50 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.codegeneration.i_reference_converter import IReferenceConverter +from pynestml.codegeneration.printers.reference_converter import ReferenceConverter +from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_variable import ASTVariable from pynestml.utils.ast_utils import ASTUtils -class NestMLReferenceConverter(IReferenceConverter): +class NestMLReferenceConverter(ReferenceConverter): """ This converter preserves the initial NestML syntax. """ - def convert_unary_op(self, ast_unary_operator): + def convert_unary_op(self, ast_unary_operator: ASTUnaryOperator) -> str: """ Returns the same string. :param ast_unary_operator: a single unary operator string. - :type ast_unary_operator: ast_unary_operator :return: the same string - :rtype: str """ return str(ast_unary_operator) + '%s' - def convert_name_reference(self, ast_variable, prefix=''): + # with_origins doesn't do anything, it's just here to match signature + # of nest_reference_converter.convert_name_reference + # this fixes an error where these converters are used exchangeably in the + # compartmental case + def convert_name_reference(self, ast_variable, prefix='', with_origins=True) -> str: """ Returns the same string :param ast_variable: a single variable - :type ast_variable: ASTVariable :return: the same string - :rtype: str """ return prefix + ast_variable.get_complete_name() - def convert_function_call(self, function_call, prefix=''): + def convert_function_call(self, function_call: ASTFunctionCall, prefix: str= '') -> str: """Return the function call in NESTML syntax. Parameters ---------- - function_call : ASTFunctionCall + function_call The function call node to convert. - prefix : str + prefix The prefix argument is not relevant for rendering NESTML syntax and will be ignored. Returns ------- - s : str + s The function call string in NESTML syntax. """ result = function_call.get_name() @@ -73,48 +73,43 @@ def convert_function_call(self, function_call, prefix=''): result += '()' return result - def convert_binary_op(self, ast_binary_operator): + def convert_binary_op(self, ast_binary_operator) -> str: """ Returns the same binary operator back. :param ast_binary_operator: a single binary operator - :type ast_binary_operator: str :return: the same binary operator - :rtype: str """ return '%s' + str(ast_binary_operator) + '%s' - def convert_constant(self, constant_name): + def convert_constant(self, constant_name: str) -> str: """ Returns the same string back. :param constant_name: a constant name - :type constant_name: str :return: the same string - :rtype: str """ return constant_name - def convert_ternary_operator(self): + def convert_ternary_operator(self) -> str: """ Converts the ternary operator to its initial kernel. :return: a string representation - :rtype: str """ return '(' + '%s' + ')?(' + '%s' + '):(' + '%s' + ')' - def convert_logical_operator(self, op): + def convert_logical_operator(self, op) -> str: return str(op) - def convert_arithmetic_operator(self, op): + def convert_arithmetic_operator(self, op) -> str: return str(op) - def convert_encapsulated(self): + def convert_encapsulated(self) -> str: return '(%s)' - def convert_comparison_operator(self, op): + def convert_comparison_operator(self, op) -> str: return str(op) - def convert_logical_not(self): + def convert_logical_not(self) -> str: return 'not' - def convert_bit_operator(self, op): + def convert_bit_operator(self, op) -> str: return str(op) diff --git a/pynestml/codegeneration/ode_toolbox_reference_converter.py b/pynestml/codegeneration/printers/ode_toolbox_reference_converter.py similarity index 68% rename from pynestml/codegeneration/ode_toolbox_reference_converter.py rename to pynestml/codegeneration/printers/ode_toolbox_reference_converter.py index b6bd41e09..0c80ac708 100644 --- a/pynestml/codegeneration/ode_toolbox_reference_converter.py +++ b/pynestml/codegeneration/printers/ode_toolbox_reference_converter.py @@ -18,10 +18,10 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.codegeneration.nestml_reference_converter import NestMLReferenceConverter -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.utils.ast_utils import ASTUtils + +from typing import Union + +from pynestml.codegeneration.printers.nestml_reference_converter import NestMLReferenceConverter class ODEToolboxReferenceConverter(NestMLReferenceConverter): @@ -29,21 +29,31 @@ class ODEToolboxReferenceConverter(NestMLReferenceConverter): Convert into a format accepted by ODE-toolbox as input. """ - def convert_name_reference(self, ast_variable, prefix=''): + def convert_name_reference(self, ast_variable, prefix: str = '') -> str: """ Returns the same string :param ast_variable: a single variable :type ast_variable: ASTVariable :return: the same string - :rtype: str """ return prefix + ast_variable.get_complete_name().replace("$", "__DOLLAR") - def convert_ternary_operator(self): + def convert_ternary_operator(self) -> str: """ ODE-toolbox does not support ternary operator! Ignore condition, and hard-wire to first parameter. :return: a string representation - :rtype: str """ s = '0 * (' + '%s' + ') + (' + '%s' + ') + 0 * (' + '%s' + ')' return '(' + s + ')' + + def convert_constant(self, const: Union[str, float, int]) -> str: + """ + Converts a single handed over constant. + :param constant_name: a constant as string. + :type constant_name: str + :return: the corresponding nest representation + """ + if isinstance(const, float) or isinstance(const, int): + return str(const) + + return const diff --git a/pynestml/codegeneration/printers/printer.py b/pynestml/codegeneration/printers/printer.py new file mode 100644 index 000000000..a12b92959 --- /dev/null +++ b/pynestml/codegeneration/printers/printer.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# +# printer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.codegeneration.printers.reference_converter import ReferenceConverter +from pynestml.codegeneration.printers.types_printer import TypesPrinter + + +class Printer: + r""" + By using a different ReferenceConverter and TypesPrinter for the handling of variables, names, and functions and so on, Printers can be easily adapted to different targets. + """ + + def __init__(self, reference_converter: ReferenceConverter, types_printer: TypesPrinter): + assert isinstance(reference_converter, ReferenceConverter) + self.reference_converter = reference_converter + self.types_printer = types_printer diff --git a/pynestml/codegeneration/printers/python_types_printer.py b/pynestml/codegeneration/printers/python_types_printer.py new file mode 100644 index 000000000..3d1d66975 --- /dev/null +++ b/pynestml/codegeneration/printers/python_types_printer.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# +# python_types_printer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from pynestml.codegeneration.printers.types_printer import TypesPrinter +from pynestml.symbols.type_symbol import TypeSymbol +from pynestml.symbols.real_type_symbol import RealTypeSymbol +from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol +from pynestml.symbols.integer_type_symbol import IntegerTypeSymbol +from pynestml.symbols.string_type_symbol import StringTypeSymbol +from pynestml.symbols.void_type_symbol import VoidTypeSymbol +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.symbols.error_type_symbol import ErrorTypeSymbol + + +class PythonTypesPrinter(TypesPrinter): + r""" + Returns a Python syntax version of the handed over type. + """ + + def convert(self, type_symbol: TypeSymbol) -> str: + r""" + Converts the name of the type symbol to a corresponding Python syntax representation. + :param type_symbol: a single type symbol + :return: the corresponding string representation. + """ + assert isinstance(type_symbol, TypeSymbol) + + if isinstance(type_symbol, RealTypeSymbol): + return "float" + + if isinstance(type_symbol, BooleanTypeSymbol): + return "bool" + + if isinstance(type_symbol, IntegerTypeSymbol): + return "int" + + if isinstance(type_symbol, StringTypeSymbol): + return "str" + + if isinstance(type_symbol, VoidTypeSymbol): + return "" + + if isinstance(type_symbol, UnitTypeSymbol): + return "float" + + if isinstance(type_symbol, ErrorTypeSymbol): + return "ERROR" + + raise Exception("Unknown NEST type") diff --git a/pynestml/codegeneration/i_reference_converter.py b/pynestml/codegeneration/printers/reference_converter.py similarity index 85% rename from pynestml/codegeneration/i_reference_converter.py rename to pynestml/codegeneration/printers/reference_converter.py index b9626347e..9481556c4 100644 --- a/pynestml/codegeneration/i_reference_converter.py +++ b/pynestml/codegeneration/printers/reference_converter.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# i_reference_converter.py +# reference_converter.py # # This file is part of NEST. # @@ -18,12 +18,12 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from abc import ABCMeta, abstractmethod -class IReferenceConverter(object): - """This class represents a abstract super class for all possible reference converters, e.g. for nest, SpiNNaker or LEMS. - """ +class ReferenceConverter: + r"""This class represents a abstract super class for all possible reference converters, e.g. for NEST, SpiNNaker, or standalone Python target.""" __metaclass__ = ABCMeta @@ -39,6 +39,10 @@ def convert_function_call(self, function_call, prefix=''): def convert_name_reference(self, variable, prefix=''): pass + @abstractmethod + def convert_delay_variable(self, variable, prefix=''): + pass + @abstractmethod def convert_constant(self, constant_name): pass diff --git a/pynestml/codegeneration/printers/types_printer.py b/pynestml/codegeneration/printers/types_printer.py new file mode 100644 index 000000000..6f04b4ba8 --- /dev/null +++ b/pynestml/codegeneration/printers/types_printer.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# +# types_printer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import abc + +from pynestml.symbols.type_symbol import TypeSymbol + + +class TypesPrinter(metaclass=abc.ABCMeta): + r""" + Returns a string format of ``TypeSymbol``s. + """ + + @classmethod + @abc.abstractmethod + def convert(cls, element: TypeSymbol): + pass diff --git a/pynestml/codegeneration/unit_converter.py b/pynestml/codegeneration/printers/unit_converter.py similarity index 99% rename from pynestml/codegeneration/unit_converter.py rename to pynestml/codegeneration/printers/unit_converter.py index 013814c48..c2044375c 100644 --- a/pynestml/codegeneration/unit_converter.py +++ b/pynestml/codegeneration/printers/unit_converter.py @@ -21,7 +21,7 @@ from astropy import units -class UnitConverter(object): +class UnitConverter: """ Calculates the factor needed to convert a given unit to its NEST counterpart. I.e.: potentials are expressed as mV, consultancies as nS etc. diff --git a/pynestml/codegeneration/unitless_expression_printer.py b/pynestml/codegeneration/printers/unitless_expression_printer.py similarity index 54% rename from pynestml/codegeneration/unitless_expression_printer.py rename to pynestml/codegeneration/printers/unitless_expression_printer.py index 12341b2f9..f28c889f3 100644 --- a/pynestml/codegeneration/unitless_expression_printer.py +++ b/pynestml/codegeneration/printers/unitless_expression_printer.py @@ -19,55 +19,43 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.codegeneration.expressions_pretty_printer import ExpressionsPrettyPrinter -from pynestml.codegeneration.i_reference_converter import IReferenceConverter -from pynestml.codegeneration.nestml_reference_converter import NestMLReferenceConverter -from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.codegeneration.printers.cpp_expression_printer import CppExpressionPrinter +from pynestml.codegeneration.printers.unit_converter import UnitConverter +from pynestml.meta_model.ast_expression_node import ASTExpressionNode from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.codegeneration.unit_converter import UnitConverter -class UnitlessExpressionPrinter(ExpressionsPrettyPrinter): +class UnitlessExpressionPrinter(CppExpressionPrinter): + r""" + An adjusted version of the printer which does not print units with literals. """ - An adjusted version of the pretty printer which does not print units with literals. - """ - - def __init__(self, reference_converter=None, types_printer=None): - """ - Standard constructor. - :param reference_converter: a single reference converter object. - :type reference_converter: IReferenceConverter - """ - super(UnitlessExpressionPrinter, self).__init__( - reference_converter=reference_converter, types_printer=types_printer) - def print_expression(self, node, prefix=''): - """Print an expression. + def print_expression(self, node: ASTExpressionNode, prefix: str = "", with_origins=True) -> str: + r"""Print an expression. Parameters ---------- - node : ASTExpressionNode + node The expression node to print. - prefix : str - *See documentation for the function ExpressionsPrettyPrinter::print_function_call().* - + prefix + *See documentation for the function CppExpressionsPrinter::print_function_call().* Returns ------- - s : str + s The expression string. """ - # todo : printing of literals etc. should be done by constant converter, not a type converter if isinstance(node, ASTSimpleExpression): if node.is_numeric_literal(): - return self.types_printer.pretty_print(node.get_numeric_literal()) - elif node.is_variable() and node.get_scope() is not None: + return self.reference_converter.convert_constant(node.get_numeric_literal()) + + if node.is_variable() and node.get_scope() is not None: node_is_variable_symbol = node.get_scope().resolve_to_symbol( node.variable.get_complete_name(), SymbolKind.VARIABLE) is not None if not node_is_variable_symbol and PredefinedUnits.is_unit(node.variable.get_complete_name()): # case for a literal unit, e.g. "ms" return str(UnitConverter.get_factor(PredefinedUnits.get_unit(node.variable.get_complete_name()).get_unit())) - return super(UnitlessExpressionPrinter, self).print_expression(node, prefix=prefix) + return super(UnitlessExpressionPrinter, self).print_expression(node, prefix=prefix, with_origins=with_origins) diff --git a/pynestml/codegeneration/resources_autodoc/nestml_models_index.jinja2 b/pynestml/codegeneration/resources_autodoc/nestml_models_index.jinja2 index 29e426d87..72d53b4d8 100644 --- a/pynestml/codegeneration/resources_autodoc/nestml_models_index.jinja2 +++ b/pynestml/codegeneration/resources_autodoc/nestml_models_index.jinja2 @@ -1,8 +1,21 @@ -NESTML model index -================== +Models library +============== -Generated at {{ now }} +.. + Generated at {{ now }} + +Neurons +~~~~~~~ {%- for neuron in neurons %} - {{ neuron.get_name() }}`_ {%- endfor %} + +Synapses +~~~~~~~~ + +{%- for synapse in synapses %} +- `{{ synapse.get_name() }}`_ +{%- endfor %} + + diff --git a/pynestml/codegeneration/resources_autodoc/nestml_model.jinja2 b/pynestml/codegeneration/resources_autodoc/nestml_neuron_model.jinja2 similarity index 88% rename from pynestml/codegeneration/resources_autodoc/nestml_model.jinja2 rename to pynestml/codegeneration/resources_autodoc/nestml_neuron_model.jinja2 index 42ce5f46c..216ba2384 100644 --- a/pynestml/codegeneration/resources_autodoc/nestml_model.jinja2 +++ b/pynestml/codegeneration/resources_autodoc/nestml_neuron_model.jinja2 @@ -1,7 +1,7 @@ {{ neuronName }} {% for i in range(neuronName | length) %}#{%- endfor %} -{{ neuron.print_comment() | trim }} +{{ neuron.print_comment() | trim | replace('"""', '') | replace('#', '') }} Parameters @@ -18,7 +18,7 @@ Parameters State variables +++++++++++++++ -{% with block = neuron.get_initial_blocks() %} +{% with block = neuron.get_state_blocks() %} {%- include "block_decl_table.jinja2" %} {% endwith %} @@ -49,7 +49,7 @@ Source code .. code-block:: nestml -{{ neuron_source_code }} +{{ model_source_code }} Characterisation diff --git a/pynestml/codegeneration/resources_autodoc/nestml_synapse_model.jinja2 b/pynestml/codegeneration/resources_autodoc/nestml_synapse_model.jinja2 new file mode 100644 index 000000000..75e82105d --- /dev/null +++ b/pynestml/codegeneration/resources_autodoc/nestml_synapse_model.jinja2 @@ -0,0 +1,42 @@ +{{ synapseName }} +{% for i in range(synapseName | length) %}#{%- endfor %} + +{{ synapse.print_comment() | trim | replace('"""', '') | replace('#', '') }} + + +Parameters +++++++++++ + +{{ synapse.print_parameter_comment() }} + +{% with block = synapse.get_parameter_blocks() %} +{%- include "block_decl_table.jinja2" %} +{% endwith %} + +{%- if synapse.get_state_blocks() is not none %} + + +State variables ++++++++++++++++ + +{% with block = synapse.get_state_blocks() %} +{%- include "block_decl_table.jinja2" %} +{%- endwith %} +{%- endif %} +Source code ++++++++++++ + +.. code-block:: nestml + +{{ model_source_code }} + + +Characterisation +++++++++++++++++ + +.. include:: {{synapseName}}_characterisation.rst + + +.. footer:: + + Generated at {{ now }} diff --git a/pynestml/codegeneration/resources_nest/NeuronClass.jinja2 b/pynestml/codegeneration/resources_nest/NeuronClass.jinja2 deleted file mode 100644 index 70528a57e..000000000 --- a/pynestml/codegeneration/resources_nest/NeuronClass.jinja2 +++ /dev/null @@ -1,423 +0,0 @@ -{# -/* -* NeuronClass.jinja2 -* -* This file is part of NEST. -* -* Copyright (C) 2004 The NEST Initiative -* -* NEST is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* NEST is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with NEST. If not, see . -* -*/ -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */{%- else -%}{%- endif -%} -/* -* {{neuronName}}.cpp -* -* This file is part of NEST. -* -* Copyright (C) 2004 The NEST Initiative -* -* NEST is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* NEST is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with NEST. If not, see . -* -* {{now}} -*/ - -// C++ includes: -#include - -// Includes from libnestutil: -#include "numerics.h" - -// Includes from nestkernel: -#include "exceptions.h" -#include "kernel_manager.h" -#include "universal_data_logger_impl.h" - -// Includes from sli: -#include "dict.h" -#include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" -#include "lockptrdatum.h" - -#include "{{neuronName}}.h" - -{% set stateSize = neuron.get_non_function_initial_values_symbols()|length %} -/* ---------------------------------------------------------------- -* Recordables map -* ---------------------------------------------------------------- */ -nest::RecordablesMap<{{neuronName}}> {{neuronName}}::recordablesMap_; - -namespace nest -{ - // Override the create() method with one call to RecordablesMap::insert_() - // for each quantity to be recorded. - template <> void RecordablesMap<{{neuronName}}>::create(){ - // use standard names where you can for consistency! - - // initial values for state variables not in ODE or kernel -{%- filter indent(2,True) %} -{%- for variable in neuron.get_state_non_alias_symbols() %} -{%- include "directives/RecordCallback.jinja2" %} -{%- endfor %} -{%- endfilter %} - - // initial values for state variables in ODE or kernel -{%- filter indent(2,True) %} -{%- for variable in neuron.get_initial_values_non_alias_symbols() %} -{%- if not is_delta_kernel(neuron.get_kernel_by_name(variable.name)) %} -{%- include "directives/RecordCallback.jinja2" %} -{%- endif %} -{%- endfor %} -{%- endfilter %} - - // internals -{%- filter indent(2,True) %} -{%- for variable in neuron.get_internal_symbols() %} -{%- include "directives/RecordCallback.jinja2" %} -{%- endfor %} -{%- endfilter %} - - // parameters -{%- filter indent(2,True) %} -{%- for variable in neuron.get_parameter_symbols() %} -{%- include "directives/RecordCallback.jinja2" %} -{%- endfor %} -{%- endfilter %} - - // function symbols -{%- filter indent(2,True) %} -{%- for funcsym in neuron.get_function_symbols() %} -{%- with variable = funcsym %} -{%- include "directives/RecordCallback.jinja2" %} -{%- endwith %} -{%- endfor %} -{%- endfilter %} - } -} - -/* ---------------------------------------------------------------- - * Default constructors defining default parameters and state - * Note: the implementation is empty. The initialization is of variables - * is a part of the {{neuronName}}'s constructor. - * ---------------------------------------------------------------- */ -{{neuronName}}::Parameters_::Parameters_(){} - -{{neuronName}}::State_::State_(){} - -/* ---------------------------------------------------------------- -* Parameter and state extractions and manipulation functions -* ---------------------------------------------------------------- */ - -{{neuronName}}::Buffers_::Buffers_({{neuronName}} &n): - logger_(n) -{%- if neuron.get_multiple_receptors()|length > 1 -%} - , spike_inputs_( std::vector< nest::RingBuffer >( SUP_SPIKE_RECEPTOR - 1 ) ) -{%- endif -%} -{%- if useGSL -%} - , __s( 0 ), __c( 0 ), __e( 0 ) -{%- endif -%} -{ - // Initialization of the remaining members is deferred to - // init_buffers_(). -} - -{{neuronName}}::Buffers_::Buffers_(const Buffers_ &, {{neuronName}} &n): - logger_(n) -{%- if neuron.get_multiple_receptors()|length > 1 -%} - , spike_inputs_( std::vector< nest::RingBuffer >( SUP_SPIKE_RECEPTOR - 1 ) ) -{%- endif -%} -{%- if useGSL -%} - , __s( 0 ), __c( 0 ), __e( 0 ) -{%- endif -%} -{ - // Initialization of the remaining members is deferred to - // init_buffers_(). -} - -/* ---------------------------------------------------------------- - * Default and copy constructor for node, and destructor - * ---------------------------------------------------------------- */ -{{neuronName}}::{{neuronName}}():ArchivingNode(), P_(), S_(), B_(*this) -{ - - recordablesMap_.create(); - - calibrate(); - -{%- if useGSL %} - // use a default "good enough" value for the absolute error. It can be adjusted via `node.set()` - P_.__gsl_error_tol = 1e-3; -{%- endif %} - - // initial values for parameters -{%- filter indent(2, True) %} -{%- for parameter in neuron.get_parameter_non_alias_symbols() -%} -{%- with variable = parameter %} -{%- include "directives/MemberInitialization.jinja2" %} -{%- endwith %} -{%- endfor %} -{%- endfilter %} - - // initial values for state variables not in ODE or kernel -{%- filter indent(2,True) %} -{%- for state in neuron.get_state_non_alias_symbols() %} -{%- with variable = state %} -{%- include "directives/MemberInitialization.jinja2" %} -{%- endwith %} -{%- endfor %} -{%- endfilter %} - - // initial values for state variables in ODE or kernel -{%- filter indent(2,True) %} -{%- for init in neuron.get_initial_values_non_alias_symbols() %} -{%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} -{%- with variable = init -%} -{%- include "directives/MemberInitialization.jinja2" %} -{%- endwith %} -{%- endif %} -{%- endfor %} -{%- endfilter %} -} - -{{neuronName}}::{{neuronName}}(const {{neuronName}}& __n): - ArchivingNode(), P_(__n.P_), S_(__n.S_), B_(__n.B_, *this) { - // copy parameter struct P_ -{%- filter indent(2, True) %} -{%- for parameter in neuron.get_parameter_non_alias_symbols() %} -P_.{{names.name(parameter)}} = __n.P_.{{names.name(parameter)}}; -{%- endfor %} -{%- endfilter %} - - // copy state struct S_ -{%- filter indent(2, True) %} -{%- for state in neuron.get_state_non_alias_symbols() %} -S_.{{names.name(state)}} = __n.S_.{{names.name(state)}}; -{%- endfor %} -{%- endfilter %} - -{%- filter indent(2, True) %} -{%- for init in neuron.get_initial_values_non_alias_symbols() %} -{%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} -S_.{{names.name(init)}} = __n.S_.{{names.name(init)}}; -{%- endif %} -{%- endfor %} -{%- for internal in neuron.get_internal_non_alias_symbols() %} -V_.{{names.name(internal)}} = __n.V_.{{names.name(internal)}}; -{%- endfor %} -{%- endfilter %} -} - -{{neuronName}}::~{{neuronName}}(){ {% if useGSL %} - // GSL structs may not have been allocated, so we need to protect destruction - if (B_.__s) - gsl_odeiv_step_free( B_.__s ); - if (B_.__c) - gsl_odeiv_control_free( B_.__c ); - if (B_.__e) - gsl_odeiv_evolve_free( B_.__e );{% endif %} -} - -/* ---------------------------------------------------------------- -* Node initialization functions -* ---------------------------------------------------------------- */ - -void {{neuronName}}::init_state_(const Node& proto){ - const {{neuronName}}& pr = downcast<{{neuronName}}>(proto); - S_ = pr.S_; -} - -{% if useGSL %} -{% include "directives/GSLDifferentiationFunction.jinja2" %} -{% endif %} - -void {{neuronName}}::init_buffers_(){ - {% for buffer in neuron.get_input_buffers() -%} - {{ printer.print_buffer_initialization(buffer) }} - {% endfor %} - B_.logger_.reset(); // includes resize - ArchivingNode::clear_history(); - {% if useGSL %} - if ( B_.__s == 0 ){ - B_.__s = gsl_odeiv_step_alloc( gsl_odeiv_step_rkf45, {{stateSize}} ); - } else { - gsl_odeiv_step_reset( B_.__s ); - } - - if ( B_.__c == 0 ){ - B_.__c = gsl_odeiv_control_y_new( P_.__gsl_error_tol, 0.0 ); - } else { - gsl_odeiv_control_init( B_.__c, P_.__gsl_error_tol, 0.0, 1.0, 0.0 ); - } - - if ( B_.__e == 0 ){ - B_.__e = gsl_odeiv_evolve_alloc( {{stateSize}} ); - } else { - gsl_odeiv_evolve_reset( B_.__e ); - } - - B_.__sys.function = {{neuronName}}_dynamics; - B_.__sys.jacobian = NULL; - B_.__sys.dimension = {{stateSize}}; - B_.__sys.params = reinterpret_cast< void* >( this ); - B_.__step = nest::Time::get_resolution().get_ms(); - B_.__integration_step = nest::Time::get_resolution().get_ms();{% endif %} -} - -void {{neuronName}}::calibrate() { - B_.logger_.init(); - -{%- filter indent(2,True) %} -{%- for variable in neuron.get_internal_non_alias_symbols() %} -{%- include "directives/Calibrate.jinja2" %} -{%- endfor %} -{%- endfilter %} - -{%- filter indent(2,True) %} -{%- for variable in neuron.get_state_non_alias_symbols() %} -{%- if variable.has_vector_parameter() %} -{%- include "directives/Calibrate.jinja2" %} -{%- endif %} -{%- endfor %} -{%- endfilter %} - -{%- for buffer in neuron.get_input_buffers() %} -{%- if buffer.has_vector_parameter() %} - B_.{{buffer.get_symbol_name()}}.resize(P_.{{buffer.get_vector_parameter()}}); - B_.{{buffer.get_symbol_name()}}_grid_sum_.resize(P_.{{buffer.get_vector_parameter()}}); -{%- endif %} -{%- endfor %} -} - -/* ---------------------------------------------------------------- -* Update and spike handling functions -* ---------------------------------------------------------------- */ - -/* - {{neuron.print_dynamics_comment('*')}} - */ -void {{neuronName}}::update(nest::Time const & origin,const long from, const long to){ -{%- if useGSL %} - double __t = 0; -{%- endif %} - - for ( long lag = from ; lag < to ; ++lag ) { -{%- for inputPort in neuron.get_input_buffers() %} -{%- if inputPort.has_vector_parameter() %} - for (long i=0; i < P_.{{inputPort.get_vector_parameter()}}; ++i){ - B_.{{names.buffer_value(inputPort)}}[i] = get_{{names.name(inputPort)}}()[i].get_value(lag); - } -{%- else %} - B_.{{names.buffer_value(inputPort)}} = get_{{names.name(inputPort)}}().get_value(lag); -{%- endif %} -{%- endfor %} - - // NESTML generated code for the update block: - -{%- if neuron.get_update_blocks() %} -{%- filter indent(2,True) %} -{%- set dynamics = neuron.get_update_blocks() %} -{%- with ast = dynamics.get_block() %} -{%- include "directives/Block.jinja2" %} -{%- endwith %} -{%- endfilter %} -{%- endif %} - - // voltage logging - B_.logger_.record_data(origin.get_steps()+lag); - } - -} - -// Do not move this function as inline to h-file. It depends on -// universal_data_logger_impl.h being included here. -void {{neuronName}}::handle(nest::DataLoggingRequest& e){ - B_.logger_.handle(e); -} - -{%- for function in neuron.get_functions() %} -{{printer.print_function_definition(function, neuronName)}} -{ -{%- filter indent(2,True) %} -{%- with ast = function.get_block() %} -{%- include "directives/Block.jinja2" %} -{%- endwith %} -{%- endfilter %} -} -{%- endfor %} - -{%- if is_spike_input %} -void {{neuronName}}::handle(nest::SpikeEvent &e){ - assert(e.get_delay_steps() > 0); -{%- if neuron.is_multisynapse_spikes() %} -{%- set spikeBuffer = neuron.get_spike_buffers()[0] %} - B_.{{spikeBuffer.get_symbol_name()}}[e.get_rport() - 1].add_value( - e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), - e.get_weight() * e.get_multiplicity() ); -{%- elif neuron.get_multiple_receptors()|length > 1 %} - assert( e.get_rport() < static_cast< int >( B_.spike_inputs_.size() ) ); - - B_.spike_inputs_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), - e.get_weight() * e.get_multiplicity() ); -{%- else %} - const double weight = e.get_weight(); - const double multiplicity = e.get_multiplicity(); -{%- for buffer in neuron.get_spike_buffers() %} -{%- if buffer.is_excitatory() %} - if ( weight >= 0.0 ){ // excitatory - get_{{buffer.get_symbol_name()}}(). - add_value(e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), - weight * multiplicity ); - } -{%- endif %} -{%- if buffer.is_inhibitory() %} - if ( weight < 0.0 ){ // inhibitory - get_{{buffer.get_symbol_name()}}(). - add_value(e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), - {% if buffer.is_conductance_based() %} // ensure conductance is positive {% endif %} - {% if buffer.is_conductance_based() %} -1 * {% endif %} weight * multiplicity ); - } -{%- endif -%} -{%- endfor %} -{%- endif %} -} -{%- endif %} - -{%- if is_current_input %} -void {{neuronName}}::handle(nest::CurrentEvent& e){ - assert(e.get_delay_steps() > 0); - - const double current = e.get_current(); // we assume that in NEST, this returns a current in pA - const double weight = e.get_weight(); - -{%- for buffer in neuron.get_current_buffers() %} - get_{{buffer.get_symbol_name()}}().add_value( - e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), - weight * current ); -{%- endfor %} -} -{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/NeuronHeader.jinja2 b/pynestml/codegeneration/resources_nest/NeuronHeader.jinja2 deleted file mode 100644 index 26b7936e7..000000000 --- a/pynestml/codegeneration/resources_nest/NeuronHeader.jinja2 +++ /dev/null @@ -1,668 +0,0 @@ -{# -/* -* NeuronHeader.jinja2 -* -* This file is part of NEST. -* -* Copyright (C) 2004 The NEST Initiative -* -* NEST is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* NEST is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with NEST. If not, see . -* -*/ --#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -/* -* {{neuronName}}.h -* -* This file is part of NEST. -* -* Copyright (C) 2004 The NEST Initiative -* -* NEST is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* NEST is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with NEST. If not, see . -* -* {{now}} -*/ -#ifndef {{neuronName.upper()}} -#define {{neuronName.upper()}} - -#include "config.h" - -{% if norm_rng -%} -// Includes from librandom: -#include "normal_randomdev.h" -{% endif -%} - -{% if useGSL %} -#ifdef HAVE_GSL - -// External includes: -#include -#include -#include - -// forwards the declaration of the function -/** - * Function computing right-hand side of ODE for GSL solver. - * @note Must be declared here so we can befriend it in class. - * @note Must have C-linkage for passing to GSL. Internally, it is - * a first-class C++ function, but cannot be a member function - * because of the C-linkage. - * @note No point in declaring it inline, since it is called - * through a function pointer. - * @param void* Pointer to model neuron instance. - */ -extern "C" inline int {{neuronName}}_dynamics( double, const double y[], double f[], void* pnode ); -{% endif %} - -// Includes from nestkernel: -#include "archiving_node.h" -#include "connection.h" -#include "event.h" -#include "nest_types.h" -#include "ring_buffer.h" -#include "universal_data_logger.h" - - -// Includes from sli: -#include "dictdatum.h" - -/* BeginDocumentation - Name: {{neuronName}}. - - Description:{% filter indent(2,True) %} - {{neuron.print_comment()}}{% endfilter %} - - Parameters: - The following parameters can be set in the status dictionary. - {% for parameter in neuron.get_parameter_symbols() -%} - {% if parameter.has_comment() -%} - {{parameter.get_symbol_name()}} [{{parameter.get_type_symbol().print_symbol()}}] {{parameter.print_comment()}} - {% endif -%} - {% endfor %} - - Dynamic state variables: - {% for state in neuron.get_state_symbols() -%} - {% if state.has_comment() -%} - {{state.get_symbol_name()}} [{{state.get_type_symbol().print_symbol()}}] {{state.print_comment()}} - {% endif -%} - {% endfor %} - - Initial values: - {% for init in neuron.get_initial_values_symbols() -%} - {% if init.has_comment() -%} - {{init.get_symbol_name()}} [{{init.get_type_symbol().print_symbol()}}] {{init.print_comment()}} - {% endif -%} - {% endfor %} - - References: Empty - - Sends: {{outputEvent}} - - Receives: {% if is_spike_input %}Spike, {% endif %}{% if is_current_input %}Current,{% endif %} DataLoggingRequest -*/ -class {{neuronName}} : public nest::ArchivingNode{ -public: - /** - * The constructor is only used to create the model prototype in the model manager. - */ - {{neuronName}}(); - - /** - * The copy constructor is used to create model copies and instances of the model. - * @node The copy constructor needs to initialize the parameters and the state. - * Initialization of buffers and interal variables is deferred to - * @c init_buffers_() and @c calibrate(). - */ - {{neuronName}}(const {{neuronName}} &); - - /** - * Releases resources. - */ - ~{{neuronName}}(); - - /** - * Import sets of overloaded virtual functions. - * @see Technical Issues / Virtual Functions: Overriding, Overloading, and - * Hiding - */ - using nest::Node::handles_test_event; - using nest::Node::handle; - - /** - * Used to validate that we can send {{outputEvent}} to desired target:port. - */ - nest::port send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool); - - /** - * @defgroup mynest_handle Functions handling incoming events. - * We tell nest that we can handle incoming events of various types by - * defining @c handle() and @c connect_sender() for the given event. - * @{ - */ - {% if is_spike_input -%} - void handle(nest::SpikeEvent &); //! accept spikes - {% endif -%} - {% if is_current_input -%} - void handle(nest::CurrentEvent &); //! accept input current - {% endif -%} - void handle(nest::DataLoggingRequest &);//! allow recording with multimeter - - {% if is_spike_input -%} - nest::port handles_test_event(nest::SpikeEvent&, nest::port); - {% endif -%} - {% if is_current_input -%} - nest::port handles_test_event(nest::CurrentEvent&, nest::port); - {% endif -%} - nest::port handles_test_event(nest::DataLoggingRequest&, nest::port); - /** @} */ - - // SLI communication functions: - void get_status(DictionaryDatum &) const; - void set_status(const DictionaryDatum &); - -private: - {% if (neuron.get_multiple_receptors())|length > 1 -%} - /** - * Synapse types to connect to - * @note Excluded upper and lower bounds are defined as INF_, SUP_. - * Excluding port 0 avoids accidental connections. - */ - enum SynapseTypes - { - INF_SPIKE_RECEPTOR = 0, - {% for buffer in neuron.get_multiple_receptors() -%} - {{buffer.get_symbol_name().upper()}} , - {% endfor -%} - SUP_SPIKE_RECEPTOR - }; - {% endif -%} - //! Reset parameters and state of neuron. - - //! Reset state of neuron. - void init_state_(const Node& proto); - - //! Reset internal buffers of neuron. - void init_buffers_(); - - //! Initialize auxiliary quantities, leave parameters and state untouched. - void calibrate(); - - //! Take neuron through given time interval - void update(nest::Time const &, const long, const long); - - // The next two classes need to be friends to access the State_ class/member - friend class nest::RecordablesMap<{{neuronName}}>; - friend class nest::UniversalDataLogger<{{neuronName}}>; - - /** - * Free parameters of the neuron. - * - {{neuron.print_parameter_comment("*")}} - * - * These are the parameters that can be set by the user through @c `node.set()`. - * They are initialized from the model prototype when the node is created. - * Parameters do not change during calls to @c update() and are not reset by - * @c ResetNetwork. - * - * @note Parameters_ need neither copy constructor nor @c operator=(), since - * all its members are copied properly by the default copy constructor - * and assignment operator. Important: - * - If Parameters_ contained @c Time members, you need to define the - * assignment operator to recalibrate all members of type @c Time . You - * may also want to define the assignment operator. - * - If Parameters_ contained members that cannot copy themselves, such - * as C-style arrays, you need to define the copy constructor and - * assignment operator to copy those members. - */ - struct Parameters_{ - {% filter indent(4,True) %} - {% for variable in neuron.get_parameter_non_alias_symbols() -%} - {% include 'directives/MemberDeclaration.jinja2' -%} - {% endfor -%}{% endfilter %} - - {% if useGSL -%} - double __gsl_error_tol; - {% endif -%} - - /** Initialize parameters to their default values. */ - Parameters_(); - }; - - /** - * Dynamic state of the neuron. - * - {{neuron.print_state_comment('*')}} - * - * These are the state variables that are advanced in time by calls to - * @c update(). In many models, some or all of them can be set by the user - * through @c `node.set()`. The state variables are initialized from the model - * prototype when the node is created. State variables are reset by @c ResetNetwork. - * - * @note State_ need neither copy constructor nor @c operator=(), since - * all its members are copied properly by the default copy constructor - * and assignment operator. Important: - * - If State_ contained @c Time members, you need to define the - * assignment operator to recalibrate all members of type @c Time . You - * may also want to define the assignment operator. - * - If State_ contained members that cannot copy themselves, such - * as C-style arrays, you need to define the copy constructor and - * assignment operator to copy those members. - */ - struct State_{ -{%- if not useGSL %} -{%- filter indent(4,True) %} -{%- for variable in neuron.get_state_non_alias_symbols() %} -{%- include "directives/MemberDeclaration.jinja2" %} -{%- endfor %} -{%- for variable in neuron.get_initial_values_symbols() %} -{%- include "directives/MemberDeclaration.jinja2" %} -{%- endfor %} -{%- endfilter %} -{%- else %} - //! Symbolic indices to the elements of the state vector y - enum StateVecElems{ -{# N.B. numeric solver contains all state variables, including those that will be solved by analytic solver #} -{%- if uses_numeric_solver %} - // numeric solver state variables -{%- for variable_name in numeric_state_variables: %} - {{variable_name}}, -{%- endfor %} -{%- for variable_name in non_equations_state_variables: %} - {{variable_name}}, -{%- endfor %} -{%- endif %} - STATE_VEC_SIZE - }; - //! state vector, must be C-array for GSL solver - double ode_state[STATE_VEC_SIZE]; - - // state variables from state block -{%- filter indent(4,True) %} -{%- for variable in neuron.get_state_symbols() %} -{%- include "directives/MemberDeclaration.jinja2" %} -{%- endfor %} -{%- endfilter %} -{%- endif %} - - State_(); - }; - - /** - * Internal variables of the neuron. - * - {{neuron.print_internal_comment('*')}} - * - * These variables must be initialized by @c calibrate, which is called before - * the first call to @c update() upon each call to @c Simulate. - * @node Variables_ needs neither constructor, copy constructor or assignment operator, - * since it is initialized by @c calibrate(). If Variables_ has members that - * cannot destroy themselves, Variables_ will need a destructor. - */ - struct Variables_ { - {%- for variable in neuron.get_internal_non_alias_symbols() -%} - {% filter indent(4,True) %}{% include "directives/MemberDeclaration.jinja2" -%}{% endfilter %} - {% endfor %} - }; - - /** - * Buffers of the neuron. - * Usually buffers for incoming spikes and data logged for analog recorders. - * Buffers must be initialized by @c init_buffers_(), which is called before - * @c calibrate() on the first call to @c Simulate after the start of NEST, - * ResetKernel or ResetNetwork. - * @node Buffers_ needs neither constructor, copy constructor or assignment operator, - * since it is initialized by @c init_nodes_(). If Buffers_ has members that - * cannot destroy themselves, Buffers_ will need a destructor. - */ - struct Buffers_ { - Buffers_({{neuronName}} &); - Buffers_(const Buffers_ &, {{neuronName}} &); - - /** Logger for all analog data */ - nest::UniversalDataLogger<{{neuronName}}> logger_; - {% if ((neuron.get_multiple_receptors())|length > 1) or neuron.is_array_buffer() %} - std::vector receptor_types_; - {% endif %} - - {%- if ((neuron.get_multiple_receptors())|length > 1) -%} - /** buffers and sums up incoming spikes/currents */ - std::vector< nest::RingBuffer > spike_inputs_; - - {% for inputPort in neuron.get_spike_buffers() %} - {{printer.print_buffer_array_getter(inputPort)}} - {{printer.print_buffer_declaration_value(inputPort)}}; - {% endfor %} - {% else -%} - {% for inputPort in neuron.get_spike_buffers() %} - {{printer.print_buffer_getter(inputPort, true)}} - {{printer.print_buffer_declaration_header(inputPort)}} - {{printer.print_buffer_declaration(inputPort)}}; - {{printer.print_buffer_declaration_value(inputPort)}}; - {% endfor %} - {% endif -%} - - {% for inputPort in neuron.get_current_buffers() -%} - {{printer.print_buffer_declaration_header(inputPort)}} - {{printer.print_buffer_declaration(inputPort)}}; - {{printer.print_buffer_getter(inputPort, true)}} - {{printer.print_buffer_declaration_value(inputPort)}}; - {% endfor %} - - {%- if useGSL -%} - /** GSL ODE stuff */ - gsl_odeiv_step* __s; //!< stepping function - gsl_odeiv_control* __c; //!< adaptive stepsize control function - gsl_odeiv_evolve* __e; //!< evolution function - gsl_odeiv_system __sys; //!< struct describing system - - // IntergrationStep_ should be reset with the neuron on ResetNetwork, - // but remain unchanged during calibration. Since it is initialized with - // step_, and the resolution cannot change after nodes have been created, - // it is safe to place both here. - double __step; //!< step size in ms - double __integration_step; //!< current integration time step, updated by GSL - {% endif -%} - }; - - /* getters/setters for state block */ - - {%- for state in neuron.get_state_symbols() -%} - {%- with variable = state -%} - {%- include "directives/MemberVariableGetterSetter.jinja2" -%} - {%- endwith -%} - {%- endfor -%} - - /* getters/setters for initial values block (excluding functions) */ - - {%- for init in neuron.get_non_function_initial_values_symbols() %} - {%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} - {%- with variable = init %} - {%- include "directives/MemberVariableGetterSetter.jinja2" %} - {%- endwith %} - {%- endif %} - {%- endfor %} - - /* getters/setters for parameters */ - - {% for parameter in neuron.get_parameter_symbols() -%} - {% with variable = parameter -%} - {% include "directives/MemberVariableGetterSetter.jinja2" -%} - {% endwith -%} - {% endfor -%} - - /* getters/setters for parameters */ - - {% for internal in neuron.get_internal_non_alias_symbols() -%} - {% with variable = internal -%} - {% include "directives/MemberVariableGetterSetter.jinja2" -%} - {% endwith -%} - {% endfor -%} - - /* getters/setters for functions */ - - {% for funcsym in neuron.get_function_symbols() %} - {% with variable = funcsym %} - {% include "directives/MemberVariableGetterSetter.jinja2" -%} - {% endwith -%} - {% endfor %} - - /* getters/setters for input buffers */ - - {% for buffer in neuron.get_input_buffers() %} - {{printer.print_buffer_getter(buffer, false)}}; - {% endfor %} - - /* function declarations */ - - {% for function in neuron.get_functions() %} - {{printer.print_function_declaration(function)}}; - {% endfor %} - - /** - * @defgroup pif_members Member variables of neuron model. - * Each model neuron should have precisely the following four data members, - * which are one instance each of the parameters, state, buffers and variables - * structures. Experience indicates that the state and variables member should - * be next to each other to achieve good efficiency (caching). - * @note Devices require one additional data member, an instance of the @c Device - * child class they belong to. - * @{ - */ - Parameters_ P_; //!< Free parameters. - State_ S_; //!< Dynamic state. - Variables_ V_; //!< Internal Variables - Buffers_ B_; //!< Buffers. - - //! Mapping of recordables names to access functions - static nest::RecordablesMap<{{neuronName}}> recordablesMap_; - - {% if useGSL -%} - friend int {{neuronName}}_dynamics( double, const double y[], double f[], void* pnode ); - {% endif %} - - {%- if norm_rng -%} - librandom::NormalRandomDev normal_dev_; //!< random deviate generator - {% endif %} - -/** @} */ -}; /* neuron {{neuronName}} */ - -inline nest::port {{neuronName}}::send_test_event( - nest::Node& target, nest::rport receptor_type, nest::synindex, bool){ - // You should usually not change the code in this function. - // It confirms that the target of connection @c c accepts @c {{outputEvent}} on - // the given @c receptor_type. - {{outputEvent}} e; - e.set_sender(*this); - return target.handles_test_event(e, receptor_type); -} -{% if is_spike_input %} -inline nest::port {{neuronName}}::handles_test_event(nest::SpikeEvent&, nest::port receptor_type){ - {% if neuron.is_multisynapse_spikes() -%} - if ( receptor_type <= 0 || receptor_type > static_cast< nest::port >( get_{{neuron.get_spike_buffers()[0].get_vector_parameter()}}()) ) { - // TODO refactor me. The code assumes that there is only one. Check by coco. - throw nest::IncompatibleReceptorType( receptor_type, get_name(), "SpikeEvent" ); - } - return receptor_type; - {% elif neuron.get_multiple_receptors()|length > 1 -%} - assert( B_.spike_inputs_.size() == {{(neuron.get_multiple_receptors())|length}} ); - - if ( !( INF_SPIKE_RECEPTOR < receptor_type && receptor_type < SUP_SPIKE_RECEPTOR ) ) - { - throw nest::UnknownReceptorType( receptor_type, get_name() ); - return 0; - } - else { - return receptor_type - 1; - }{%- else %} - // You should usually not change the code in this function. - // It confirms to the connection management system that we are able - // to handle @c SpikeEvent on port 0. You need to extend the function - // if you want to differentiate between input ports. - if (receptor_type != 0) - throw nest::UnknownReceptorType(receptor_type, get_name()); - return 0; - {%- endif %} -} -{% endif %} - -{% if is_current_input %} -inline nest::port {{neuronName}}::handles_test_event( - nest::CurrentEvent&, nest::port receptor_type){ - // You should usually not change the code in this function. - // It confirms to the connection management system that we are able - // to handle @c CurrentEvent on port 0. You need to extend the function - // if you want to differentiate between input ports. - if (receptor_type != 0) - throw nest::UnknownReceptorType(receptor_type, get_name()); - return 0; -} -{% endif %} -inline nest::port {{neuronName}}::handles_test_event( - nest::DataLoggingRequest& dlr, nest::port receptor_type){ - // You should usually not change the code in this function. - // It confirms to the connection management system that we are able - // to handle @c DataLoggingRequest on port 0. - // The function also tells the built-in UniversalDataLogger that this node - // is recorded from and that it thus needs to collect data during simulation. - if (receptor_type != 0) - throw nest::UnknownReceptorType(receptor_type, get_name()); - - return B_.logger_.connect_logging_device(dlr, recordablesMap_); -} - -// TODO call get_status on used or internal components -inline void {{neuronName}}::get_status(DictionaryDatum &__d) const{ - - // parameters - {%- for parameter in neuron.get_parameter_symbols() -%} - {%- with variable = parameter %} - {%- filter indent(2,True) %} - {%- include "directives/WriteInDictionary.jinja2" %} - {%- endfilter %} - {%- endwith %} - {%- endfor %} - - // initial values for state variables not in ODE or kernel - {%- for state in neuron.get_state_non_alias_symbols() %} - {%- with variable = state %} - {%- filter indent(2,True) %} - {%- include "directives/WriteInDictionary.jinja2" %} - {%- endfilter %} - {%- endwith %} - {%- endfor %} - - // initial values for state variables in ODE or kernel - {%- for init in neuron.get_initial_values_non_alias_symbols() %} - {%- with variable = init %} - {%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} - {%- filter indent(2,True) %} - {%- include "directives/WriteInDictionary.jinja2" %} - {%- endfilter %} - {%- endif %} - {%- endwith %} - {%- endfor %} - - ArchivingNode::get_status( __d ); - - {% if (neuron.get_multiple_receptors())|length > 1 -%} - DictionaryDatum __receptor_type = new Dictionary(); - {% for spikeBuffer in neuron.get_multiple_receptors() -%} - ( *__receptor_type )[ "{{spikeBuffer.get_symbol_name().upper()}}" ] = {{spikeBuffer.get_symbol_name().upper()}}; - {% endfor %} - ( *__d )[ "receptor_types" ] = __receptor_type; - {% endif %} - - (*__d)[nest::names::recordables] = recordablesMap_.get_list(); - {% if useGSL %} - def< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol); - if ( P_.__gsl_error_tol <= 0. ){ - throw nest::BadProperty( "The gsl_error_tol must be strictly positive." ); - } - {% endif %} - -} - -inline void {{neuronName}}::set_status(const DictionaryDatum &__d){ - // parameters - {%- for parameter in neuron.get_parameter_symbols() -%} - {%- with variable = parameter %} - {%- filter indent(2,True) %} - {%- include "directives/ReadFromDictionaryToTmp.jinja2" %} - {%- endfilter %} - {%- endwith %} - {%- endfor %} - - // initial values for state variables not in ODE or kernel - {%- for state in neuron.get_state_non_alias_symbols() %} - {%- with variable = state %} - {%- filter indent(2,True) %} - {%- include "directives/ReadFromDictionaryToTmp.jinja2" %} - {%- endfilter %} - {%- endwith %} - {%- endfor %} - - // initial values for state variables in ODE or kernel - {%- for init in neuron.get_initial_values_non_alias_symbols() %} - {%- with variable = init %} - {%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} - {%- filter indent(2,True) %} - {%- include "directives/ReadFromDictionaryToTmp.jinja2" %} - {%- endfilter %} - {%- endif %} - {%- endwith %} - {%- endfor %} - - // We now know that (ptmp, stmp) are consistent. We do not - // write them back to (P_, S_) before we are also sure that - // the properties to be set in the parent class are internally - // consistent. - ArchivingNode::set_status(__d); - - // if we get here, temporaries contain consistent set of properties - {%- for parameter in neuron.get_parameter_symbols() -%} - {%- with variable = parameter -%} - {%- filter indent(2,True) %} - {%- include "directives/AssignTmpDictionaryValue.jinja2" -%} - {%- endfilter %} - {%- endwith -%} - {%- endfor -%} - - {%- for state in neuron.get_state_non_alias_symbols() -%} - {%- with variable = state %} - {%- filter indent(2,True) %} - {%- include "directives/AssignTmpDictionaryValue.jinja2" %} - {%- endfilter %} - {%- endwith %} - {%- endfor %} - - {%- for init in neuron.get_initial_values_non_alias_symbols() %} - {%- with variable = init %} - {%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} - {%- filter indent(2,True) %} - {%- include "directives/AssignTmpDictionaryValue.jinja2" %} - {%- endfilter %} - {%- endif %} - {%- endwith %} - {%- endfor %} - - {% for invariant in neuron.get_parameter_invariants() %} - if ( !({{printer.print_expression(invariant)}}) ) { - throw nest::BadProperty("The constraint '{{idemPrinter.print_expression(invariant)}}' is violated!"); - } - {%- endfor -%} - - {% if useGSL %} - updateValue< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol); - if ( P_.__gsl_error_tol <= 0. ){ - throw nest::BadProperty( "The gsl_error_tol must be strictly positive." ); - } - {% endif %} -}; - -#endif /* #ifndef {{neuronName.upper()}} */ -{%- if useGSL %} -#endif /* HAVE GSL */ -{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/AnalyticIntegrationStep_begin.jinja2 b/pynestml/codegeneration/resources_nest/directives/AnalyticIntegrationStep_begin.jinja2 deleted file mode 100644 index 6e9651a2f..000000000 --- a/pynestml/codegeneration/resources_nest/directives/AnalyticIntegrationStep_begin.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ -{# - Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. -#} -{% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if uses_analytic_solver -%} -{% for variable_name in analytic_state_variables: -%} -{% set update_expr = update_expressions[variable_name] -%} - double {{variable_name}}__tmp = {{printer.print_expression(update_expr)}}; -{% endfor -%} -{% endif -%} diff --git a/pynestml/codegeneration/resources_nest/directives/AnalyticIntegrationStep_end.jinja2 b/pynestml/codegeneration/resources_nest/directives/AnalyticIntegrationStep_end.jinja2 deleted file mode 100644 index 3d4dda992..000000000 --- a/pynestml/codegeneration/resources_nest/directives/AnalyticIntegrationStep_end.jinja2 +++ /dev/null @@ -1,11 +0,0 @@ -{# - Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. -#} -/* replace analytically solvable variables with precisely integrated values */ -{% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if uses_analytic_solver -%} -{% for variable_name in analytic_state_variables: -%} -{% set variable_sym = analytic_variable_symbols[variable_name] -%} - {{printer.print_origin(variable_sym)}}{{names.name(variable_sym)}} = {{variable_name}}__tmp; -{% endfor -%} -{% endif -%} diff --git a/pynestml/codegeneration/resources_nest/directives/AssignTmpDictionaryValue.jinja2 b/pynestml/codegeneration/resources_nest/directives/AssignTmpDictionaryValue.jinja2 deleted file mode 100644 index eeffe48b5..000000000 --- a/pynestml/codegeneration/resources_nest/directives/AssignTmpDictionaryValue.jinja2 +++ /dev/null @@ -1,16 +0,0 @@ -{# - Assigns a tmp value which was read from the dictionary to the corresponding block variable. - - @param variable VariableSymbol - @result C++ Block -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if not variable.is_function %} -{% if not variable.is_init_values %} - {{names.setter(variable)}}(tmp_{{names.name(variable)}}); -{% else %} - {{names.setter(variable)}}(tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}}); -{% endif %} -{%- else %} - // ignores '{{names.name(variable)}}' {{declarations.print_variable_type(variable)}}' since it is an function and setter isn't defined -{%- endif %} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/directives/Block.jinja2 b/pynestml/codegeneration/resources_nest/directives/Block.jinja2 deleted file mode 100644 index d772436ce..000000000 --- a/pynestml/codegeneration/resources_nest/directives/Block.jinja2 +++ /dev/null @@ -1,13 +0,0 @@ -{# - Handles a complex block statement - @grammar: Block = ( Stmt | NEWLINE )*; - @param ast ASTBlock -#} -{% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% for statement in ast.get_stmts() -%} -{% filter indent(2,True) -%} -{% with stmt = statement -%} -{% include "directives/Statement.jinja2" -%} -{% endwith -%} -{% endfilter %} -{% endfor -%} diff --git a/pynestml/codegeneration/resources_nest/directives/Calibrate.jinja2 b/pynestml/codegeneration/resources_nest/directives/Calibrate.jinja2 deleted file mode 100644 index 7a264651a..000000000 --- a/pynestml/codegeneration/resources_nest/directives/Calibrate.jinja2 +++ /dev/null @@ -1,27 +0,0 @@ -{# - TODO: instead of using 0 a default value provider must be used --#} -{%- if variable.has_vector_parameter() %} -{%- if tracing %} -/* generated by {{self._TemplateReference__context.name}} */ -{%- endif %} -{{printer.print_origin(variable)}} {{variable.get_symbol_name()}}.resize(P_.{{variable.get_vector_parameter()}}); -for (long i=0; i < get_{{variable.get_vector_parameter()}}(); i++) { - {{printer.print_origin(variable)}} {{variable.get_symbol_name()}}[i] = -{%- if variable.has_declaring_expression() %} - {{printer.print_expression(variable.get_declaring_expression())}} -{%- else %} - 0 -{%- endif %}; -} -{%- else %} -{%- if tracing %} -/* generated by {{self._TemplateReference__context.name}} */ -{%- endif %} -{{printer.print_origin(variable)}}{{variable.get_symbol_name()}} = -{%- if variable.has_declaring_expression() -%} -{{printer.print_expression(variable.get_declaring_expression())}} -{%- else %} -0 -{%- endif %}; -{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/CompoundStatement.jinja2 b/pynestml/codegeneration/resources_nest/directives/CompoundStatement.jinja2 deleted file mode 100644 index 08a3c64b7..000000000 --- a/pynestml/codegeneration/resources_nest/directives/CompoundStatement.jinja2 +++ /dev/null @@ -1,18 +0,0 @@ -{# - Handles the compound statement. - @grammar: Compound_Stmt = IF_Stmt | FOR_Stmt | WHILE_Stmt; -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if stmt.is_if_stmt() -%} -{%- with ast = stmt.get_if_stmt() -%} -{%- include "directives/IfStatement.jinja2" -%} -{%- endwith -%} -{%- elif stmt.is_for_stmt() -%} -{%- with ast = stmt.get_for_stmt() -%}} -{%- include "directives/ForStatement.jinja2" -%} -{%- endwith -%} -{%- elif stmt.is_while_stmt() -%} -{%- with ast = stmt.get_while_stmt() -%}} -{%- include "directives/WhileStatement.jinja2" -%} -{%- endwith -%} -{%- endif -%} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/directives/FunctionCall.jinja2 b/pynestml/codegeneration/resources_nest/directives/FunctionCall.jinja2 deleted file mode 100644 index 79d293cc3..000000000 --- a/pynestml/codegeneration/resources_nest/directives/FunctionCall.jinja2 +++ /dev/null @@ -1,15 +0,0 @@ -{# - Generates C++ declaration - @param ast ASTFunctionCall -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{%- if utils.is_integrate(ast) -%} -{%- include "directives/AnalyticIntegrationStep_begin.jinja2" -%} -{%- if uses_numeric_solver %} -{%- include "directives/GSLIntegrationStep.jinja2" %} -{%- endif %} -{%- include "directives/AnalyticIntegrationStep_end.jinja2" -%} -{%- include "directives/ApplySpikesFromBuffers.jinja2" -%} -{%- else -%} -{{printer.print_method_call(ast)}}; -{%- endif -%} diff --git a/pynestml/codegeneration/resources_nest/directives/GSLDifferentiationFunction.jinja2 b/pynestml/codegeneration/resources_nest/directives/GSLDifferentiationFunction.jinja2 deleted file mode 100644 index 39bacc0f8..000000000 --- a/pynestml/codegeneration/resources_nest/directives/GSLDifferentiationFunction.jinja2 +++ /dev/null @@ -1,42 +0,0 @@ -{# - Creates GSL implementation of the differentiation step for the system of ODEs. --#} -extern "C" inline int {{neuronName}}_dynamics(double, const double ode_state[], double f[], void* pnode){ - typedef {{neuronName}}::State_ State_; - // get access to node so we can almost work as in a member function - assert( pnode ); - const {{neuronName}}& node = *( reinterpret_cast< {{neuronName}}* >( pnode ) ); - - // ode_state[] here is---and must be---the state vector supplied by the integrator, - // not the state vector in the node, node.S_.ode_state[]. - -{%- for ode in neuron.get_equations_blocks().get_declarations() %} -{%- for function in utils.get_alias_symbols(ode) %} -{%- if not function.is_equation() %} -{%- set declaringExpression = function.get_declaring_expression() %} - double {{names.name(function)}} = {{printerGSL.print_expression(declaringExpression, prefix="node.")}}; -{%- endif %} -{%- endfor %} -{%- endfor %} - -{# todo by kp: this part is no longer required since we make all functions self contained -{%- for function in neuron.get_function_symbols() %} -{%- set declaringExpression = function.get_declaring_expression() %} - double {{names.name(function)}} = {{printerGSL.print_expression(declaringExpression, prefix="node.")}}; -{%- endfor %} -#} - -{%- for variable_name in numeric_state_variables: %} -{%- set update_expr = numeric_update_expressions[variable_name] %} -{%- set variable_sym = numeric_variable_symbols[variable_name] %} - f[{{names.array_index(variable_sym)}}] = {{printerGSL.print_expression(update_expr, prefix="node.")}}; -{%- endfor %} - -{%- for variable_name in non_equations_state_variables: %} -{%- set variable_sym = neuron.get_initial_values_blocks().get_scope().resolve_to_symbol(variable_name, SymbolKind.VARIABLE) %} - f[{{names.array_index(variable_sym)}}] = 0.; -{%- endfor %} - - return GSL_SUCCESS; -} - diff --git a/pynestml/codegeneration/resources_nest/directives/IfStatement.jinja2 b/pynestml/codegeneration/resources_nest/directives/IfStatement.jinja2 deleted file mode 100644 index e511a8692..000000000 --- a/pynestml/codegeneration/resources_nest/directives/IfStatement.jinja2 +++ /dev/null @@ -1,22 +0,0 @@ -{# - Generates C++ declaration - @param ast ASTIfStmt -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -if ({{printer.print_expression(ast.get_if_clause().get_condition())}}) { -{%- with ast = ast.get_if_clause().get_block() -%} -{%- include "directives/Block.jinja2" -%} -{%- endwith -%} -{%- for elif in ast.get_elif_clauses() -%} -}else if({{printer.print_expression(elif.get_condition())}}) { -{%- with ast = elif.get_block() -%} -{%- include "directives/Block.jinja2" -%} -{%- endwith -%} -{%- endfor -%} -{%- if ast.has_else_clause() %} -} else { {%- with ast = ast.get_else_clause().get_block() -%} -{%- include "directives/Block.jinja2" -%} -{%- endwith -%} -{%- endif -%} -} /* if end */ - diff --git a/pynestml/codegeneration/resources_nest/directives/MemberInitialization.jinja2 b/pynestml/codegeneration/resources_nest/directives/MemberInitialization.jinja2 deleted file mode 100644 index 5be53a835..000000000 --- a/pynestml/codegeneration/resources_nest/directives/MemberInitialization.jinja2 +++ /dev/null @@ -1,18 +0,0 @@ -{# - In general case creates an - @param variable VariableSymbol Variable for which the initialization should be done --#} -{% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif -%} -{%- if variable.has_declaring_expression() and (not neuron.get_kernel_by_name(variable.name)) %} -{%- if variable.has_vector_parameter() %} -{{printer.print_origin(variable)}}{{names.name(variable)}}.resize(P_.{{variable.get_vector_parameter()}}, {{printer.print_expression(variable.get_declaring_expression())}}); // as {{variable.get_type_symbol().print_symbol()}} -{%- else %} -{{printer.print_origin(variable)}}{{names.name(variable)}} = {{printer.print_expression(variable.get_declaring_expression())}}; // as {{variable.get_type_symbol().print_symbol()}} -{%- endif %} -{%- else %} -{%- if variable.has_vector_parameter() %} -{{printer.print_origin(variable)}}{{names.name(variable)}}.resize(0); // as {{variable.get_type_symbol().print_symbol()}} -{%- else %} -{{printer.print_origin(variable)}}{{names.name(variable)}} = 0; // as {{variable.get_type_symbol().print_symbol()}} -{%- endif -%} -{%- endif -%} diff --git a/pynestml/codegeneration/resources_nest/directives/MemberVariableGetterSetter.jinja2 b/pynestml/codegeneration/resources_nest/directives/MemberVariableGetterSetter.jinja2 deleted file mode 100644 index 692c457d4..000000000 --- a/pynestml/codegeneration/resources_nest/directives/MemberVariableGetterSetter.jinja2 +++ /dev/null @@ -1,17 +0,0 @@ -{# - Generates the getter function for the variable. - @param variable VariableSymbol that captures the variable from the model -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{%- if variable.is_function and not utils.contains_sum_call(variable) %} - inline {{declarations.print_variable_type(variable)}} {{names.getter(variable)}}() const { - return {{printer.print_expression(variable.get_declaring_expression())}}; - } -{% else %} - inline {{declarations.print_variable_type(variable)}} {{names.getter(variable)}}() const { - return {{printer.print_origin(variable)}}{{names.name(variable)}}; - } - inline void {{names.setter(variable)}}(const {{declarations.print_variable_type(variable)}} __v) { - {{printer.print_origin(variable)}}{{names.name(variable)}} = __v; - } -{% endif %} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/directives/ReadFromDictionaryToTmp.jinja2 b/pynestml/codegeneration/resources_nest/directives/ReadFromDictionaryToTmp.jinja2 deleted file mode 100644 index a6a4690fa..000000000 --- a/pynestml/codegeneration/resources_nest/directives/ReadFromDictionaryToTmp.jinja2 +++ /dev/null @@ -1,14 +0,0 @@ -{# - Generates a code snippet that retrieves a data from dictionary and sets it the the model variable. - @param variable VariableSymbol -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if not variable.is_function and not variable.is_init_values()%} - {{declarations.print_variable_type(variable)}} tmp_{{names.name(variable)}} = {{names.getter(variable)}}(); - updateValue<{{declarations.print_variable_type(variable)}}>(__d, "{{names.name(variable)}}", tmp_{{names.name(variable)}}); -{% elif not variable.is_function and variable.is_init_values() %} - {{declarations.print_variable_type(variable)}} tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}} = {{names.getter(variable)}}(); - updateValue<{{declarations.print_variable_type(variable)}}>(__d, "{{variable.get_symbol_name()}}", tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}}); -{% else -%} - // ignores '{{names.name(variable)}}' {{declarations.print_variable_type(variable)}}' since it is an function and setter isn't defined -{% endif -%} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/directives/RecordCallback.jinja2 b/pynestml/codegeneration/resources_nest/directives/RecordCallback.jinja2 deleted file mode 100644 index 04d2fd6c5..000000000 --- a/pynestml/codegeneration/resources_nest/directives/RecordCallback.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ -{# - Registers recordables for recording - @param variable VariableSymbol --#} -{%- set varDomain = declarations.get_domain_from_type(variable.get_type_symbol()) %} -{%- if varDomain == "double" and variable.is_recordable %} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */{% endif %} -insert_("{{variable.get_symbol_name()}}", &{{neuronName}}::{{names.getter(variable)}}); -{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/SmallStatement.jinja2 b/pynestml/codegeneration/resources_nest/directives/SmallStatement.jinja2 deleted file mode 100644 index 36eaa37b3..000000000 --- a/pynestml/codegeneration/resources_nest/directives/SmallStatement.jinja2 +++ /dev/null @@ -1,22 +0,0 @@ -{# - Generates a single small statement into equivalent C++ syntax. - @param stmt ASTSmallStmt -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{%- if stmt.is_assignment() -%} -{%- with ast = stmt.get_assignment() -%} -{%- include "directives/Assignment.jinja2" -%} -{%- endwith -%} -{%- elif stmt.is_function_call() -%} -{%- with ast = stmt.get_function_call() -%} -{%- include "directives/FunctionCall.jinja2" -%} -{%- endwith -%} -{%- elif stmt.is_declaration() -%} -{%- with ast = stmt.get_declaration() -%} -{%- include "directives/Declaration.jinja2" -%} -{%- endwith -%} -{%- elif stmt.is_return_stmt() -%} -{%- with ast = stmt.get_return_stmt() -%} -{%- include "directives/ReturnStatement.jinja2" -%} -{%- endwith -%} -{%- endif -%} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/directives/Statement.jinja2 b/pynestml/codegeneration/resources_nest/directives/Statement.jinja2 deleted file mode 100644 index 0a5740ac5..000000000 --- a/pynestml/codegeneration/resources_nest/directives/Statement.jinja2 +++ /dev/null @@ -1,16 +0,0 @@ -{# - Generates a single statement, either a simple or compound, to equivalent C++ syntax. - @param ast ASTSmallStmt or ASTCompoundStmt -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if stmt.has_comment() %} -{{stmt.print_comment('//')}}{% endif %} -{%- if stmt.is_small_stmt() %} -{%- with stmt = stmt.small_stmt -%} -{% include "directives/SmallStatement.jinja2" -%} -{%- endwith -%} -{% elif stmt.is_compound_stmt() -%} -{%- with stmt = stmt.compound_stmt %} -{% include "directives/CompoundStatement.jinja2" -%} -{%- endwith %} -{%- endif -%} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/directives/WhileStatement.jinja2 b/pynestml/codegeneration/resources_nest/directives/WhileStatement.jinja2 deleted file mode 100644 index b15ba6bf6..000000000 --- a/pynestml/codegeneration/resources_nest/directives/WhileStatement.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ -{# - Generates C++ declaration - @param ast ASTWhileStmt -#} -{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -while( {{printer.print_expression(ast.get_condition())}}) { -{% with ast = ast.get_block() %} -{% include "directives/Block.jinja2" %} -{% endwith %} -} /* while end */ \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/point_neuron/@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/@NEURON_NAME@.cpp.jinja2 new file mode 100644 index 000000000..442780375 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/@NEURON_NAME@.cpp.jinja2 @@ -0,0 +1,21 @@ +{#- +@NEURON_NAME@.cpp.jinja2 + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +#} +{%- include "common/NeuronClass.jinja2" %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/@NEURON_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/@NEURON_NAME@.h.jinja2 new file mode 100644 index 000000000..9673d7eaa --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/@NEURON_NAME@.h.jinja2 @@ -0,0 +1,21 @@ +{#- +@NEURON_NAME@.h.jinja2 + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +#} +{%- include "common/NeuronHeader.jinja2" %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/@SYNAPSE_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/@SYNAPSE_NAME@.h.jinja2 new file mode 100644 index 000000000..9ce86e797 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/@SYNAPSE_NAME@.h.jinja2 @@ -0,0 +1,21 @@ +{#- +@SYNAPSE_NAME@.h.jinja2 + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +#} +{%- include "common/SynapseHeader.h.jinja2" %} diff --git a/pynestml/codegeneration/resources_nest/__init__.py b/pynestml/codegeneration/resources_nest/point_neuron/__init__.py similarity index 100% rename from pynestml/codegeneration/resources_nest/__init__.py rename to pynestml/codegeneration/resources_nest/point_neuron/__init__.py diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 new file mode 100644 index 000000000..0ab7676b1 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 @@ -0,0 +1,979 @@ +// #define DEBUG 1 +{# +NeuronClass.jinja2 + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */{% endif -%} +/* + * {{neuronName}}.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + * Generated from NESTML at time: {{now}} +**/ + +// C++ includes: +#include + +// Includes from libnestutil: +#include "numerics.h" + +// Includes from nestkernel: +#include "exceptions.h" +#include "kernel_manager.h" +#include "universal_data_logger_impl.h" + +// Includes from sli: +#include "dict.h" +#include "dictutils.h" +#include "doubledatum.h" +#include "integerdatum.h" +#include "lockptrdatum.h" + +#include "{{neuronName}}.h" + +{%- set stateSize = neuron.get_non_inline_state_symbols()|length %} + +// --------------------------------------------------------------------------- +// Recordables map +// --------------------------------------------------------------------------- +{%- if not has_state_vectors %} +nest::RecordablesMap<{{neuronName}}> {{neuronName}}::recordablesMap_; +{%- endif %} +namespace nest +{ + + // Override the create() method with one call to RecordablesMap::insert_() + // for each quantity to be recorded. +{%- if has_state_vectors %} +template <> void DynamicRecordablesMap<{{neuronName}}>::create({{neuronName}}& host) +{%- else %} +template <> void RecordablesMap<{{neuronName}}>::create() +{%- endif %} + { + +{%- if recordable_state_variables|length > 0 %} +{%- if has_state_vectors %} +{%- for sym in recordable_state_variables %} +{%- if not sym.has_vector_parameter() %} + insert("{{sym.get_symbol_name()}}", host.get_data_access_functor( {{neuronName}}::State_::{{names.name(sym).upper()}} )); +{%- endif %} +{%- endfor %} +{%- else %} + // add state variables to recordables map +{%- for sym in recordable_state_variables %} + insert_({{names_namespace}}::_{{sym.get_symbol_name()}}, &{{neuronName}}::{{names.getter(sym)}}); +{%- endfor %} +{%- endif %} +{%- endif %} + +{%- if recordable_inline_expressions|length > 0 %} + // add recordable inline expressions to recordables map +{%- for sym in recordable_inline_expressions %} + insert_({{names_namespace}}::_{{sym.get_symbol_name()}}, &{{neuronName}}::{{names.getter(sym)}}); +{%- endfor %} +{%- endif %} + + // Add vector variables +{%- filter indent(2,True) %} +{%- if has_state_vectors %} + host.insert_recordables(); +{%- endif %} +{%- endfilter %} + } +} + +{%- if has_state_vectors %} + std::string {{neuronName}}::get_var_name(size_t elem, std::string var_name) + { + std::stringstream n; + n << var_name << elem + 1; + return n.str(); + } + + void {{neuronName}}::insert_recordables(size_t first) + { +{%- for variable in neuron.get_vector_state_symbols() %} + for (size_t i = 0; i < {{printer.print_vector_size_parameter(variable)}}; i++) + { + size_t elem = {{neuronName}}::State_::{{names.name(variable).upper()}} + i; + recordablesMap_.insert(get_var_name(i, "{{names.name(variable).upper()}}_"), this->get_data_access_functor(elem)); + } +{%- endfor %} + } + + nest::DataAccessFunctor< {{neuronName}} > + {{neuronName}}::get_data_access_functor( size_t elem ) + { + return nest::DataAccessFunctor< {{neuronName}} >( *this, elem ); + } +{%- endif %} + +// --------------------------------------------------------------------------- +// Default constructors defining default parameters and state +// Note: the implementation is empty. The initialization is of variables +// is a part of {{neuronName}}'s constructor. +// --------------------------------------------------------------------------- + +{{neuronName}}::Parameters_::Parameters_() +{ +} + +{{neuronName}}::State_::State_() +{ +} + +// --------------------------------------------------------------------------- +// Parameter and state extractions and manipulation functions +// --------------------------------------------------------------------------- + +{{neuronName}}::Buffers_::Buffers_({{neuronName}} &n): + logger_(n) +{%- if neuron.get_multiple_receptors()|length > 1 %} + , spike_inputs_( std::vector< nest::RingBuffer >( SUP_SPIKE_RECEPTOR - 1 ) ) +{%- endif %} +{%- if uses_numeric_solver %} + , __s( 0 ), __c( 0 ), __e( 0 ) +{%- endif %} +{ + // Initialization of the remaining members is deferred to init_buffers_(). +} + +{{neuronName}}::Buffers_::Buffers_(const Buffers_ &, {{neuronName}} &n): + logger_(n) +{%- if neuron.get_multiple_receptors()|length > 1 %} + , spike_inputs_( std::vector< nest::RingBuffer >( SUP_SPIKE_RECEPTOR - 1 ) ) +{%- endif %} +{%- if uses_numeric_solver %} + , __s( 0 ), __c( 0 ), __e( 0 ) +{%- endif %} +{ + // Initialization of the remaining members is deferred to init_buffers_(). +} + +// --------------------------------------------------------------------------- +// Default constructor for node +// --------------------------------------------------------------------------- + +{{neuronName}}::{{neuronName}}():{{neuron_parent_class}}(), P_(), S_(), B_(*this) +{ + const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + calibrate(); +{%- else %} + pre_run_hook(); +{%- endif %} + +{%- if uses_numeric_solver %} + + // use a default "good enough" value for the absolute error. It can be adjusted via `node.set()` + P_.__gsl_error_tol = 1e-3; +{%- endif %} + +{%- if parameter_syms_with_iv|length > 0 %} + // initial values for parameters +{%- filter indent(2) %} +{%- for parameter in parameter_syms_with_iv %} +{%- with variable = parameter %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} +{%- endif %} + +{%- if neuron.get_state_symbols()|length > 0 %} + // initial values for state variables +{%- filter indent(2) %} +{%- for init in neuron.get_state_symbols() %} +{%- with variable = init %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} +{%- endif %} + +{%- if has_state_vectors %} + recordablesMap_.create(*this); +{%- else %} + recordablesMap_.create(); +{%- endif %} + + +{%- if paired_synapse is defined %} + // state variables for archiving state for paired synapse + n_incoming_ = 0; + max_delay_ = 0; + last_spike_ = -1.; + + // cache initial values +{%- for var in transferred_variables %} +{%- with var_sym = transferred_variables_syms[var] %} +{%- if not var == var_sym.get_symbol_name() %} +{{ raise('Error in resolving variable to symbol') }} +{%- endif %} + {{var}}__iv = {{names.getter(var_sym)}}(); +{%- endwith %} +{%- endfor %} +{%- endif %} +} + +// --------------------------------------------------------------------------- +// Copy constructor for node +// --------------------------------------------------------------------------- + +{{neuronName}}::{{neuronName}}(const {{neuronName}}& __n): + {{neuron_parent_class}}(), P_(__n.P_), S_(__n.S_), B_(__n.B_, *this) { + + // copy parameter struct P_ +{%- for parameter in neuron.get_parameter_symbols() %} + P_.{{names.name(parameter)}} = __n.P_.{{names.name(parameter)}}; +{%- endfor %} + + // copy state struct S_ +{%- for init in neuron.get_state_symbols() %} +{%- if not is_delta_kernel(neuron.get_kernel_by_name(init.name)) %} + S_.{{names.name(init)}} = __n.S_.{{names.name(init)}}; +{%- endif %} +{%- endfor %} + + + // copy internals V_ +{%- for internal in neuron.get_internal_symbols() %} + V_.{{names.name(internal)}} = __n.V_.{{names.name(internal)}}; +{%- endfor %} + +{%- if has_state_vectors %} + recordablesMap_.create(*this); +{%- endif %} +{%- if paired_synapse is defined %} + n_incoming_ = __n.n_incoming_; + max_delay_ = __n.max_delay_; + last_spike_ = __n.last_spike_; + + // cache initial values +{%- for var in transferred_variables %} +{%- with var_sym = transferred_variables_syms[var] %} +{%- if not var == var_sym.get_symbol_name() %} +{{ raise('Error in resolving variable to symbol') }} +{%- endif %} + {{var}}__iv = {{names.getter(var_sym)}}(); +{%- endwith %} +{%- endfor %} +{%- endif %} +} + +// --------------------------------------------------------------------------- +// Destructor for node +// --------------------------------------------------------------------------- + +{{neuronName}}::~{{neuronName}}() +{ +{%- if uses_numeric_solver %} + // GSL structs may not have been allocated, so we need to protect destruction + + if (B_.__s) + { + gsl_odeiv_step_free( B_.__s ); + } + + if (B_.__c) + { + gsl_odeiv_control_free( B_.__c ); + } + + if (B_.__e) + { + gsl_odeiv_evolve_free( B_.__e ); + } +{%- endif %} +} + +// --------------------------------------------------------------------------- +// Node initialization functions +// --------------------------------------------------------------------------- + +{%- if nest_version.startswith("v2") %} +void {{neuronName}}::init_state_(const Node& proto) +{ + const {{neuronName}}& pr = downcast<{{neuronName}}>(proto); + S_ = pr.S_; +} +{%- endif %} + +void {{neuronName}}::init_buffers_() +{ +{%- for port in neuron.get_input_ports() %} + {{ printer.print_buffer_initialization(port) }} +{%- endfor %} + B_.logger_.reset(); // includes resize +{%- if has_delay_variables %} + // Initialize helper variables for delay-based variables +{%- for variable in neuron.get_state_symbols() %} +{%- if variable.has_delay_parameter() %} +{%- include "directives/DelayVariablesInitialization.jinja2" %} +{%- endif %} +{%- endfor %} +{%- endif %} + +{%- if paired_neuron is defined %} + clear_history(); +{%- endif %} +{%- if uses_numeric_solver %} + + if ( B_.__s == 0 ) + { + B_.__s = gsl_odeiv_step_alloc( gsl_odeiv_step_rkf45, {{stateSize}} ); + } + else + { + gsl_odeiv_step_reset( B_.__s ); + } + + if ( B_.__c == 0 ) + { + B_.__c = gsl_odeiv_control_y_new( P_.__gsl_error_tol, 0.0 ); + } + else + { + gsl_odeiv_control_init( B_.__c, P_.__gsl_error_tol, 0.0, 1.0, 0.0 ); + } + + if ( B_.__e == 0 ) + { + B_.__e = gsl_odeiv_evolve_alloc( {{stateSize}} ); + } + else + { + gsl_odeiv_evolve_reset( B_.__e ); + } + + B_.__sys.function = {{neuronName}}_dynamics; + B_.__sys.jacobian = NULL; + B_.__sys.dimension = {{stateSize}}; + B_.__sys.params = reinterpret_cast< void* >( this ); + B_.__step = nest::Time::get_resolution().get_ms(); + B_.__integration_step = nest::Time::get_resolution().get_ms(); +{%- endif %} +} + +void {{neuronName}}::recompute_internal_variables(bool exclude_timestep) { + const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function + + if (exclude_timestep) { +{%- filter indent(4,True) %} +{%- for variable in neuron.get_internal_symbols() %} +{%- if variable.name != "__h" %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endif %} +{%- endfor %} +{%- endfilter %} + } + else { + // internals V_ +{%- filter indent(4) %} +{%- for variable in neuron.get_internal_symbols() %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endfor %} +{%- endfilter %} + } +} + +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +void {{neuronName}}::calibrate() { +{%- else %} +void {{neuronName}}::pre_run_hook() { +{%- endif %} + B_.logger_.init(); + + recompute_internal_variables(); + + // buffers B_ +{%- for port in neuron.get_input_ports() %} +{%- if port.has_vector_parameter() %} + B_.{{port.get_symbol_name()}}.resize(P_.{{port.get_vector_parameter()}}); + B_.{{port.get_symbol_name()}}_grid_sum_.resize(P_.{{port.get_vector_parameter()}}); +{%- endif %} +{%- endfor %} +} +{%- if neuron.get_functions()|length > 0 %} + +// --------------------------------------------------------------------------- +// Functions defined in the NESTML model +// --------------------------------------------------------------------------- + +{%- for function in neuron.get_functions() %} +{{printer.print_function_definition(function, neuronName)}} +{ +{%- filter indent(2,True) %} +{%- with ast = function.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +} +{%- endfor %} +{%- endif %} + +// --------------------------------------------------------------------------- +// Update and spike handling functions +// --------------------------------------------------------------------------- + +{% if uses_numeric_solver %} +{%- include "directives/GSLDifferentiationFunction.jinja2" %} +{% endif %} + +{%- if has_delay_variables %} +void {{neuronName}}::update_delay_variables() +{ +{%- for variable in neuron.get_state_symbols() %} +{%- if variable.has_delay_parameter() %} +{%- include "directives/UpdateDelayVariables.jinja2" %} +{%- endif %} +{%- endfor %} +} + +{%- for variable in neuron.get_state_symbols() %} +{%- if variable.has_delay_parameter() %} +double {{neuronName}}::get_delayed_{{variable.get_symbol_name()}}() const +{ + return DV_.delayed_{{variable.get_symbol_name()}}[ DV_.delayed_{{variable.get_symbol_name()}}_idx ]; +} +{%- endif %} +{%- endfor %} + +{%- endif %} +{%- if neuron.print_dynamics_comment('*')|length > 1 %} +/* + {{neuron.print_dynamics_comment('*')}} + */ +{%- endif %} +void {{neuronName}}::update(nest::Time const & origin,const long from, const long to) +{ + const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function + +{% if propagators_are_state_dependent %} + // the propagators are state dependent; update them! + recompute_internal_variables(); +{%- endif %} + + for ( long lag = from ; lag < to ; ++lag ) + { +{%- for inputPort in neuron.get_input_ports() %} +{%- if inputPort.has_vector_parameter() %} + for (long i=0; i < P_.{{inputPort.get_vector_parameter()}}; ++i) + { + B_.{{names.buffer_value(inputPort)}}[i] = get_{{names.name(inputPort)}}()[i].get_value(lag); + } +{%- else %} + B_.{{names.buffer_value(inputPort)}} = get_{{names.name(inputPort)}}().get_value(lag); +{%- endif %} +{%- endfor %} + +{%- if has_delay_variables %} + update_delay_variables(); +{%- endif %} + + // NESTML generated code for the update block: + +{%- if neuron.get_update_blocks() %} +{%- filter indent(2) %} +{%- set dynamics = neuron.get_update_blocks() %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +{%- endif %} + + // voltage logging + B_.logger_.record_data(origin.get_steps() + lag); + } +} + +// Do not move this function as inline to h-file. It depends on +// universal_data_logger_impl.h being included here. +void {{neuronName}}::handle(nest::DataLoggingRequest& e) +{ + B_.logger_.handle(e); +} +{% if has_spike_input %} +void {{neuronName}}::handle(nest::SpikeEvent &e) +{ + assert(e.get_delay_steps() > 0); +{%- if neuron.is_multisynapse_spikes() %} +{%- set port = neuron.get_spike_input_ports()[0] %} + B_.{{port.get_symbol_name()}}[e.get_rport() - 1].add_value( + e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); +{%- elif neuron.get_multiple_receptors()|length > 1 %} + assert( e.get_rport() < static_cast< int >( B_.spike_inputs_.size() ) ); + + B_.spike_inputs_[ e.get_rport() ].add_value( + e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); +{%- else %} + const double weight = e.get_weight(); + const double multiplicity = e.get_multiplicity(); +{%- for port in neuron.get_spike_input_ports() %} +{%- if port.is_excitatory() and port.is_inhibitory() %} + // this port receives both excitatory and inhibitory spikes (where inhibitory spikes are those where weight < 0) + get_{{port.get_symbol_name()}}(). + add_value(e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), + weight * multiplicity ); +{%- elif port.is_excitatory() %} + // this port receives excitatory spikes + if ( weight >= 0.0 ) + { + get_{{port.get_symbol_name()}}(). + add_value(e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), + weight * multiplicity ); + } +{%- elif port.is_inhibitory() %} + // this port receives inhibitory spikes + if ( weight < 0.0 ) + { + get_{{port.get_symbol_name()}}(). + add_value(e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), + -weight * multiplicity ); + } +{%- endif %} +{%- endfor %} +{%- endif %} +} +{%- endif %} + +{%- if has_continuous_input %} + +void {{neuronName}}::handle(nest::CurrentEvent& e) +{ + assert(e.get_delay_steps() > 0); + + const double current = e.get_current(); // we assume that in NEST, this returns a current in pA + const double weight = e.get_weight(); + +{%- for port in neuron.get_continuous_input_ports() %} + get_{{port.get_symbol_name()}}().add_value( + e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin()), + weight * current ); +{%- endfor %} +} +{%- endif %} + + + +{%- if paired_synapse is defined %} + + +inline double +{{neuronName}}::get_spiketime_ms() const +{ + return last_spike_; +} + + +void +{{neuronName}}::register_stdp_connection( double t_first_read, double delay ) +{ + // Mark all entries in the deque, which we will not read in future as read by + // this input input, so that we safely increment the incoming number of + // connections afterwards without leaving spikes in the history. + // For details see bug #218. MH 08-04-22 + + for ( std::deque< histentry__{{neuronName}} >::iterator runner = history_.begin(); + runner != history_.end() and ( t_first_read - runner->t_ > -1.0 * nest::kernel().connection_manager.get_stdp_eps() ); + ++runner ) + { + ( runner->access_counter_ )++; + } + + n_incoming_++; + + max_delay_ = std::max( delay, max_delay_ ); +} + + +void +{{neuronName}}::get_history__( double t1, + double t2, + std::deque< histentry__{{neuronName}} >::iterator* start, + std::deque< histentry__{{neuronName}} >::iterator* finish ) +{ + *finish = history_.end(); + if ( history_.empty() ) + { + *start = *finish; + return; + } + std::deque< histentry__{{neuronName}} >::reverse_iterator runner = history_.rbegin(); + const double t2_lim = t2 + nest::kernel().connection_manager.get_stdp_eps(); + const double t1_lim = t1 + nest::kernel().connection_manager.get_stdp_eps(); + while ( runner != history_.rend() and runner->t_ >= t2_lim ) + { + ++runner; + } + *finish = runner.base(); + while ( runner != history_.rend() and runner->t_ >= t1_lim ) + { + runner->access_counter_++; + ++runner; + } + *start = runner.base(); +} + +void +{{neuronName}}::set_spiketime( nest::Time const& t_sp, double offset ) +{ + {{neuron_parent_class}}::set_spiketime( t_sp, offset ); + + unsigned int num_transferred_variables = 0; +{%- for var in transferred_variables %} + ++num_transferred_variables; +{%- endfor %} + + const double t_sp_ms = t_sp.get_ms() - offset; + + if ( n_incoming_ ) + { + // prune all spikes from history which are no longer needed + // only remove a spike if: + // - its access counter indicates it has been read out by all connected + // STDP synapses, and + // - there is another, later spike, that is strictly more than + // (max_delay_ + eps) away from the new spike (at t_sp_ms) + while ( history_.size() > 1 ) + { + const double next_t_sp = history_[ 1 ].t_; + if ( history_.front().access_counter_ >= n_incoming_ * num_transferred_variables + and t_sp_ms - next_t_sp > max_delay_ + nest::kernel().connection_manager.get_stdp_eps() ) + { + history_.pop_front(); + } + else + { + break; + } + } + + if (history_.size() > 0) { + assert(history_.back().t_ == last_spike_); + +{%- for var in purely_numeric_state_variables_moved|sort %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var, SymbolKind.VARIABLE))}} = history_.back().{{var}}_; +{%- endfor %} +{%- for var in analytic_state_variables_moved|sort %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var, SymbolKind.VARIABLE))}} = history_.back().{{var}}_; +{%- endfor %} + } + else { +{%- for var in purely_numeric_state_variables_moved|sort %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var, SymbolKind.VARIABLE))}} = 0.; // initial value for convolution is always 0 +{%- endfor %} +{%- for var in analytic_state_variables_moved|sort %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var, SymbolKind.VARIABLE))}} = 0.; // initial value for convolution is always 0 +{%- endfor %} + } + + + /** + * update state variables transferred from synapse from `last_spike_` to `t_sp_ms` + **/ + + const double old___h = V_.__h; + V_.__h = t_sp_ms - last_spike_; + if (V_.__h > 1E-12) { + recompute_internal_variables(true); +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} + +{%- filter indent(6, True) %} +{%- with analytic_state_variables_ = analytic_state_variables_moved|sort %} +{%- include "directives/AnalyticIntegrationStep_begin.jinja2" %} +{%- endwith %} + +{%- if uses_numeric_solver %} +// update only synapse->neuron moved variables; back-up and restore the rest +double ode_state_bak[State_::STATE_VEC_SIZE]; + +{%- for variable_name in numeric_state_variables %} +ode_state_bak[State_::{{variable_name}}] = S_.ode_state[State_::{{variable_name}}]; +{%- endfor %} + +{%- if uses_numeric_solver %} +{%- include "directives/GSLIntegrationStep.jinja2" %} +{%- endif %} + +// restore non-synapse->neuron-moved variables +{%- for variable_name in numeric_state_variables %} +S_.ode_state[State_::{{variable_name}}] = ode_state_bak[State_::{{variable_name}}]; +{%- endfor %} + +// restore variables solved analytically +{%- for variable_name in numeric_state_variables %} +S_.ode_state[State_::{{variable_name}}] = ode_state_bak[State_::{{variable_name}}]; +{%- endfor %} +{%- endif %} + +{%- with analytic_state_variables_ = analytic_state_variables_moved|sort %} +{%- include "directives/AnalyticIntegrationStep_end.jinja2" %} +{%- endwith %} + +{%- endfilter %} + V_.__h = old___h; + recompute_internal_variables(true); + } + + /** + * apply spike updates + **/ + +{%- for stmt in spike_update_stmts %} +{%- if uses_numeric_solver %} + {{printer.print_node(stmt)}}; +{%- else %} + {{nest_printer.print_node(stmt)}}; +{%- endif %} +{%- endfor %} + +{%- for _, spike_update in post_spike_updates.items() %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(spike_update.get_variable().get_complete_name(), SymbolKind.VARIABLE))}} += 1.; +{%- endfor %} + + last_spike_ = t_sp_ms; + history_.push_back( histentry__{{neuronName}}( last_spike_ +{%- for var in purely_numeric_state_variables_moved|sort %} + , get_{{var}}() +{%- endfor %} +{%- for var in analytic_state_variables_moved|sort %} + , get_{{var}}() +{%- endfor %} +, 0 + ) ); + } + else + { + last_spike_ = t_sp_ms; + } +} + + +void +{{neuronName}}::clear_history() +{ + last_spike_ = -1.0; + history_.clear(); +} + + +{# + generate getter functions for the transferred variables +#} + +{%- for var in transferred_variables %} +{%- with var_sym = transferred_variables_syms[var] %} + +{%- if not var == var_sym.get_symbol_name() %} +{{ raise('Error in resolving variable to symbol') }} +{%- endif %} + +double +{{neuronName}}::get_{{var}}( double t, const bool before_increment ) +{ +#ifdef DEBUG + std::cout << "{{neuronName}}::get_{{var}}: getting value at t = " << t << std::endl; +#endif + + // case when the neuron has not yet spiked + if ( history_.empty() ) + { +#ifdef DEBUG + std::cout << "{{neuronName}}::get_{{var}}: \thistory empty, returning initial value = " << {{var}}__iv << std::endl; +#endif + // return initial value + return {{var}}__iv; + } + + // search for the latest post spike in the history buffer that came strictly before `t` + int i = history_.size() - 1; + double eps = 0.; + if ( before_increment ) { + eps = nest::kernel().connection_manager.get_stdp_eps(); + } + while ( i >= 0 ) + { + if ( t - history_[ i ].t_ >= eps ) + { +#ifdef DEBUG + std::cout<<"{{neuronName}}::get_{{var}}: \tspike occurred at history[i].t_ = " << history_[i].t_ << std::endl; +#endif + +{%- for var_ in purely_numeric_state_variables_moved %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var_, SymbolKind.VARIABLE))}} = history_[ i ].{{var_}}_; +{%- endfor %} +{%- for var_ in analytic_state_variables_moved %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var_, SymbolKind.VARIABLE))}} = history_[ i ].{{var_}}_; +{%- endfor %} + + /** + * update state variables transferred from synapse from `history[i].t_` to `t` + **/ + + if ( t - history_[ i ].t_ >= nest::kernel().connection_manager.get_stdp_eps() ) + { + const double old___h = V_.__h; + V_.__h = t - history_[i].t_; + assert(V_.__h > 0); + recompute_internal_variables(true); +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} + +{%- filter indent(6, True) %} +{%- with analytic_state_variables_ = analytic_state_variables_moved|sort %} +{%- include "directives/AnalyticIntegrationStep_begin.jinja2" %} +{%- endwith %} + +{%- if purely_numeric_state_variables_moved|length > 0 %} +double ode_state_tmp[STATE_VEC_SIZE]; + +for (int i = 0; i < STATE_VEC_SIZE; ++i) { + ode_state_tmp[i] = S_.ode_state[i]; +} + +{%- if uses_numeric_solver %} +{%- include "directives/GSLIntegrationStep.jinja2" %} +{%- endif %} + +{%- for variable_name in numeric_state_variables_moved|sort %} +{%- if not variable_name in analytic_state_variables_moved %} +S_.ode_state[State_::{{variable_name}}] = ode_state_tmp[State_::{{variable_name}}]; +{%- endif %} +{%- endfor %} +{%- endif %} + +{%- with analytic_state_variables_ = analytic_state_variables_moved|sort %} +{%- include "directives/AnalyticIntegrationStep_end.jinja2" %} +{%- endwith %} +{%- endfilter %} + + V_.__h = old___h; + recompute_internal_variables(true); + } + +#ifdef DEBUG + std::cout << "{{neuronName}}::get_{{var}}: \treturning " << {{names.getter(var_sym)}}() << std::endl; +#endif + return {{names.getter(var_sym)}}(); // type: {{declarations.print_variable_type(var_sym)}} + } + --i; + } + + // this case occurs when the trace was requested at a time precisely at that of the first spike in the history + if ( (!before_increment) && t == history_[ 0 ].t_) + { +{%- for var_ in purely_numeric_state_variables_moved %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var_, SymbolKind.VARIABLE))}} = history_[ 0 ].{{var_}}_; +{%- endfor %} +{%- for var_ in analytic_state_variables_moved %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var_, SymbolKind.VARIABLE))}} = history_[ 0 ].{{var_}}_; +{%- endfor %} + +#ifdef DEBUG + std::cout << "{{neuronName}}::get_{{var}}: \ttrace requested at exact time of history entry 0, returning " << {{names.getter(var_sym)}}() << std::endl; +#endif + return {{names.getter(var_sym)}}(); + } + + // this case occurs when the trace was requested at a time before the first spike in the history + // return initial value propagated in time +#ifdef DEBUG + std::cout << "{{neuronName}}::get_{{var}}: \tfall-through, returning initial value = " << {{var}}__iv << std::endl; +#endif + + if (t == 0.) { + return 0.; // initial value for convolution is always 0 + } + + // set to initial value +{%- for var_ in purely_numeric_state_variables_moved %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var_, SymbolKind.VARIABLE))}} = 0.; // initial value for convolution is always 0 +{%- endfor %} +{%- for var_ in analytic_state_variables_moved %} + S_.{{names.name(neuron.get_equations_block().get_scope().resolve_to_symbol(var_, SymbolKind.VARIABLE))}} = 0.; // initial value for convolution is always 0 +{%- endfor %} + + // propagate in time + const double old___h = V_.__h; + V_.__h = t; // from time 0 to the requested time + assert(V_.__h > 0); + recompute_internal_variables(true); +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} +{%- filter indent(2, True) %} +{%- with analytic_state_variables_ = analytic_state_variables_moved|sort %} +{%- include "directives/AnalyticIntegrationStep_begin.jinja2" %} +{%- endwith %} + +{%- if purely_numeric_state_variables_moved|length > 0 %} +double ode_state_tmp[STATE_VEC_SIZE]; + +for (int i = 0; i < STATE_VEC_SIZE; ++i) { + ode_state_tmp[i] = S_.ode_state[i]; +} + +{%- if uses_numeric_solver %} +{%- include "directives/GSLIntegrationStep.jinja2" %} +{%- endif %} + +{%- for variable_name in numeric_state_variables_moved|sort %} +{%- if not variable_name in analytic_state_variables_moved %} + S_.ode_state[State_::{{variable_name}}] = ode_state_tmp[State_::{{variable_name}}]; +{%- endif %} +{%- endfor %} +{%- endif %} + +{%- with analytic_state_variables_ = analytic_state_variables_moved|sort %} +{%- include "directives/AnalyticIntegrationStep_end.jinja2" %} +{%- endwith %} + +{%- endfilter %} + V_.__h = old___h; + recompute_internal_variables(true); + + return {{names.getter(var_sym)}}(); +} +{%- endwith -%} +{%- endfor %} + +{%- endif %} +{# leave this comment here to ensure newline is generated at end of file -#} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 new file mode 100644 index 000000000..bb54d1893 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 @@ -0,0 +1,911 @@ +{#- +NeuronHeader.jinja2 + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif -%} +/** + * {{neuronName}}.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + * Generated from NESTML at time: {{now}} +**/ +#ifndef {{neuronName.upper()}} +#define {{neuronName.upper()}} + +#include "config.h" +{%- if norm_rng %} + +// Includes for random number generator +{%- if nest_version.startswith("v2") %} +#include "normal_randomdev.h" +#include "uniform_randomdev.h" +{%- else %} +#include +{%- endif %} +{%- endif %} +{%- if uses_numeric_solver %} + +#ifndef HAVE_GSL +#error "The GSL library is required for neurons that require a numerical solver." +#endif + +// External includes: +#include +#include +#include +{%- endif %} + +// Includes from nestkernel: +#include "{{neuron_parent_class_include}}" +#include "connection.h" +#include "event.h" +#include "nest_types.h" +#include "ring_buffer.h" +#include "universal_data_logger.h" + +// Includes from sli: +#include "dictdatum.h" + +namespace nest +{ +namespace {{names_namespace}} +{ +{%- if neuron.get_state_symbols()|length > 0 %} +{%- for sym in neuron.get_state_symbols() %} + const Name _{{sym.get_symbol_name()}}( "{{sym.get_symbol_name()}}" ); +{%- endfor %} +{%- endif %} +{%- if recordable_inline_expressions|length > 0 %} +{%- for sym in recordable_inline_expressions %} + const Name _{{sym.get_symbol_name()}}( "{{sym.get_symbol_name()}}" ); +{%- endfor %} +{%- endif %} +{%- if neuron.get_parameter_symbols()|length > 0 %} +{%- for sym in neuron.get_parameter_symbols() %} + const Name _{{sym.get_symbol_name()}}( "{{sym.get_symbol_name()}}" ); +{%- endfor %} +{%- endif %} +} +} + + +{% if uses_numeric_solver %} +/** + * Function computing right-hand side of ODE for GSL solver. + * @note Must be declared here so we can befriend it in class. + * @note Must have C-linkage for passing to GSL. Internally, it is + * a first-class C++ function, but cannot be a member function + * because of the C-linkage. + * @note No point in declaring it inline, since it is called + * through a function pointer. + * @param void* Pointer to model neuron instance. +**/ +extern "C" inline int {{neuronName}}_dynamics( double, const double y[], double f[], void* pnode ); +{% endif %} + +#include "nest_time.h" + + +{%- if paired_synapse is defined %} + +// entry in the spiking history +class histentry__{{neuronName}} +{ +public: + histentry__{{neuronName}}( double t, +{%- for var in purely_numeric_state_variables_moved|sort%} +double {{var}}, +{%- endfor %} +{%- for var in analytic_state_variables_moved|sort%} +double {{var}}, +{%- endfor %} +size_t access_counter ) + : t_( t ) +{%- for var in purely_numeric_state_variables_moved|sort %} + , {{var}}_( {{var}} ) +{%- endfor %} +{%- for var in analytic_state_variables_moved|sort %} + , {{var}}_( {{var}} ) +{%- endfor %} + , access_counter_( access_counter ) + { + } + + double t_; //!< point in time when spike occurred (in ms) +{%- for var in purely_numeric_state_variables_moved|sort %} + double {{var}}_; +{%- endfor %} +{%- for var in analytic_state_variables_moved|sort %} + double {{var}}_; +{%- endfor %} + size_t access_counter_; //!< access counter to enable removal of the entry, once all neurons read it +}; + + + +{%- endif %} + + + + +/* BeginDocumentation + Name: {{neuronName}}. + + Description: +{% filter indent(2) %} + {{neuron.print_comment()}} +{%- endfilter %} + + Parameters: + The following parameters can be set in the status dictionary. +{% for parameter in neuron.get_parameter_symbols() -%} +{% if parameter.has_comment() -%} + {{parameter.get_symbol_name()}} [{{parameter.get_type_symbol().print_symbol()}}] {{parameter.print_comment()}} +{% endif -%} +{% endfor %} + + Dynamic state variables: +{% for state in neuron.get_state_symbols() -%} +{% if state.has_comment() -%} + {{state.get_symbol_name()}} [{{state.get_type_symbol().print_symbol()}}] {{state.print_comment()}} +{% endif -%} +{% endfor %} + + Sends: {{outputEvent}} + + Receives: {% if has_spike_input %}Spike, {% endif %}{% if has_continuous_input %}Current,{% endif %} DataLoggingRequest +*/ +class {{neuronName}} : public nest::{{neuron_parent_class}} +{ +public: + /** + * The constructor is only used to create the model prototype in the model manager. + **/ + {{neuronName}}(); + + /** + * The copy constructor is used to create model copies and instances of the model. + * @node The copy constructor needs to initialize the parameters and the state. + * Initialization of buffers and interal variables is deferred to + * @c init_buffers_() and @c pre_run_hook() (or calibrate() in NEST 3.3 and older). + **/ + {{neuronName}}(const {{neuronName}} &); + + /** + * Destructor. + **/ + ~{{neuronName}}(); + + // ------------------------------------------------------------------------- + // Import sets of overloaded virtual functions. + // See: Technical Issues / Virtual Functions: Overriding, Overloading, + // and Hiding + // ------------------------------------------------------------------------- + + using nest::Node::handles_test_event; + using nest::Node::handle; + + /** + * Used to validate that we can send {{outputEvent}} to desired target:port. + **/ + nest::port send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool); + + // ------------------------------------------------------------------------- + // Functions handling incoming events. + // We tell nest that we can handle incoming events of various types by + // defining handle() for the given event. + // ------------------------------------------------------------------------- + +{% if has_spike_input %} + void handle(nest::SpikeEvent &); //! accept spikes +{%- endif %} +{%- if has_continuous_input %} + void handle(nest::CurrentEvent &); //! accept input current +{%- endif %} + void handle(nest::DataLoggingRequest &);//! allow recording with multimeter + +{%- if has_spike_input %} + nest::port handles_test_event(nest::SpikeEvent&, nest::port); +{%- endif %} +{%- if has_continuous_input %} + nest::port handles_test_event(nest::CurrentEvent&, nest::port); +{%- endif %} + nest::port handles_test_event(nest::DataLoggingRequest&, nest::port); + + // ------------------------------------------------------------------------- + // Functions for getting/setting parameters and state values. + // ------------------------------------------------------------------------- + + void get_status(DictionaryDatum &) const; + void set_status(const DictionaryDatum &); + +{%- if paired_synapse is defined %} + // support for spike archiving + + /** + * \fn void get_history(long t1, long t2, + * std::deque::iterator* start, + * std::deque::iterator* finish) + * return the spike times (in steps) of spikes which occurred in the range + * (t1,t2]. + * XXX: two underscores to differentiate it from nest::Node::get_history() + */ + void get_history__( double t1, + double t2, + std::deque< histentry__{{neuronName}} >::iterator* start, + std::deque< histentry__{{neuronName}} >::iterator* finish ); + + /** + * Register a new incoming STDP connection. + * + * t_first_read: The newly registered synapse will read the history entries + * with t > t_first_read. + */ + void register_stdp_connection( double t_first_read, double delay ); +{%- endif %} + + // ------------------------------------------------------------------------- + // Getters/setters for state block + // ------------------------------------------------------------------------- + +{% filter indent(2, True) -%} +{%- for state in neuron.get_state_symbols() %} +{%- if not is_delta_kernel(neuron.get_kernel_by_name(state.name)) %} +{%- with variable = state %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endif %} +{%- endfor %} +{%- endfilter %} + // ------------------------------------------------------------------------- + // Getters/setters for parameters + // ------------------------------------------------------------------------- + +{% filter indent(2, True) -%} +{%- for parameter in neuron.get_parameter_symbols() %} +{%- with variable = parameter %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + // ------------------------------------------------------------------------- + // Getters/setters for internals + // ------------------------------------------------------------------------- + +{% filter indent(2, True) -%} +{%- for internal in neuron.get_internal_symbols() %} +{%- with variable = internal %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + +{%- if paired_synapse is defined %} + + /* getters/setters for variables transferred from synapse */ + +{%- for var in transferred_variables %} + double get_{{var}}( double t, const bool before_increment = true ); +{%- endfor %} +{%- endif %} + +protected: +{%- if paired_synapse is defined %} + // support for spike archiving + + /** + * record spike history + */ + void set_spiketime( nest::Time const& t_sp, double offset = 0.0 ); + + /** + * return most recent spike time in ms + */ + inline double get_spiketime_ms() const; + + /** + * clear spike history + */ + void clear_history(); +{%- endif %} + +private: + void recompute_internal_variables(bool exclude_timestep=false); + + +{%- if paired_synapse is defined %} + // support for spike archiving + + // number of incoming connections from stdp connectors. + // needed to determine, if every incoming connection has + // read the spikehistory for a given point in time + size_t n_incoming_; + + double max_delay_; + + double last_spike_; + + // spiking history needed by stdp synapses + std::deque< histentry__{{neuronName}} > history_; + + // cache for initial values +{%- for var in transferred_variables %} + double {{var}}__iv; +{%- endfor %} + + +{%- endif %} + +private: + {% if (neuron.get_multiple_receptors())|length > 1 -%} + /** + * Synapse types to connect to + * @note Excluded upper and lower bounds are defined as INF_, SUP_. + * Excluding port 0 avoids accidental connections. + **/ + enum SynapseTypes + { + INF_SPIKE_RECEPTOR = 0, +{%- for port in neuron.get_multiple_receptors() %} + {{port.get_symbol_name().upper()}} , +{%- endfor %} + SUP_SPIKE_RECEPTOR + }; +{%- endif %} + +{%- if nest_version.startswith("v2") %} + /** + * Reset state of neuron. + **/ + void init_state_(const Node& proto); +{%- endif %} + + /** + * Reset internal buffers of neuron. + **/ + void init_buffers_(); + + /** + * Initialize auxiliary quantities, leave parameters and state untouched. + **/ +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate(); +{%- else %} + void pre_run_hook(); +{%- endif %} + + /** + * Take neuron through given time interval + **/ + void update(nest::Time const &, const long, const long); + + // The next two classes need to be friends to access the State_ class/member +{%- if (has_state_vectors) %} + friend class nest::DynamicRecordablesMap< {{neuronName}} >; + friend class nest::DynamicUniversalDataLogger< {{neuronName}} >; + friend class nest::DataAccessFunctor< {{neuronName}} >; +{%- else %} + friend class nest::RecordablesMap<{{neuronName}}>; + friend class nest::UniversalDataLogger<{{neuronName}}>; +{%- endif %} + + /** + * Free parameters of the neuron. + * + {{neuron.print_parameter_comment("*")}} + * + * These are the parameters that can be set by the user through @c `node.set()`. + * They are initialized from the model prototype when the node is created. + * Parameters do not change during calls to @c update() and are not reset by + * @c ResetNetwork. + * + * @note Parameters_ need neither copy constructor nor @c operator=(), since + * all its members are copied properly by the default copy constructor + * and assignment operator. Important: + * - If Parameters_ contained @c Time members, you need to define the + * assignment operator to recalibrate all members of type @c Time . You + * may also want to define the assignment operator. + * - If Parameters_ contained members that cannot copy themselves, such + * as C-style arrays, you need to define the copy constructor and + * assignment operator to copy those members. + **/ + struct Parameters_ + { +{%- filter indent(4,True) %} +{%- for variable in neuron.get_parameter_symbols() %} +{%- include 'directives/MemberDeclaration.jinja2' %} +{%- endfor %} +{%- endfilter %} +{%- if uses_numeric_solver %} + + double __gsl_error_tol; +{%- endif %} + + /** + * Initialize parameters to their default values. + **/ + Parameters_(); + }; + + /** + * Dynamic state of the neuron. + * + {{neuron.print_state_comment('*')}} + * + * These are the state variables that are advanced in time by calls to + * @c update(). In many models, some or all of them can be set by the user + * through @c `node.set()`. The state variables are initialized from the model + * prototype when the node is created. State variables are reset by @c ResetNetwork. + * + * @note State_ need neither copy constructor nor @c operator=(), since + * all its members are copied properly by the default copy constructor + * and assignment operator. Important: + * - If State_ contained @c Time members, you need to define the + * assignment operator to recalibrate all members of type @c Time . You + * may also want to define the assignment operator. + * - If State_ contained members that cannot copy themselves, such + * as C-style arrays, you need to define the copy constructor and + * assignment operator to copy those members. + **/ + struct State_ + { +{%- if not uses_numeric_solver %} +{%- if has_state_vectors %} +{% include "directives/StateVariablesEnum.jinja2" %} +{%- endif %} +{%- filter indent(4,True) %} +{%- for variable in neuron.get_state_symbols() %} +{%- include "directives/MemberDeclaration.jinja2" %} +{%- endfor %} +{%- endfilter %} +{%- else %} +{%- if has_state_vectors %} +{%- include "directives/VectorVariablesEnum.jinja2" %} +{%- endif %} + //! Symbolic indices to the elements of the state vector y + enum StateVecElems + { +{#- N.B. numeric solver contains all state variables, including those that will be solved by analytic solver #} +{%- if uses_numeric_solver %} +{%- for variable_name in numeric_state_variables %} + {{variable_name}}, +{%- endfor %} + // moved state variables from synapse +{%- for variable_name in purely_numeric_state_variables_moved|sort %} + {{variable_name}}, +{%- endfor %} +{%- for variable_name in analytic_state_variables_moved|sort %} + {{variable_name}}, +{%- endfor %} +{%- for variable_name in non_equations_state_variables: %} + {{variable_name}}, +{%- endfor %} +{%- else %} +{#- analytic solver only #} +{%- for variable_name in analytic_state_variables: %} + {{variable_name}}, +{%- endfor %} +{%- for variable_name in non_equations_state_variables: %} + {{variable_name}}, +{%- endfor %} +{%- endif %} + STATE_VEC_SIZE + }; + + //! state vector, must be C-array for GSL solver + double ode_state[STATE_VEC_SIZE]; +{%- endif %} + + State_(); + }; + + struct DelayedVariables_ + { +{%- if has_delay_variables %} + // Declare helper variables for variables with delay +{%- for variable in neuron.get_state_symbols() %} +{%- if variable.has_delay_parameter() %} +{%- include "directives/DelayVariablesDeclaration.jinja2" %} +{%- endif %} +{%- endfor %} +{%- endif %} + }; + + /** + * Internal variables of the neuron. + * + {{neuron.print_internal_comment('*')}} + * + * These variables must be initialized by @c pre_run_hook (or calibrate in NEST 3.3 and older), which is called before + * the first call to @c update() upon each call to @c Simulate. + * @node Variables_ needs neither constructor, copy constructor or assignment operator, + * since it is initialized by @c pre_run_hook() (or calibrate() in NEST 3.3 and older). If Variables_ has members that + * cannot destroy themselves, Variables_ will need a destructor. + **/ + struct Variables_ + { +{%- for variable in neuron.get_internal_symbols() %} +{%- filter indent(4) %} +{%- include "directives/MemberDeclaration.jinja2" %} +{%- endfilter %} +{%- endfor %} + }; + + /** + * Buffers of the neuron. + * Usually buffers for incoming spikes and data logged for analog recorders. + * Buffers must be initialized by @c init_buffers_(), which is called before + * @c pre_run_hook() (or calibrate() in NEST 3.3 and older) on the first call to @c Simulate after the start of NEST, + * ResetKernel or ResetNetwork. + * @node Buffers_ needs neither constructor, copy constructor or assignment operator, + * since it is initialized by @c init_nodes_(). If Buffers_ has members that + * cannot destroy themselves, Buffers_ will need a destructor. + **/ + struct Buffers_ + { + Buffers_({{neuronName}} &); + Buffers_(const Buffers_ &, {{neuronName}} &); + + /** + * Logger for all analog data + **/ +{%- if (has_state_vectors) %} + nest::DynamicUniversalDataLogger<{{neuronName}}> logger_; +{%- else %} + nest::UniversalDataLogger<{{neuronName}}> logger_; +{%- endif %} + +{%- if ((neuron.get_multiple_receptors())|length > 1) or neuron.has_vector_port() %} + std::vector receptor_types_; +{%- endif %} + +{%- if ((neuron.get_multiple_receptors())|length > 1) %} + // ----------------------------------------------------------------------- + // Buffers and sums of incoming spikes/currents per timestep + // ----------------------------------------------------------------------- + std::vector< nest::RingBuffer > spike_inputs_; + +{%- for inputPort in neuron.get_spike_input_ports() %} + {{printer.print_buffer_array_getter(inputPort)}} + {{printer.print_buffer_declaration_value(inputPort)}}; +{%- endfor %} +{%- else %} +{%- for inputPort in neuron.get_spike_input_ports() %} + {{printer.print_buffer_getter(inputPort, true)}} + {{printer.print_buffer_declaration_header(inputPort)}} + {{printer.print_buffer_declaration(inputPort)}}; + {{printer.print_buffer_declaration_value(inputPort)}}; +{%- endfor %} +{%- endif %} + +{%- for inputPort in neuron.get_continuous_input_ports() %} + {{printer.print_buffer_declaration_header(inputPort)}} + {{printer.print_buffer_declaration(inputPort)}}; + {{printer.print_buffer_getter(inputPort, true)}} + {{printer.print_buffer_declaration_value(inputPort)}}; +{%- endfor %} +{%- if uses_numeric_solver %} + + // ----------------------------------------------------------------------- + // GSL ODE solver data structures + // ----------------------------------------------------------------------- + + gsl_odeiv_step* __s; //!< stepping function + gsl_odeiv_control* __c; //!< adaptive stepsize control function + gsl_odeiv_evolve* __e; //!< evolution function + gsl_odeiv_system __sys; //!< struct describing system + + // __integration_step should be reset with the neuron on ResetNetwork, + // but remain unchanged during calibration. Since it is initialized with + // step_, and the resolution cannot change after nodes have been created, + // it is safe to place both here. + double __step; //!< step size in ms + double __integration_step; //!< current integration time step, updated by GSL +{%- endif %} + + }; + + // ------------------------------------------------------------------------- + // Getters/setters for inline expressions + // ------------------------------------------------------------------------- +{% filter indent(2, True) -%} +{%- for sym in neuron.get_inline_expression_symbols() %} +{%- with variable = sym %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + + // ------------------------------------------------------------------------- + // Getters/setters for input buffers + // ------------------------------------------------------------------------- +{% filter indent(2, True) -%} +{%- for port in neuron.get_input_ports() %} +{{printer.print_buffer_getter(port, false)}}; +{%- endfor %} +{%- endfilter %} +{%- if neuron.get_functions()|length > 0 %} + // ------------------------------------------------------------------------- + // Function declarations + // ------------------------------------------------------------------------- + +{% filter indent(2) -%} +{%- for function in neuron.get_functions() %} +{{printer.print_function_declaration(function)}}; +{%- endfor %} +{%- endfilter %} +{%- endif %} + + // ------------------------------------------------------------------------- + // Member variables of neuron model. + // Each model neuron should have precisely the following four data members, + // which are one instance each of the parameters, state, buffers and variables + // structures. Experience indicates that the state and variables member should + // be next to each other to achieve good efficiency (caching). + // Note: Devices require one additional data member, an instance of the + // ``Device`` child class they belong to. + // ------------------------------------------------------------------------- + + + Parameters_ P_; //!< Free parameters. + State_ S_; //!< Dynamic state. + DelayedVariables_ DV_; //!< Delayed state variables. + Variables_ V_; //!< Internal Variables + Buffers_ B_; //!< Buffers. + + //! Mapping of recordables names to access functions +{%- if has_state_vectors %} + nest::DynamicRecordablesMap<{{neuronName}}> recordablesMap_; + nest::DataAccessFunctor< {{neuronName}} > get_data_access_functor( size_t elem ); + std::string get_var_name(size_t elem, std::string var_name); + void insert_recordables(size_t first=0); + +{% include "directives/DynamicStateElement.jinja2" %} + +{%- else %} + static nest::RecordablesMap<{{neuronName}}> recordablesMap_; +{%- endif %} + +{%- if uses_numeric_solver %} + friend int {{neuronName}}_dynamics( double, const double y[], double f[], void* pnode ); +{% endif %} +{%- if norm_rng %} + +{%- if nest_version.startswith("v2") %} + librandom::NormalRandomDev normal_dev_; //!< random deviate generator +{%- else %} + nest::normal_distribution normal_dev_; //!< random deviate generator +{%- endif %} +{%- endif %} +{%- if has_delay_variables %} + void update_delay_variables(); + + // Getters for the delayed variables + // These are obtained from the vector helper variables defined + // for the state variable that is used with a delay parameter +{%- for variable in neuron.get_state_symbols() %} +{%- if variable.has_delay_parameter() %} + double get_delayed_{{variable.get_symbol_name()}}() const; +{%- endif %} +{%- endfor %} +{%- endif %} + +}; /* neuron {{neuronName}} */ + +inline nest::port {{neuronName}}::send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool) +{ + // You should usually not change the code in this function. + // It confirms that the target of connection @c c accepts @c {{outputEvent}} on + // the given @c receptor_type. + {{outputEvent}} e; + e.set_sender(*this); + return target.handles_test_event(e, receptor_type); +} +{%- if has_spike_input %} + +inline nest::port {{neuronName}}::handles_test_event(nest::SpikeEvent&, nest::port receptor_type) +{ +{%- if neuron.is_multisynapse_spikes() %} + if ( receptor_type <= 0 || receptor_type > static_cast< nest::port >( get_{{neuron.get_spike_input_ports()[0].get_vector_parameter()}}()) ) + { + // TODO refactor me. The code assumes that there is only one. Check by coco. + throw nest::IncompatibleReceptorType( receptor_type, get_name(), "SpikeEvent" ); + } + return receptor_type; +{%- elif neuron.get_multiple_receptors()|length > 1 %} + assert( B_.spike_inputs_.size() == {{(neuron.get_multiple_receptors())|length}} ); + + if ( !( INF_SPIKE_RECEPTOR < receptor_type && receptor_type < SUP_SPIKE_RECEPTOR ) ) + { + throw nest::UnknownReceptorType( receptor_type, get_name() ); + return 0; + } + else + { + return receptor_type - 1; + } +{%- else %} + // You should usually not change the code in this function. + // It confirms to the connection management system that we are able + // to handle @c SpikeEvent on port 0. You need to extend the function + // if you want to differentiate between input ports. + if (receptor_type != 0) + { + throw nest::UnknownReceptorType(receptor_type, get_name()); + } + return 0; +{%- endif %} +} +{%- endif %} +{%- if has_continuous_input %} + +inline nest::port {{neuronName}}::handles_test_event(nest::CurrentEvent&, nest::port receptor_type) +{ + // You should usually not change the code in this function. + // It confirms to the connection management system that we are able + // to handle @c CurrentEvent on port 0. You need to extend the function + // if you want to differentiate between input ports. + if (receptor_type != 0) + { + throw nest::UnknownReceptorType(receptor_type, get_name()); + } + return 0; +} +{%- endif %} + +inline nest::port {{neuronName}}::handles_test_event(nest::DataLoggingRequest& dlr, nest::port receptor_type) +{ + // You should usually not change the code in this function. + // It confirms to the connection management system that we are able + // to handle @c DataLoggingRequest on port 0. + // The function also tells the built-in UniversalDataLogger that this node + // is recorded from and that it thus needs to collect data during simulation. + if (receptor_type != 0) + { + throw nest::UnknownReceptorType(receptor_type, get_name()); + } + + return B_.logger_.connect_logging_device(dlr, recordablesMap_); +} + +inline void {{neuronName}}::get_status(DictionaryDatum &__d) const +{ + // parameters +{%- for parameter in neuron.get_parameter_symbols() %} +{%- with variable = parameter %} +{%- filter indent(2) %} +{%- include "directives/WriteInDictionary.jinja2" %} +{%- endfilter %} +{%- endwith %} +{%- endfor %} + + // initial values for state variables in ODE or kernel +{%- for state in neuron.get_state_symbols() %} +{%- with variable = state %} +{%- if not is_delta_kernel(neuron.get_kernel_by_name(state.name)) %} +{%- filter indent(2) %} +{%- include "directives/WriteInDictionary.jinja2" %} +{%- endfilter %} +{%- endif -%} +{%- endwith %} +{%- endfor %} + + {{neuron_parent_class}}::get_status( __d ); + +{%- if (neuron.get_multiple_receptors())|length > 1 %} + DictionaryDatum __receptor_type = new Dictionary(); +{%- for port in neuron.get_multiple_receptors() %} + ( *__receptor_type )[ "{{port.get_symbol_name().upper()}}" ] = {{port.get_symbol_name().upper()}}; +{%- endfor %} + ( *__d )[ "receptor_types" ] = __receptor_type; +{%- endif %} + + (*__d)[nest::names::recordables] = recordablesMap_.get_list(); +{%- if uses_numeric_solver %} + def< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol); + if ( P_.__gsl_error_tol <= 0. ){ + throw nest::BadProperty( "The gsl_error_tol must be strictly positive." ); + } +{%- endif %} +} + +inline void {{neuronName}}::set_status(const DictionaryDatum &__d) +{ + // parameters +{%- for parameter in neuron.get_parameter_symbols() -%} +{%- with variable = parameter %} +{%- filter indent(2) %} +{%- include "directives/ReadFromDictionaryToTmp.jinja2" %} +{%- endfilter %} +{%- endwith %} +{%- endfor %} + + // initial values for state variables in ODE or kernel +{%- for state in neuron.get_state_symbols() %} +{%- with variable = state %} +{%- if not is_delta_kernel(neuron.get_kernel_by_name(state.name)) %} +{%- filter indent(2) %} +{%- include "directives/ReadFromDictionaryToTmp.jinja2" %} +{%- endfilter %} +{%- endif %} +{%- endwith %} +{%- endfor %} + + // We now know that (ptmp, stmp) are consistent. We do not + // write them back to (P_, S_) before we are also sure that + // the properties to be set in the parent class are internally + // consistent. + {{neuron_parent_class}}::set_status(__d); + + // if we get here, temporaries contain consistent set of properties +{%- for parameter in neuron.get_parameter_symbols() -%} +{%- with variable = parameter -%} +{%- filter indent(2) %} +{%- include "directives/AssignTmpDictionaryValue.jinja2" -%} +{%- endfilter %} +{%- endwith -%} +{%- endfor -%} + +{%- for state in neuron.get_state_symbols() -%} +{%- with variable = state %} +{%- if not is_delta_kernel(neuron.get_kernel_by_name(state.name)) %} +{%- filter indent(2) %} +{%- include "directives/AssignTmpDictionaryValue.jinja2" %} +{%- endfilter %} +{%- endif %} +{%- endwith %} +{%- endfor %} + +{%- for invariant in neuron.get_parameter_invariants() %} + if ( !({{printer.print_expression(invariant)}}) ) + { + throw nest::BadProperty("The constraint '{{idemPrinter.print_expression(invariant)}}' is violated!"); + } +{%- endfor %} + +{% if uses_numeric_solver %} + updateValue< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol); + if ( P_.__gsl_error_tol <= 0. ) + { + throw nest::BadProperty( "The gsl_error_tol must be strictly positive." ); + } +{%- endif %} + + // recompute internal variables in case they are dependent on parameters or state that might have been updated in this call to set_status() + recompute_internal_variables(); +}; + +#endif /* #ifndef {{neuronName.upper()}} */ +{# leave this comment here to ensure newline is generated at end of file -#} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 new file mode 100644 index 000000000..244625d47 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 @@ -0,0 +1,1315 @@ +{#- +SynapseHeader.h.jinja2 + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif -%} +/** + * {{synapseName}}.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + * Generated from NESTML at time: {{now}} +**/ + +#ifndef {{synapseName.upper()}}_H +#define {{synapseName.upper()}}_H + +// C++ includes: +#include + +// Includes from nestkernel: +#include "common_synapse_properties.h" +#include "connection.h" +#include "connector_model.h" +#include "event.h" +{%- if norm_rng %} + +// Includes for random number generator +{%- if nest_version.startswith("v2") %} +#include "normal_randomdev.h" +#include "uniform_randomdev.h" +{%- else %} +#include +{%- endif %} +{%- endif %} +{%- if vt_ports is defined and vt_ports|length > 0 %} +// Includes for volume transmitter +#include "volume_transmitter.h" +{%- endif %} + + +// Includes from sli: +#include "dictdatum.h" +#include "dictutils.h" + +/** @BeginDocumentation +{{ synapse.print_comment() }} +**/ + +#define POST_NEURON_TYPE {{ paired_neuron }} + +//#define DEBUG + +namespace nest +{ + +namespace {{names_namespace}} +{ +{%- if synapse.get_state_symbols()|length > 0 %} +{%- for sym in synapse.get_state_symbols() %} + const Name _{{sym.get_symbol_name()}}( "{{sym.get_symbol_name()}}" ); +{%- endfor %} +{%- endif %} +{%- if synapse.get_parameter_symbols()|length > 0 %} +{%- for sym in synapse.get_parameter_symbols() %} + const Name _{{sym.get_symbol_name()}}( "{{sym.get_symbol_name()}}" ); +{%- endfor %} +{%- endif %} +} + +class {{synapseName}}CommonSynapseProperties : public CommonSynapseProperties { +public: + + {{synapseName}}CommonSynapseProperties() + : CommonSynapseProperties() + { +{%- filter indent(width=8) %} +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if isHomogeneous %} +{%- with variable = parameter %} +{%- include "directives/CommonPropertiesDictionaryMemberInitialization.jinja2" %} +{%- endwith %} +{%- endif %} +{%- endfor %} +{%- endfilter %} + } + + /** + * Get all properties and put them into a dictionary. + */ + void get_status( DictionaryDatum& d ) const + { + CommonSynapseProperties::get_status( d ); + +{%- filter indent(width=8) %} +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if isHomogeneous %} +{%- set namespaceName = parameter.get_namespace_decorator("nest") %} +{%- if namespaceName == '' %} +{{ raise('nest::names decorator is required for parameter "%s" when used in a common properties class' % names.name(parameter)) }} +{%- endif %} +{%- with variable = parameter %} +{%- include "directives/CommonPropertiesDictionaryWriter.jinja2" %} +{%- endwith %} +{%- endif %} +{%- endfor %} +{%- endfilter %} + } + + + /** + * Set properties from the values given in dictionary. + */ + void set_status( const DictionaryDatum& d, ConnectorModel& cm ) + { + CommonSynapseProperties::set_status( d, cm ); + +{%- filter indent(width=8) %} +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if isHomogeneous %} +{%- set namespaceName = parameter.get_namespace_decorator("nest") %} +{%- if (namespaceName == '') %} + {{ raise('nest::names decorator is required for parameter "%s" when used in a common properties class' % names.name(parameter)) }} +{%- endif %} +{%- with variable = parameter %} +{%- include "directives/CommonPropertiesDictionaryReader.jinja2" %} +{%- endwith %} +{%- endif %} +{%- endfor %} +{%- endfilter %} + +{%- if vt_ports is defined and vt_ports|length > 0 %} + long vtnode_id; + if ( updateValue< long >( d, names::vt, vtnode_id ) ) + { + const thread tid = kernel().vp_manager.get_thread_id(); +{%- if nest_version.startswith("v2") %} + Node* vt = kernel().node_manager.get_node( vtnode_id, tid ); +{%- else %} + Node* vt = kernel().node_manager.get_node_or_proxy( vtnode_id, tid ); +{%- endif %} + vt_ = dynamic_cast< volume_transmitter* >( vt ); + if ( vt_ == 0 ) + { + throw BadProperty( "Neuromodulatory source must be volume transmitter" ); + } + } +{%- endif %} + } + + // N.B.: we define all parameters as public for easy reference conversion later on. + // This may or may not benefit performance (TODO: compare with inline getters/setters) + +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if (isHomogeneous) %} +{%- set parameterName = names.name(parameter) %} + {{declarations.print_variable_type(parameter)}} {{parameter.get_symbol_name()}}; +{%- endif %} +{%- endfor %} + +{%- if vt_ports is defined and vt_ports|length > 0 %} + volume_transmitter* vt_; + + inline long get_vt_node_id() const + { + if ( vt_ != 0 ) + { +{%- if nest_version.startswith("v2") %} + return vt_->get_gid(); +{%- else %} + return vt_->get_node_id(); +{%- endif %} + } + else + { + return -1; + } + } + +{%- endif %} +}; + + +template < typename targetidentifierT > +class {{synapseName}} : public Connection< targetidentifierT > +{ +{%- if vt_ports is defined and vt_ports|length > 0 %} +public: + void trigger_update_weight( thread t, + const std::vector< spikecounter >& vt_spikes, + double t_trig, + const {{synapseName}}CommonSynapseProperties& cp ); +{%- endif %} +private: + double t_lastspike_; +{%- if vt_ports is defined and vt_ports|length > 0 %} + // time of last update, which is either time of last presyn. spike or time-driven update + double t_last_update_; + + // vt_spikes_idx_ refers to the vt spike that has just been processed after trigger_update_weight + // a pseudo vt spike at t_trig is stored at index 0 and vt_spikes_idx_ = 0 + index vt_spikes_idx_; +{%- endif %} + + /** + * Dynamic state of the synapse. + * + * These are the state variables that are advanced in time by calls to + * send(). In many models, some or all of them can be set by the user + * through ``SetStatus()``. + * + * @note State_ need neither copy constructor nor @c operator=(), since + * all its members are copied properly by the default copy constructor + * and assignment operator. Important: + * - If State_ contained @c Time members, you need to define the + * assignment operator to recalibrate all members of type @c Time . You + * may also want to define the assignment operator. + * - If State_ contained members that cannot copy themselves, such + * as C-style arrays, you need to define the copy constructor and + * assignment operator to copy those members. + **/ + struct State_{ +{%- if not uses_numeric_solver %} +{%- filter indent(4,True) %} +{%- for variable in synapse.get_state_symbols() %} +{%- include "directives/MemberDeclaration.jinja2" %} +{%- endfor %} +{%- endfilter %} +{%- else %} + //! Symbolic indices to the elements of the state vector y + enum StateVecElems{ +{# N.B. numeric solver contains all state variables, including those that will be solved by analytic solver#} +{%- if uses_numeric_solver %} + // numeric solver state variables +{%- for variable_name in numeric_state_variables: %} + {{variable_name}}, +{%- endfor %} +{%- endif %} + STATE_VEC_SIZE + }; + //! state vector, must be C-array for GSL solver + double ode_state[STATE_VEC_SIZE]; + + // state variables from state block +{%- filter indent(4,True) %} +{%- for variable in synapse.get_state_symbols() %} +{%- include "directives/MemberDeclaration.jinja2" %} +{%- endfor %} +{%- endfilter %} +{%- endif %} + + State_() {}; + }; + + /** + * Free parameters of the synapse. + * + {{synapse.print_parameter_comment("*")}} + * + * These are the parameters that can be set by the user through @c SetStatus. + * Parameters do not change during calls to ``send()`` and are not reset by + * @c ResetNetwork. + * + * @note Parameters_ need neither copy constructor nor @c operator=(), since + * all its members are copied properly by the default copy constructor + * and assignment operator. Important: + * - If Parameters_ contained @c Time members, you need to define the + * assignment operator to recalibrate all members of type @c Time . You + * may also want to define the assignment operator. + * - If Parameters_ contained members that cannot copy themselves, such + * as C-style arrays, you need to define the copy constructor and + * assignment operator to copy those members. + */ + struct Parameters_{ +{%- filter indent(4,True) %} +{%- for variable in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in variable.get_decorators() %} +{%- if (not isHomogeneous) %} +{%- include 'directives/MemberDeclaration.jinja2' %} +{%- else %} + // N.B. the parameter `{{names.name(variable)}}` is defined in the common properties class +{%- endif %} +{%- endfor %} +{%- endfilter %} + +{% if uses_numeric_solver %} + double __gsl_error_tol; +{% endif %} + + /** Initialize parameters to their default values. */ + Parameters_() {}; + }; + + /** + * Internal variables of the synapse. + * + {{synapse.print_internal_comment('*')}} + * + * These variables must be initialized by recompute_internal_variables(). + **/ + struct Variables_ + { +{%- for variable in synapse.get_internal_symbols() %} +{%- filter indent(4,True) %} +{%- include "directives/MemberDeclaration.jinja2" %} +{%- endfilter %} +{%- endfor %} + }; + + Parameters_ P_; //!< Free parameters. + State_ S_; //!< Dynamic state. + Variables_ V_; //!< Internal Variables + + // ------------------------------------------------------------------------- + // Getters/setters for state block + // ------------------------------------------------------------------------- + +{% filter indent(2, True) -%} +{%- for state in synapse.get_state_symbols() %} +{%- with variable = state %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + // ------------------------------------------------------------------------- + // Getters/setters for parameters + // ------------------------------------------------------------------------- + +{% filter indent(2, True) -%} +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if (not isHomogeneous) %} +{%- with variable = parameter %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endif %} +{%- endfor %} +{%- endfilter %} + + // ------------------------------------------------------------------------- + // Getters/setters for inline expressions + // ------------------------------------------------------------------------- +{% filter indent(2, True) -%} +{%- for funcsym in synapse.get_inline_expression_symbols() %} +{%- with variable = funcsym %} +{%- include "directives/MemberVariableGetterSetter.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + + // ------------------------------------------------------------------------- + // Function declarations + // ------------------------------------------------------------------------- + +{% filter indent(2) -%} +{% for function in synapse.get_functions() %} + {{printer.print_function_declaration(function)}}; +{% endfor %} +{%- endfilter %} + + /** + * Update internal state (``S_``) of the synapse according to the dynamical equations defined in the model and the statements in the ``update`` block. + **/ + inline void + update_internal_state_(double t_start, double timestep, const {{synapseName}}CommonSynapseProperties& cp); + + void recompute_internal_variables(); + +{# + /** + * All parameters marked as homogeneous will go into a CommonPropertiesDictionary + **/ + + {% for parameter in synapse.get_parameter_symbols() %} + {%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} + {%- if (isHomogeneous) %} + // {-{ assert ( decl.get_variables()|length == 1 ) }-} + {%- set parameterName = names.name(parameter) %} + !!! homeogensou decl -->> {{parameterName}} + {%- endif %} + {%- endfor %} + + {%- set isHeterogeneous = PyNestMLLexer["DECORATOR_HETEROGENEOUS"] in parameter.get_decorators() %} + {%- if (isHeterogeneous) %} + {%- set parameterName = decl.get_variables()[0].name %} + heterogen decl -->> {{parameterName}} + {%- endif %} +#} + +public: + // this line determines which common properties to use + typedef {{synapseName}}CommonSynapseProperties CommonPropertiesType; + + typedef Connection< targetidentifierT > ConnectionBase; + + /** + * Default constructor. + * + * Sets default values for all parameters (skipping common properties). + * + * Needed by GenericConnectorModel. + */ + {{synapseName}}(); + + /** + * Copy constructor from a property object. + * + * Sets default values for all parameters (skipping common properties). + * + * Needs to be defined properly in order for GenericConnector to work. + */ + {{synapseName}}( const {{synapseName}}& rhs ); + +{%- if vt_ports is defined and vt_ports|length > 0 %} +{%- set vt_port = vt_ports[0] %} + void process_{{vt_port}}_spikes_( const std::vector< spikecounter >& vt_spikes, + double t0, + double t1, + const {{synapseName}}CommonSynapseProperties& cp ); +{%- endif %} + + // Explicitly declare all methods inherited from the dependent base + // ConnectionBase. This avoids explicit name prefixes in all places these + // functions are used. Since ConnectionBase depends on the template parameter, + // they are not automatically found in the base class. + using ConnectionBase::get_delay_steps; + using ConnectionBase::set_delay_steps; + using ConnectionBase::get_delay; + using ConnectionBase::set_delay; + using ConnectionBase::get_rport; + using ConnectionBase::get_target; + + + class ConnTestDummyNode : public ConnTestDummyNodeBase + { + public: + // Ensure proper overriding of overloaded virtual functions. + // Return values from functions are ignored. + using ConnTestDummyNodeBase::handles_test_event; + port + handles_test_event( SpikeEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} + } + port + handles_test_event( RateEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + port + handles_test_event( DataLoggingRequest&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + port + handles_test_event( CurrentEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + port + handles_test_event( ConductanceEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + port + handles_test_event( DoubleDataEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + port + handles_test_event( DSSpikeEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + port + handles_test_event( DSCurrentEvent&, rport ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + return invalid_port_; +{%- else %} + return invalid_port; +{%- endif %} } + }; + + /** + * special case for weights in NEST: only in case a NESTML state variable was decorated by @nest::weight + **/ + inline void set_weight(double w) + { +{%- for init in synapse.get_state_symbols() %} +{%- with variable = init %} +{%- if variable.get_namespace_decorator("nest")|length > 0 %} + // special case for variable marked with @nest::weight decorator +{%- set nest_namespace_name = variable.get_namespace_decorator("nest") %} +{%- if nest_namespace_name == "weight" %} + {{names.setter(variable)}}(w); + return; +{%- endif %} +{%- endif %} +{%- endwith %} +{%- endfor %} + + // no variable was decorated by @nest::weight, so no "weight" defined from the NEST perspective + assert(0); + } +{# +/* + + {{printer.print_origin(weight_parameter)}}{{names.name(weight_parameter)}} = w; // type: {{declarations.print_variable_type(weight_parameter)}} + +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set namespaceName = parameter.get_namespace_decorator('nest') %} +{%- if (namespaceName == 'weight') %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if isHomogeneous %} + throw BadProperty( + "Setting of individual weights is not possible! The common weights can " + "be changed via CopyModel()." ); +{%- else %} + {{printer.print_origin(parameter)}}{{names.name(parameter)}} = w; // type: {{declarations.print_variable_type(parameter)}} +{%- endif %} +{%- endif %} +{%- endfor %} + } +*/ +#} + +/* inline double get_weight() { +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set namespaceName = parameter.get_namespace_decorator('nest') %} +{%- if (namespaceName == 'weight') %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if isHomogeneous %} + return cp.{{printer.print_origin(parameter)}}{{names.name(parameter)}}; // type: {{declarations.print_variable_type(parameter)}} // XXX: replace with get_status or throw() +{%- else %} + return {{printer.print_origin(parameter)}}{{names.name(parameter)}}; // type: {{declarations.print_variable_type(parameter)}} +{%- endif %} +{%- endif %} +{%- endfor %} + } +*/ + void + check_connection( Node& s, + Node& t, + rport receptor_type, + const CommonPropertiesType& cp ) + { + ConnTestDummyNode dummy_target; + ConnectionBase::check_connection_( dummy_target, s, t, receptor_type ); + +{%- if paired_neuron is defined %} + try { + dynamic_cast<{{paired_neuron}}&>(t); + } + catch (std::bad_cast &exp) { + std::cout << "wrong type of neuron connected! Synapse '{{synapseName}}' will only work with neuron '{{paired_neuron}}'.\n"; + exit(1); + } +{%- endif %} +{%- if vt_ports is defined and vt_ports|length > 0 %} + + if ( cp.vt_ == 0 ) + { + throw BadProperty( "No volume transmitter has been assigned to the dopamine synapse." ); + } +{%- endif %} + + t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() ); + } + + void + send( Event& e, const thread tid, const {{synapseName}}CommonSynapseProperties& cp ) + { + const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function + + auto get_thread = [tid]() + { + return tid; + }; + + // synapse STDP depressing/facilitation dynamics + const double __t_spike = e.get_stamp().get_ms(); +#ifdef DEBUG + std::cout << "{{synapseName}}::send(): handling pre spike at t = " << __t_spike << std::endl; +#endif + +{%- if vt_ports is defined and vt_ports|length > 0 %} + // get history of volume transmitter spikes + const std::vector< spikecounter >& vt_spikes = cp.vt_->deliver_spikes(); + +{%- endif %} + // use accessor functions (inherited from Connection< >) to obtain delay and target +{%- if paired_neuron is not none and paired_neuron|length > 0 %} + {{paired_neuron}}* __target = static_cast<{{paired_neuron}}*>(get_target(tid)); + assert(__target != NULL); +{%- else %} + Node* __target = get_target( tid ); +{%- endif %} + const double __dendritic_delay = get_delay(); + const bool pre_before_post_update = {{pre_before_post_update}}; + bool pre_before_post_flag = false; + + if (t_lastspike_ < 0.) + { + // this is the first presynaptic spike to be processed + t_lastspike_ = 0.; + } + +{%- if paired_neuron is not none and paired_neuron|length > 0 %} + double timestep = 0; + + { + // get spike history in relevant range (t1, t2] from post-synaptic neuron + std::deque< histentry__{{paired_neuron}} >::iterator start; + std::deque< histentry__{{paired_neuron}} >::iterator finish; +{%- if vt_ports is defined and vt_ports|length > 0 %} + double t0 = t_last_update_; +{%- endif %} + // For a new synapse, t_lastspike_ contains the point in time of the last + // spike. So we initially read the + // history(t_last_spike - dendritic_delay, ..., T_spike-dendritic_delay] + // which increases the access counter for these entries. + // At registration, all entries' access counters of + // history[0, ..., t_last_spike - dendritic_delay] have been + // incremented by Archiving_Node::register_stdp_connection(). See bug #218 for + // details. + __target->get_history__( t_lastspike_ - __dendritic_delay, + __t_spike - __dendritic_delay, + &start, + &finish ); + // facilitation due to post-synaptic spikes since last pre-synaptic spike + while ( start != finish ) + { + {%- if vt_ports is defined and vt_ports|length > 0 %} + {%- set vt_port = vt_ports[0] %} + process_{{vt_port}}_spikes_( vt_spikes, t0, start->t_ + __dendritic_delay, cp ); + t0 = start->t_ + __dendritic_delay; + {%- endif %} + const double minus_dt = t_lastspike_ - ( start->t_ + __dendritic_delay ); + // get_history() should make sure that + // start->t_ > t_lastspike_ - dendritic_delay, i.e. minus_dt < 0 + assert( minus_dt < -kernel().connection_manager.get_stdp_eps() ); + + if (pre_before_post_update && start->t_ == __t_spike - __dendritic_delay) + { + pre_before_post_flag = true; + break; // this would in any case have been the last post spike to be processed + } + +#ifdef DEBUG + std::cout << "\tprocessing post spike at t = " << start->t_ << std::endl; +#endif + + /** + * update synapse internal state from `t_lastspike_` to `start->t_` + **/ + + update_internal_state_(t_lastspike_, (start->t_ + __dendritic_delay) - t_lastspike_, cp); + + timestep += (start->t_ + __dendritic_delay) - t_lastspike_; + + const double _tr_t = start->t_; + +{%- filter indent(6, True) %} +{%- if post_ports is defined %} +{%- for post_port in spiking_post_ports %} +/** + * NESTML generated onReceive code block for postsynaptic port "{{post_port}}" begins here! +**/ + +{%- set dynamics = synapse.get_on_receive_block(post_port) %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endif %} +{%- endfilter %} + + /** + * internal state has now been fully updated to `start->t_ + __dendritic_delay` + **/ + + t_lastspike_ = start->t_ + __dendritic_delay; + ++start; + } + } +{%- endif %} + + /** + * update synapse internal state from `t_lastspike_` to `__t_spike` + **/ +{%- if vt_ports is defined and vt_ports|length > 0 %} +{%- set vt_port = vt_ports[0] %} + process_{{vt_port}}_spikes_( vt_spikes, t_lastspike_, __t_spike, cp ); +{%- endif %} + + update_internal_state_(t_lastspike_, __t_spike - t_lastspike_, cp); + + const double _tr_t = __t_spike - __dendritic_delay; + +#ifdef DEBUG + std::cout << "\tDepressing, old w = " << S_.w << "\n"; +#endif + //std::cout << "r2 = " << get_tr_r2() << std::endl; + +{%- filter indent(4, True) %} +{%- for pre_port in pre_ports %} +/** + * NESTML generated onReceive code block for presynaptic port "{{pre_port}}" begins here! +**/ + +{%- set dynamics = synapse.get_on_receive_block(pre_port) %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + +#ifdef DEBUG + std::cout <<"\t-> new w = " << S_.w << std::endl; +#endif + + /** + * update all convolutions with pre spikes + **/ + +{# {%- for inputLine in synapse.get_spike_buffers() %} #} +{%- for spike_updates_for_port in spike_updates.values() %} +{%- for spike_update in spike_updates_for_port -%} + // XXX: TODO: increment with initial value instead of 1 + S_.{{names.name(synapse.get_state_blocks().get_scope().resolve_to_symbol(spike_update.get_variable().get_complete_name(), SymbolKind.VARIABLE))}} += 1.; +{%- endfor %} +{%- endfor %} + + /** + * in case pre and post spike time coincide and pre update takes priority + **/ + + if (pre_before_post_flag) + { +{%- filter indent(6, True) %} +{%- if post_ports is defined %} +{%- for post_port in spiking_post_ports %} +/** + * NESTML generated onReceive code block for postsynaptic port "{{post_port}}" begins here! +**/ +#ifdef DEBUG +std::cout << "\tFacilitating from c = " << S_.c << " (using trace = " << S_.pre_tr << ")"; +#endif +{%- set dynamics = synapse.get_on_receive_block(post_port) %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endif %} +{%- endfilter %} +#ifdef DEBUG + std::cout << " to " << S_.c << std::endl; +#endif + } + + /** + * synapse internal state has now been fully updated to `__t_spike` + **/ + + t_lastspike_ = __t_spike; + } + + void get_status( DictionaryDatum& d ) const; + + void set_status( const DictionaryDatum& d, ConnectorModel& cm ); + +{%- if norm_rng %} +{%- if nest_version.startswith("v2") %} + librandom::NormalRandomDev normal_dev_; //!< random deviate generator +{%- else %} + nest::normal_distribution normal_dev_; //!< random deviate generator +{%- endif %} +{%- endif %} +}; + + +{%- if vt_ports is defined and vt_ports|length > 0 %} +{%- set vt_port = vt_ports[0] %} +template < typename targetidentifierT > +void +{{synapseName}}< targetidentifierT >::process_{{vt_port}}_spikes_( const std::vector< spikecounter >& vt_spikes, + double t0, + double t1, + const {{synapseName}}CommonSynapseProperties& cp ) +{ +#ifdef DEBUG + std::cout << "\tIn process_{{vt_port}}_spikes_(): t0 = " << t0 << ", t1 = " << t1 << "\n"; +#endif + // process dopa spikes in (t0, t1] + // propagate weight from t0 to t1 + if ( ( vt_spikes.size() > vt_spikes_idx_ + 1 ) + && ( t1 - vt_spikes[ vt_spikes_idx_ + 1 ].spike_time_ > -1.0 * kernel().connection_manager.get_stdp_eps() ) ) + { + // there is at least 1 dopa spike in (t0, t1] + // propagate up to first dopa spike +#ifdef DEBUG + std::cout << "\t\tHandling (1) spike at t = " << vt_spikes[ vt_spikes_idx_ +1].spike_time_ << "\n"; +#endif + update_internal_state_(t0, vt_spikes[ vt_spikes_idx_ + 1 ].spike_time_ - t0, cp ); + ++vt_spikes_idx_; +#ifdef DEBUG +std::cout<<"\t\tIncrementing n_ from " << S_.n << " to " ; +#endif + /** + * NESTML generated onReceive code block for volume transmitter synaptic port "{{vt_port}}" begins here! + **/ + +{%- filter indent(4, True) %} +{%- set dynamics = synapse.get_on_receive_block(vt_port) %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +#ifdef DEBUG +std::cout << S_.n << "\n"; +#endif + // process remaining dopa spikes in (t0, t1] + double cd; + while ( ( vt_spikes.size() > vt_spikes_idx_ + 1 ) + && ( t1 - vt_spikes[ vt_spikes_idx_ + 1 ].spike_time_ > -1.0 * kernel().connection_manager.get_stdp_eps() ) ) + { +#ifdef DEBUG + std::cout << "\t\tHandling (2) spike at t = " << vt_spikes[ vt_spikes_idx_ ].spike_time_ << "\n"; +#endif + // propagate up to next dopa spike + update_internal_state_(vt_spikes[ vt_spikes_idx_ ].spike_time_, + vt_spikes[ vt_spikes_idx_ + 1 ].spike_time_ - vt_spikes[ vt_spikes_idx_ ].spike_time_, + cp ); + ++vt_spikes_idx_; + + /** + * NESTML generated onReceive code block for volume transmitter synaptic port "{{vt_port}}" begins here! + **/ +#ifdef DEBUG +std::cout<<"\t\tIncrementing n_ from " << S_.n << " to " ; +#endif +{%- filter indent(6, True) %} +{%- set dynamics = synapse.get_on_receive_block(vt_port) %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +#ifdef DEBUG +std::cout << S_.n << "\n"; +#endif + } +#ifdef DEBUG + std::cout << "\t\t3\n"; +#endif + + // propagate up to t1 + update_internal_state_(vt_spikes[ vt_spikes_idx_ ].spike_time_, + t1 - vt_spikes[ vt_spikes_idx_ ].spike_time_, + cp ); + } + else + { +#ifdef DEBUG + std::cout << "\t\t4: updating internal state from t0 = " << t0 << " to t1 = " << t1 << "\n"; +#endif + + // no dopamine spikes in (t0, t1] + update_internal_state_( t0, t1 - t0, cp ); + } +} +{%- endif %} + + +template < typename targetidentifierT > +void +{{synapseName}}< targetidentifierT >::get_status( DictionaryDatum& __d ) const +{ + ConnectionBase::get_status( __d ); + def< long >( __d, names::size_of, sizeof( *this ) ); + + // parameters +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if (not isHomogeneous) %} +{%- set namespaceName = parameter.get_namespace_decorator('nest') %} +{%- if namespaceName == '' %} +{%- with variable = parameter %} +{%- filter indent(2,True) %} +{%- include "directives/WriteInDictionary.jinja2" %} +{%- endfilter %} +{%- endwith %} +{%- else %} + def< {{declarations.print_variable_type(parameter)}} >( __d, names::{{namespaceName}}, {{printer.print_origin(parameter)}}{{names.name(parameter)}} ); +{%- endif %} +{%- endif %} +{%- endfor %} + + // initial values for state variables in ODE or kernel +{%- filter indent(2,True) %} +{%- for init in synapse.get_state_symbols() %} +{%- with variable = init %} +{%- if not is_delta_kernel(synapse.get_kernel_by_name(init.name)) %} +{%- include "directives/WriteInDictionary.jinja2" %} +{%- if variable.get_namespace_decorator("nest")|length > 0 %} +// special treatment for variable marked with @nest::name decorator +{%- set nest_namespace_name = variable.get_namespace_decorator("nest") %} +{%- if not variable.is_internals() %} +def<{{declarations.print_variable_type(variable)}}>(__d, names::{{nest_namespace_name}}, {{names.getter(variable)}}()); +{%- endif %} +{%- endif %} +{%- endif %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} +} + +template < typename targetidentifierT > +void +{{synapseName}}< targetidentifierT >::set_status( const DictionaryDatum& __d, + ConnectorModel& cm ) +{ + // parameters +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set namespaceName = parameter.get_namespace_decorator('nest') %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if (not isHomogeneous) %} +{%- with variable = parameter %} +{%- filter indent(2,True) %} +{%- include "directives/ReadFromDictionaryToTmp.jinja2" %} +{%- endfilter %} +{%- endwith %} +{%- endif %} +{%- endfor %} + + // initial values for state variables in ODE or kernel +{%- filter indent(2,True) %} +{%- for init in synapse.get_state_symbols() %} +{%- with variable = init %} +{%- if not is_delta_kernel(synapse.get_kernel_by_name(init.name)) %} +{%- include "directives/ReadFromDictionaryToTmp.jinja2" %} + +{%- if variable.get_namespace_decorator("nest")|length > 0 %} +// special treatment for variables marked with @nest::name decorator +{%- set nest_namespace_name = variable.get_namespace_decorator("nest") %} +{#- -------- XXX: TODO: this is almost the content of directives/ReadFromDictionaryToTmp.jinja2 verbatim, refactor this ---------- #} +{%- if not variable.is_inline_expression and not variable.is_state() %} +tmp_{{names.name(variable)}} = {{names.getter(variable)}}(); +updateValue<{{declarations.print_variable_type(variable)}}>(__d, "{{nest_namespace_name}}", tmp_{{names.name(variable)}}); +{%- elif not variable.is_inline_expression and variable.is_state() %} +tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}} = {{names.getter(variable)}}(); +updateValue<{{declarations.print_variable_type(variable)}}>(__d, "{{nest_namespace_name}}", tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}}); +{%- else %} + // ignores '{{names.name(variable)}}' {{declarations.print_variable_type(variable)}}' since it is an function and setter isn't defined +{%- endif %} +{#- -------------------------------------------------------------------------------------------------------------------------------- #} +{%- endif %} +{%- endif %} +{%- endwith %} +{%- endfor %} +{%- endfilter %} + + + // We now know that (ptmp, stmp) are consistent. We do not + // write them back to (P_, S_) before we are also sure that + // the properties to be set in the parent class are internally + // consistent. + ConnectionBase::set_status( __d, cm ); + + // if we get here, temporaries contain consistent set of properties + // set parameters +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set namespaceName = parameter.get_namespace_decorator('nest') %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if (not isHomogeneous) %} +{%- with variable = parameter %} +{%- filter indent(2,True) %} +{%- include "directives/AssignTmpDictionaryValue.jinja2" %} +{%- endfilter %} +{%- endwith %} +{%- endif %} +{%- endfor %} + + // set state +{%- for init in synapse.get_state_symbols() %} +{%- with variable = init %} +{%- if not is_delta_kernel(synapse.get_kernel_by_name(init.name)) %} +{%- filter indent(2,True) %} +{%- include "directives/AssignTmpDictionaryValue.jinja2" %} +{%- endfilter %} +{%- endif %} +{%- endwith %} +{%- endfor %} + + // check invariants +{% for invariant in synapse.get_parameter_invariants() %} + if ( !({{printer.print_expression(invariant)}}) ) { + throw nest::BadProperty("The constraint '{{idemPrinter.print_expression(invariant)}}' is violated!"); + } +{%- endfor %} +{% if uses_numeric_solver %} + + updateValue< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol); + if ( P_.__gsl_error_tol <= 0. ){ + throw nest::BadProperty( "The gsl_error_tol must be strictly positive." ); + } +{% endif %} + + // special treatment of NEST delay + set_delay({%- for parameter in synapse.get_parameter_symbols() %} +{%- set namespaceName = parameter.get_namespace_decorator("nest") %} +{%- if namespaceName == "delay" %} +{{ names.getter(parameter) }}() +{%- endif %} +{%- endfor %}); + + // recompute internal variables in case they are dependent on parameters or state that might have been updated in this call to set_status() + recompute_internal_variables(); +} + +/** + * NESTML internals block symbols initialisation +**/ +template < typename targetidentifierT > +void {{synapseName}}< targetidentifierT >::recompute_internal_variables() +{ + const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function + +{% filter indent(2) %} +{%- for variable in synapse.get_internal_symbols() %} +{%- if not variable.get_symbol_name() == "__h" %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endif %} +{%- endfor %} +{%- endfilter %} +} + +/** + * constructor +**/ +template < typename targetidentifierT > +{{synapseName}}< targetidentifierT >::{{synapseName}}() : ConnectionBase() +{ + const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function + +{%- for parameter in synapse.get_parameter_symbols() %} +{%- with variable = parameter %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in variable.get_decorators() %} +{%- if (not isHomogeneous) %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endif %} +{%- endwith %} +{%- endfor %} + + V_.__h = nest::Time::get_resolution().get_ms(); + recompute_internal_variables(); + + // initial values for state variables in ODE or kernel +{%- for init in synapse.get_state_symbols() %} +{%- with variable = init %} +{%- include "directives/MemberInitialization.jinja2" %} +{%- endwith %} +{%- endfor %} + + t_lastspike_ = 0.; +{%- if vt_ports is defined and vt_ports|length > 0 %} + t_last_update_ = 0.; +{%- endif %} +} + +/** + * copy constructor +**/ +template < typename targetidentifierT > +{{synapseName}}< targetidentifierT >::{{synapseName}}( const {{synapseName}}< targetidentifierT >& rhs ) +: ConnectionBase( rhs ) +{ +{%- for parameter in synapse.get_parameter_symbols() %} +{%- set isHomogeneous = PyNestMLLexer["DECORATOR_HOMOGENEOUS"] in parameter.get_decorators() %} +{%- if (not isHomogeneous) %} + {{printer.print_origin(parameter)}}{{names.name(parameter)}} = rhs.{{printer.print_origin(parameter)}}{{names.name(parameter)}}; +{%- endif %} +{%- endfor %} + + // state variables in ODE or kernel +{%- for init in synapse.get_state_symbols() %} +{%- with variable = init %} + {{printer.print_origin(variable)}}{{names.name(variable)}} = rhs.{{printer.print_origin(variable)}}{{names.name(variable)}}; +{%- endwith %} +{%- endfor %} + + //weight_ = get_named_parameter(names::weight); + //set_weight( *rhs.weight_ ); +{%- if vt_ports is defined and vt_ports|length > 0 %} + t_last_update_ = rhs.t_last_update_; +{%- endif %} + t_lastspike_ = rhs.t_lastspike_; + + // special treatment of NEST delay + set_delay(rhs.get_delay()); +} + +template < typename targetidentifierT > +inline void +{{synapseName}}< targetidentifierT >::update_internal_state_(double t_start, double timestep, const {{synapseName}}CommonSynapseProperties& cp) +{ + if (timestep < 1E-12) + { +#ifdef DEBUG + std::cout << "\tupdate_internal_state_() called with dt < 1E-12; skipping update\n" ; +#endif + return; + } + + const double __resolution = timestep; // do not remove, this is necessary for the resolution() function + +#ifdef DEBUG + std::cout<< "\tUpdating internal state: t_start = " << t_start << ", dt = " << timestep << "\n"; +#endif + const double old___h = V_.__h; + V_.__h = timestep; + recompute_internal_variables(); +{%- filter indent(2, True) %} +{%- with analytic_state_variables_ = analytic_state_variables %} +{%- include "directives/AnalyticIntegrationStep_begin.jinja2" %} +{%- endwith %} +{%- if uses_numeric_solver %} +{%- include "directives/GSLIntegrationStep.jinja2" %} +{%- endif %} +{%- with analytic_state_variables_ = analytic_state_variables %} +{%- include "directives/AnalyticIntegrationStep_end.jinja2" %} +{%- endwith %} +{%- endfilter %} + V_.__h = old___h; + recompute_internal_variables(); // XXX: can be skipped? + +{%- if synapse.get_update_blocks() %} +{%- filter indent(2) %} +{%- set dynamics = synapse.get_update_blocks() %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +{%- endif %} + +{%- if vt_ports is defined and vt_ports|length > 0 %} + t_last_update_ = t_start + timestep; +{%- endif %} +} + +{%- if vt_ports is defined and vt_ports|length > 0 %} +/** + * Update to end of timestep ``t_trig``, while processing vt spikes and post spikes +**/ +template < typename targetidentifierT > +inline void +{{synapseName}}< targetidentifierT >::trigger_update_weight( thread t, + const std::vector< spikecounter >& vt_spikes, + const double t_trig, + const CommonPropertiesType& cp ) +{ + // propagate all state variables in the synapse to time t_trig +#ifdef DEBUG + std::cout << "\n{{synapseName}}::trigger_update_weight(): t = " << t_trig << std::endl; +#endif + // purely dendritic delay + double dendritic_delay = get_delay(); + + // get spike history in relevant range (t_last_update, t_trig] from postsyn. neuron + std::deque< histentry__{{paired_neuron}} >::iterator start; + std::deque< histentry__{{paired_neuron}} >::iterator finish; + static_cast<{{paired_neuron}}*>(get_target(t))->get_history__( t_last_update_ - dendritic_delay, t_trig - dendritic_delay, &start, &finish ); + + // facilitation due to postsyn. spikes since last update + double t0 = t_last_update_; + // double minus_dt; + double timestep = 0; + + while ( start != finish ) + { +{%- for vt_port in vt_ports %} +{%- set vt_port = vt_ports[0] %} + process_{{vt_port}}_spikes_( vt_spikes, t0, start->t_ + dendritic_delay, cp ); +{%- endfor %} + +#ifdef DEBUG + std::cout << "\tprocessing post spike from " << t_last_update_ << " to " << start->t_ + dendritic_delay << std::endl; +#endif + + /** + * update synapse internal state from `t_last_update_` to `start->t_` + **/ + + update_internal_state_(t_last_update_, + (start->t_ + dendritic_delay) - t_last_update_, + cp); + + const double _tr_t = start->t_; +#ifdef DEBUG + std::cout << "\tFacilitating from c = " << S_.c << " (using trace = " << S_.pre_tr << ")"; +#endif +{%- filter indent(6, True) %} +{%- if post_ports is defined %} +{%- for post_port in spiking_post_ports %} + /** + * NESTML generated onReceive code block for postsynaptic port "{{post_port}}" begins here! + **/ + +{%- set dynamics = synapse.get_on_receive_block(post_port) %} +{%- with ast = dynamics.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- endif %} +{%- endfilter %} + +// #ifdef DEBUG +// std::cout << "\t--> new w = " << S_.w << std::endl; +// #endif +#ifdef DEBUG + std::cout << " to " << S_.c << std::endl; +#endif + /** + * internal state has now been fully updated to `start->t_ + dendritic_delay` + **/ + + t0 = start->t_ + dendritic_delay; + // minus_dt = t_last_update_ - t0; + t_lastspike_ = start->t_ + dendritic_delay; + ++start; + } + + /** + * update synapse internal state from `t_lastspike_` to `t_trig` + **/ + +{%- for vt_port in vt_ports %} +{%- set vt_port = vt_ports[0] %} + process_{{vt_port}}_spikes_( vt_spikes, t_lastspike_, t_trig, cp ); +{%- endfor %} + +#ifdef DEBUG + //std::cout << "{{synapseName}}::trigger_update_weight(): \tupdating from " << t_lastspike_ << " to " << t_trig + dendritic_delay << std::endl; +#endif + + /* update_internal_state_(t_lastspike_, + t_trig - t_lastspike_, + cp);*/ + + vt_spikes_idx_ = 0; + t_lastspike_ = t_trig; +} + + +{%- endif %} + +} // namespace + +#endif /* #ifndef {{synapseName.upper()}}_H */ diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/AnalyticIntegrationStep_begin.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/AnalyticIntegrationStep_begin.jinja2 new file mode 100644 index 000000000..9475e80ae --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/AnalyticIntegrationStep_begin.jinja2 @@ -0,0 +1,10 @@ +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if uses_analytic_solver %} +{%- for variable_name in analytic_state_variables_: %} +{%- set update_expr = update_expressions[variable_name] %} +double {{variable_name}}__tmp = {{printer.print_expression(update_expr)}}; +{%- endfor %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/AnalyticIntegrationStep_end.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/AnalyticIntegrationStep_end.jinja2 new file mode 100644 index 000000000..0d5d7b1aa --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/AnalyticIntegrationStep_end.jinja2 @@ -0,0 +1,11 @@ +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} +/* replace analytically solvable variables with precisely integrated values */ +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if uses_analytic_solver %} +{%- for variable_name in analytic_state_variables_: %} +{%- set variable_sym = variable_symbols[variable_name] %} +{{printer.print_origin(variable_sym)}}{{names.name(variable_sym)}} = {{variable_name}}__tmp; +{%- endfor %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/ApplySpikesFromBuffers.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/ApplySpikesFromBuffers.jinja2 new file mode 100644 index 000000000..5b5ee3f03 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/ApplySpikesFromBuffers.jinja2 @@ -0,0 +1,6 @@ +{% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- for spike_updates_for_port in spike_updates.values() %} +{%- for ast in spike_updates_for_port -%} +{%- include "directives/Assignment.jinja2" %} +{%- endfor %} +{%- endfor %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/AssignTmpDictionaryValue.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/AssignTmpDictionaryValue.jinja2 new file mode 100644 index 000000000..5ac9b03ca --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/AssignTmpDictionaryValue.jinja2 @@ -0,0 +1,16 @@ +{# + Assigns a tmp value which was read from the dictionary to the corresponding block variable. + + @param variable VariableSymbol + @result C++ Block +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if not variable.is_inline_expression %} +{%- if not variable.is_state() %} +{{names.setter(variable)}}(tmp_{{names.name(variable)}}); +{%- else %} +{{names.setter(variable)}}(tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}}); +{%- endif %} +{%- else %} +// ignores '{{names.name(variable)}}' {{declarations.print_variable_type(variable)}}' since it is an function and setter isn't defined +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/Assignment.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/Assignment.jinja2 new file mode 100644 index 000000000..d65068823 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/Assignment.jinja2 @@ -0,0 +1,26 @@ +{# + Generates C++ declaration + @grammar: Assignment = variableName:QualifiedName "=" Expr; + @param ast ASTAssignment +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- set lhs_variable = assignments.lhs_variable(ast) %} +{%- if lhs_variable is none %} +{{ raise('Symbol with name "%s" could not be resolved' % ast.lhs.get_complete_name()) }} +{%- endif %} + +{%- if assignments.is_vectorized_assignment(ast) %} +{%- if lhs_variable.has_vector_parameter() %} +{%- set lhs_vector_variable = assignments.lhs_vector_variable(ast) %} +{%- if lhs_vector_variable is none %} + {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}}[{{ast.get_variable().get_vector_parameter()}}] +{%- else %} + {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}}[{{printer.print_origin(lhs_vector_variable)}}{{names.name(lhs_vector_variable)}}] +{%- endif %} +{%- else %} + {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}} +{%- endif %} + {{assignments.print_assignments_operation(ast)}} {{printer.print_expression(ast.get_expression())}}; +{%- else %} + {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}} {{assignments.print_assignments_operation(ast)}} {{printer.print_expression(ast.get_expression())}}; +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/Block.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/Block.jinja2 new file mode 100644 index 000000000..c5a0f5268 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/Block.jinja2 @@ -0,0 +1,11 @@ +{# + Handles a complex block statement + @grammar: Block = ( Stmt | NEWLINE )*; + @param ast ASTBlock +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- for statement in ast.get_stmts() %} +{%- with stmt = statement %} +{%- include "directives/Statement.jinja2" %} +{%- endwith %} +{%- endfor %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryMemberInitialization.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryMemberInitialization.jinja2 new file mode 100644 index 000000000..314004de0 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryMemberInitialization.jinja2 @@ -0,0 +1,18 @@ +{# + In general case creates an + @param variable VariableSymbol Variable for which the initialization should be done +#} + {% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif -%} +{% if variable.has_declaring_expression() and not variable.is_kernel() %} + {%- if variable.has_vector_parameter() %} + this->{{names.name(variable)}}.resize(P_.{{variable.get_vector_parameter()}}, {{printer.print_expression(variable.get_declaring_expression())}}); // as {{variable.get_type_symbol().print_symbol()}} + {%- else %} + this->{{names.name(variable)}} = {{printer.print_expression(variable.get_declaring_expression())}}; // as {{variable.get_type_symbol().print_symbol()}} + {%- endif %} +{%- else %} + {%- if variable.has_vector_parameter() %} + this->{{names.name(variable)}}.resize(0); // as {{variable.get_type_symbol().print_symbol()}} + {%- else %} + this->{{names.name(variable)}} = 0; // as {{variable.get_type_symbol().print_symbol()}} + {%- endif -%} +{%- endif -%} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryReader.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryReader.jinja2 new file mode 100644 index 000000000..766a1c138 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryReader.jinja2 @@ -0,0 +1,9 @@ +{# + In general case creates an + @param variable VariableSymbol Variable for which the initialization should be done +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if variable.has_vector_parameter() %} +{{ raise('Vector parameters not supported in common properties dictionary.') }} +{%- endif %} +updateValue< {{declarations.print_variable_type(variable)}} >(d, names::{{namespaceName}}, this->{{names.name(variable)}} ); diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryWriter.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryWriter.jinja2 new file mode 100644 index 000000000..a6ecf6541 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/CommonPropertiesDictionaryWriter.jinja2 @@ -0,0 +1,9 @@ +{# + In general case creates an + @param variable VariableSymbol Variable for which the initialization should be done +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if variable.has_vector_parameter() %} +{{ raise('Vector parameters not supported in common properties dictionary.') }} +{%- endif %} +def< {{declarations.print_variable_type(variable)}} >(d, names::{{namespaceName}}, this->{{names.name(variable)}} ); diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/CompoundStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/CompoundStatement.jinja2 new file mode 100644 index 000000000..3705a62e1 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/CompoundStatement.jinja2 @@ -0,0 +1,18 @@ +{# + Handles the compound statement. + @grammar: Compound_Stmt = IF_Stmt | FOR_Stmt | WHILE_Stmt; +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if stmt.is_if_stmt() %} +{%- with ast = stmt.get_if_stmt() %} +{%- include "directives/IfStatement.jinja2" %} +{%- endwith %} +{%- elif stmt.is_for_stmt() %} +{%- with ast = stmt.get_for_stmt() %} +{%- include "directives/ForStatement.jinja2" %} +{%- endwith %} +{%- elif stmt.is_while_stmt() %} +{%- with ast = stmt.get_while_stmt() %} +{%- include "directives/WhileStatement.jinja2" %} +{%- endwith %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/Declaration.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/Declaration.jinja2 similarity index 73% rename from pynestml/codegeneration/resources_nest/directives/Declaration.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/directives/Declaration.jinja2 index f1d454e1c..623376993 100644 --- a/pynestml/codegeneration/resources_nest/directives/Declaration.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/Declaration.jinja2 @@ -3,19 +3,19 @@ @param ast ASTDeclaration #} {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% for variable in declarations.get_variables(ast) -%} -{%- if ast.has_size_parameter() %} +{%- for variable in declarations.get_variables(ast) %} +{%- if ast.has_size_parameter() %} {{declarations.print_variable_type(variable)}} {{variable.get_symbol_name()}}(P_.{{declarations.print_size_parameter(ast)}}); - {%- if ast.has_expression() %} +{%- if ast.has_expression() %} for (long i=0; i < get_{{declarations.print_size_parameter(ast)}}(); i++) { {{variable.get_symbol_name()}}[i] = {{printer.print_expression(ast.getExpr())}}; } - {%- endif -%} - {%- else -%} - {%- if ast.has_expression() %} +{%- endif %} +{%- else %} +{%- if ast.has_expression() %} {{declarations.print_variable_type(variable)}} {{variable.get_symbol_name()}} = {{printer.print_expression(ast.get_expression())}}; - {%- else %} +{%- else %} {{declarations.print_variable_type(variable)}} {{variable.get_symbol_name()}}; - {%- endif %} - {%- endif %} +{%- endif %} +{%- endif %} {%- endfor -%} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/DelayVariablesDeclaration.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/DelayVariablesDeclaration.jinja2 new file mode 100644 index 000000000..19e6184a4 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/DelayVariablesDeclaration.jinja2 @@ -0,0 +1,8 @@ +{# + Generates C++ declaration of vector for variables with delay + @param variable VariableSymbol + @result C++ declaration +#} + size_t delay_{{variable.get_symbol_name()}}_steps; + std::vector< double > delayed_{{variable.get_symbol_name()}}; + size_t delayed_{{variable.get_symbol_name()}}_idx; diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/DelayVariablesInitialization.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/DelayVariablesInitialization.jinja2 new file mode 100644 index 000000000..f23d1faa7 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/DelayVariablesInitialization.jinja2 @@ -0,0 +1,8 @@ +{# + Generates C++ initialization of variables related to delay variables + @param variable VariableSymbol + @result C++ declaration +#} + DV_.delayed_{{variable.get_symbol_name()}}_idx = 0; + DV_.delay_{{variable.get_symbol_name()}}_steps = nest::Time::delay_ms_to_steps( {{printer.print_delay_parameter(variable)}} ) + 1; + DV_.delayed_{{variable.get_symbol_name()}}.resize( DV_.delay_{{variable.get_symbol_name()}}_steps ); diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/DynamicStateElement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/DynamicStateElement.jinja2 new file mode 100644 index 000000000..aab2bf26b --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/DynamicStateElement.jinja2 @@ -0,0 +1,46 @@ +{# + Generates get_state_element function to get elements state variables based on how they are inserted into the DynamicRecordablesMap + @param neuron ASTNeuron: the neuron model +-#} + +inline double get_state_element(size_t elem) + { +{%- set len = recordable_state_variables | length %} +{%- for variable in recordable_state_variables %} +{%- if loop.index == 1 %} + if +{%- elif loop.index == len %} + else +{%- else %} + else if +{%- endif %} + +{%- if len == 1 or loop.index < len %} +{%- if variable.has_vector_parameter() %} +{%- set size = variable.get_vector_parameter() %} +{%- if size|int == 0 %} +{%- set size = printer.print_vector_size_parameter(variable) %} +{%- endif -%} + (elem >= State_::{{names.name(variable).upper()}} && elem < State_::{{names.name(variable).upper()}} + {{size}}) + { + return S_.{{names.name(variable)}}[ elem - State_::{{names.name(variable).upper()}} ]; + } +{%- else %} + (elem == State_::{{names.name(variable).upper()}}) + { + return S_.{{names.name(variable)}}; + } +{%- endif %} +{%- else %} +{%- if variable.has_vector_parameter() %} + { + return S_.{{names.name(variable)}}[ elem - State_::{{names.name(variable).upper()}} ]; + } +{%- else %} + { + return S_.{{names.name(variable)}}; + } +{%- endif %} +{%- endif %} +{%- endfor %} + } diff --git a/pynestml/codegeneration/resources_nest/directives/ForStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/ForStatement.jinja2 similarity index 79% rename from pynestml/codegeneration/resources_nest/directives/ForStatement.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/directives/ForStatement.jinja2 index cf42de14d..e55a5761b 100644 --- a/pynestml/codegeneration/resources_nest/directives/ForStatement.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/ForStatement.jinja2 @@ -7,8 +7,7 @@ for( {{ast.get_variable()}} = {{printer.print_expression(ast.get_start_from())} {{ast.get_variable()}} {{printer.print_comparison_operator(ast)}} {{printer.print_expression(ast.get_end_at())}}; {{ast.get_variable()}} += {{ast.get_step()}} ) { - {% with ast = ast.get_block() %} - {% include "directives/Block.jinja2" %} - {% endwith %} -} /* for end */ - +{%- with ast = ast.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/FunctionCall.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/FunctionCall.jinja2 new file mode 100644 index 000000000..ed28a047c --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/FunctionCall.jinja2 @@ -0,0 +1,19 @@ +{# + Generates C++ declaration + @param ast ASTFunctionCall +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if utils.is_integrate(ast) %} +{%- with analytic_state_variables_ = analytic_state_variables %} +{%- include "directives/AnalyticIntegrationStep_begin.jinja2" %} +{%- endwith %} +{%- if uses_numeric_solver %} +{%- include "directives/GSLIntegrationStep.jinja2" %} +{%- endif %} +{%- with analytic_state_variables_ = analytic_state_variables %} +{%- include "directives/AnalyticIntegrationStep_end.jinja2" %} +{%- endwith %} +{%- include "directives/ApplySpikesFromBuffers.jinja2" %} +{%- else %} +{{printer.print_function_call(ast)}}; +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/GSLDifferentiationFunction.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/GSLDifferentiationFunction.jinja2 new file mode 100644 index 000000000..ea429b90e --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/GSLDifferentiationFunction.jinja2 @@ -0,0 +1,41 @@ +{# + Creates GSL implementation of the differentiation step for the system of ODEs. +-#} +extern "C" inline int {{neuronName}}_dynamics(double, const double ode_state[], double f[], void* pnode) +{ + typedef {{neuronName}}::State_ State_; + // get access to node so we can almost work as in a member function + assert( pnode ); + const {{neuronName}}& node = *( reinterpret_cast< {{neuronName}}* >( pnode ) ); + + // ode_state[] here is---and must be---the state vector supplied by the integrator, + // not the state vector in the node, node.S_.ode_state[]. + +{%- for ode in neuron.get_equations_blocks().get_declarations() %} +{%- for inline_expr in utils.get_inline_expression_symbols(ode) %} +{%- if not inline_expr.is_equation() %} +{%- set declaring_expr = inline_expr.get_declaring_expression() %} + double {{names.name(inline_expr)}} = {{printerGSL.print_expression(declaring_expr, prefix="node.")}}; +{%- endif %} +{%- endfor %} +{%- endfor %} + +{%- for variable_name in numeric_state_variables %} +{%- set update_expr = numeric_update_expressions[variable_name] %} +{%- set variable_sym = variable_symbols[variable_name] %} + f[{{names.array_index(variable_sym)}}] = {{printerGSL.print_expression(update_expr, prefix="node.")}}; +{%- endfor %} +{%- if paired_synapse is defined %} +{%- for variable_name in numeric_state_variables_moved %} +{%- set update_expr = numeric_update_expressions[variable_name] %} +{%- set variable_sym = neuron.get_state_blocks().get_scope().resolve_to_symbol(variable_name, SymbolKind.VARIABLE) %} + f[{{names.array_index(variable_sym)}}] = {{printerGSL.print_expression(update_expr, prefix="node.")}}; +{%- endfor %} +{%- endif %} +{%- for variable_name in non_equations_state_variables %} +{%- set variable_sym = neuron.get_state_blocks().get_scope().resolve_to_symbol(variable_name, SymbolKind.VARIABLE) %} + f[{{names.array_index(variable_sym)}}] = 0.; +{%- endfor %} + + return GSL_SUCCESS; +} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/GSLIntegrationStep.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/GSLIntegrationStep.jinja2 new file mode 100644 index 000000000..dfd7955df --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/GSLIntegrationStep.jinja2 @@ -0,0 +1,34 @@ +{# + Generates a series of C++ statements which perform one integration step of + all odes defined the neuron. +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +double __t = 0; +// numerical integration with adaptive step size control: +// ------------------------------------------------------ +// gsl_odeiv_evolve_apply performs only a single numerical +// integration step, starting from t and bounded by step; +// the while-loop ensures integration over the whole simulation +// step (0, step] if more than one integration step is needed due +// to a small integration step size; +// note that (t+IntegrationStep > step) leads to integration over +// (t, step] and afterwards setting t to step, but it does not +// enforce setting IntegrationStep to step-t; this is of advantage +// for a consistent and efficient integration across subsequent +// simulation intervals +while ( __t < B_.__step ) +{ + const int status = gsl_odeiv_evolve_apply(B_.__e, + B_.__c, + B_.__s, + &B_.__sys, // system of ODE + &__t, // from t + B_.__step, // to t <= step + &B_.__integration_step, // integration step size + S_.ode_state); // neuronal state + + if ( status != GSL_SUCCESS ) + { + throw nest::GSLSolverFailure( get_name(), status ); + } +} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/IfStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/IfStatement.jinja2 new file mode 100644 index 000000000..23667c2c7 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/IfStatement.jinja2 @@ -0,0 +1,27 @@ +{# + Generates C++ declaration + @param ast ASTIfStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +if ({{printer.print_expression(ast.get_if_clause().get_condition())}}) +{ +{%- with ast = ast.get_if_clause().get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- for elif in ast.get_elif_clauses() %} +} +else if ({{printer.print_expression(elif.get_condition())}}) +{ +{%- with ast = elif.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- if ast.has_else_clause() %} +} +else +{ +{%- with ast = ast.get_else_clause().get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endif %} +} diff --git a/pynestml/codegeneration/resources_nest/directives/MemberDeclaration.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberDeclaration.jinja2 similarity index 74% rename from pynestml/codegeneration/resources_nest/directives/MemberDeclaration.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/directives/MemberDeclaration.jinja2 index 7de9a7f9f..8554620fc 100644 --- a/pynestml/codegeneration/resources_nest/directives/MemberDeclaration.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberDeclaration.jinja2 @@ -4,6 +4,7 @@ @result C++ declaration #} {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if variable.has_comment() %} -{{variable.print_comment("//! ")}}{% endif %} -{{declarations.print_variable_type(variable)}} {{names.name(variable)}}; \ No newline at end of file +{%- if variable.has_comment() %} +{{variable.print_comment("//! ")}} +{%- endif %} +{{declarations.print_variable_type(variable)}} {{names.name(variable)}}; diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberInitialization.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberInitialization.jinja2 new file mode 100644 index 000000000..84b5a27b4 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberInitialization.jinja2 @@ -0,0 +1,18 @@ +{# + In general case creates an + @param variable VariableSymbol Variable for which the initialization should be done +#} + {% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif -%} +{% if variable.has_declaring_expression() and not variable.is_kernel() %} + {%- if variable.has_vector_parameter() %} +{{printer.print_vector_declaration(variable)}} + {%- else %} + {{printer.print_origin(variable)}}{{names.name(variable)}} = {{printer.print_expression(variable.get_declaring_expression())}}; // as {{variable.get_type_symbol().print_symbol()}} + {%- endif %} +{%- else %} + {%- if variable.has_vector_parameter() %} + {{printer.print_origin(variable)}}{{names.name(variable)}}.resize(0); // as {{variable.get_type_symbol().print_symbol()}} + {%- else %} + {{printer.print_origin(variable)}}{{names.name(variable)}} = 0; // as {{variable.get_type_symbol().print_symbol()}} + {%- endif -%} +{%- endif -%} \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberVariableGetterSetter.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberVariableGetterSetter.jinja2 new file mode 100644 index 000000000..0f6cb444c --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/MemberVariableGetterSetter.jinja2 @@ -0,0 +1,17 @@ +{%- if variable.is_inline_expression and not utils.contains_convolve_call(variable) %} +inline {{declarations.print_variable_type(variable)}} {{names.getter(variable)}}() const +{ + return {{printer.print_expression(variable.get_declaring_expression())}}; +} +{% else -%} +inline {{declarations.print_variable_type(variable)}} {{names.getter(variable)}}() const +{ + return {{printer.print_origin(variable)}}{{names.name(variable)}}; +} + +inline void {{names.setter(variable)}}(const {{declarations.print_variable_type(variable)}} __v) +{ + {{printer.print_origin(variable)}}{{names.name(variable)}} = __v; +} + +{% endif -%} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/ReadFromDictionaryToTmp.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/ReadFromDictionaryToTmp.jinja2 new file mode 100644 index 000000000..d7743cb1b --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/ReadFromDictionaryToTmp.jinja2 @@ -0,0 +1,50 @@ +{# + Generates a code snippet that retrieves a data from dictionary and sets it the the model variable. + @param variable VariableSymbol +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} + +{%- if not variable.is_inline_expression %} +{%- if not variable.is_state() %} +{{declarations.print_variable_type(variable)}} tmp_{{names.name(variable)}} = {{names.getter(variable)}}(); +updateValue<{{declarations.print_variable_type(variable)}}>(__d, nest::{{names_namespace}}::_{{names.name(variable)}}, tmp_{{names.name(variable)}}); + +{%- if vector_symbols|length > 0 %} +// Resize vectors +if (tmp_{{names.name(variable)}} != {{names.getter(variable)}}()) +{ +{%- for vector_var in vector_symbols %} +{%- if vector_var.get_vector_parameter() == variable.get_symbol_name() %} + {{declarations.print_variable_type(vector_var)}} _tmp_{{names.name(vector_var)}} = {{names.getter(vector_var)}}(); + _tmp_{{names.name(vector_var)}}.resize(tmp_{{names.name(variable)}}, 0.); + set_{{names.name(vector_var)}}(_tmp_{{names.name(vector_var)}}); +{%- endif %} +{%- endfor %} +} +{%- endif %} + +{%- else %} +{{declarations.print_variable_type(variable)}} tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}} = {{names.getter(variable)}}(); +updateValue<{{declarations.print_variable_type(variable)}}>(__d, nest::{{names_namespace}}::_{{variable.get_symbol_name()}}, tmp_{{names.convert_to_cpp_name(variable.get_symbol_name())}}); +{%- endif %} + +{%- if variable.has_vector_parameter() %} + {# +Typecast the vector parameter to an int. If the typecast fails with a return value of 0, the vector parameter is a +variable + #} +{%- set vector_size = variable.get_vector_parameter() | int %} +{%- if not vector_size %} +{%- set vector_size = "tmp_" + variable.get_vector_parameter() %} +{%- endif %} +// Check if the new vector size matches its original size +if ( tmp_{{names.name(variable)}}.size() != {{vector_size}} ) +{ + std::stringstream msg; + msg << "The vector \"{{names.name(variable)}}\" does not match its size: " << {{vector_size}}; + throw nest::BadProperty(msg.str()); +} +{%- endif %} +{%- else %} + // ignores '{{names.name(variable)}}' {{declarations.print_variable_type(variable)}}' since it is an function and setter isn't defined +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/ReturnStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/ReturnStatement.jinja2 similarity index 83% rename from pynestml/codegeneration/resources_nest/directives/ReturnStatement.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/directives/ReturnStatement.jinja2 index b0b0e5363..fc533a422 100644 --- a/pynestml/codegeneration/resources_nest/directives/ReturnStatement.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/ReturnStatement.jinja2 @@ -3,8 +3,8 @@ @param: ast A single ast-return stmt object. ASTReturnStmt #} {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if ast.has_expression() %} +{%- if ast.has_expression() %} return {{printer.print_expression(ast.get_expression())}}; -{% else %} +{%- else %} return; -{% endif %} \ No newline at end of file +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/SmallStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/SmallStatement.jinja2 new file mode 100644 index 000000000..f4eac1694 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/SmallStatement.jinja2 @@ -0,0 +1,22 @@ +{# + Generates a single small statement into equivalent C++ syntax. + @param stmt ASTSmallStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if stmt.is_assignment() %} +{%- with ast = stmt.get_assignment() %} +{%- include "directives/Assignment.jinja2" %} +{%- endwith %} +{%- elif stmt.is_function_call() %} +{%- with ast = stmt.get_function_call() %} +{%- include "directives/FunctionCall.jinja2" %} +{%- endwith %} +{%- elif stmt.is_declaration() %} +{%- with ast = stmt.get_declaration() %} +{%- include "directives/Declaration.jinja2" %} +{%- endwith %} +{%- elif stmt.is_return_stmt() %} +{%- with ast = stmt.get_return_stmt() %} +{%- include "directives/ReturnStatement.jinja2" %} +{%- endwith %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/StateVariablesEnum.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/StateVariablesEnum.jinja2 new file mode 100644 index 000000000..e90fd8e9b --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/StateVariablesEnum.jinja2 @@ -0,0 +1,20 @@ +{# + Generates an Enum with state variables that are recordable when the neuron model uses vectors + @param neuron ASTNeuron: the neuron model +-#} + +enum StateVecVars { +{%- set ns = namespace(count=0) %} +{%- for variable in neuron.get_state_symbols() %} + {% set varDomain = declarations.get_domain_from_type(variable.get_type_symbol()) -%} + {% if varDomain == "double" and variable.is_recordable -%} + {{names.name(variable).upper()}} = {{ns.count}}, + {%- if variable.has_vector_parameter() -%} + {%- set size = utils.get_numeric_vector_size(variable) -%} + {%- set ns.count = ns.count + size -%} + {%- else -%} + {%- set ns.count = ns.count + 1 -%} + {%- endif -%} + {%- endif -%} +{%- endfor %} +}; diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/Statement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/Statement.jinja2 new file mode 100644 index 000000000..4a1d3b13c --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/Statement.jinja2 @@ -0,0 +1,16 @@ +{# + Generates a single statement, either a simple or compound, to equivalent C++ syntax. + @param ast ASTSmallStmt or ASTCompoundStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if stmt.has_comment() %} +{{stmt.print_comment('//')}}{%- endif %} +{%- if stmt.is_small_stmt() %} +{%- with stmt = stmt.small_stmt %} +{%- include "directives/SmallStatement.jinja2" %} +{%- endwith %} +{%- elif stmt.is_compound_stmt() %} +{%- with stmt = stmt.compound_stmt %} +{%- include "directives/CompoundStatement.jinja2" %} +{%- endwith %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/UpdateDelayVariables.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/UpdateDelayVariables.jinja2 new file mode 100644 index 000000000..a5f3ed941 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/UpdateDelayVariables.jinja2 @@ -0,0 +1,6 @@ +{# + Generates C++ statements that update the delay variables + @param variable VariableSymbol +#} + DV_.delayed_{{variable.get_symbol_name()}} [DV_.delayed_{{variable.get_symbol_name()}}_idx] = {{printer.print_origin(variable)}}{{names.name(variable)}}; + DV_.delayed_{{variable.get_symbol_name()}}_idx = (DV_.delayed_{{variable.get_symbol_name()}}_idx + 1) % DV_.delay_{{variable.get_symbol_name()}}_steps; diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives/WhileStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/WhileStatement.jinja2 new file mode 100644 index 000000000..9414d9e1b --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/WhileStatement.jinja2 @@ -0,0 +1,11 @@ +{# + Generates C++ declaration + @param ast ASTWhileStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +while ( {{printer.print_expression(ast.get_condition())}}) +{ +{%- with ast = ast.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +} diff --git a/pynestml/codegeneration/resources_nest/directives/WriteInDictionary.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives/WriteInDictionary.jinja2 similarity index 52% rename from pynestml/codegeneration/resources_nest/directives/WriteInDictionary.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/directives/WriteInDictionary.jinja2 index bc19a3c18..191143cc1 100644 --- a/pynestml/codegeneration/resources_nest/directives/WriteInDictionary.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives/WriteInDictionary.jinja2 @@ -3,6 +3,6 @@ @param variable VariableSymbol #} {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% if not variable.is_internals() -%} - def<{{declarations.print_variable_type(variable)}}>(__d, "{{variable.get_symbol_name()}}", {{names.getter(variable)}}()); -{%- endif -%} \ No newline at end of file +{%- if not variable.is_internals() %} +def<{{declarations.print_variable_type(variable)}}>(__d, nest::{{names_namespace}}::_{{variable.get_symbol_name()}}, {{names.getter(variable)}}()); +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/__init__.py b/pynestml/codegeneration/resources_nest/point_neuron/directives/__init__.py similarity index 100% rename from pynestml/codegeneration/resources_nest/directives/__init__.py rename to pynestml/codegeneration/resources_nest/point_neuron/directives/__init__.py diff --git a/pynestml/codegeneration/resources_nest/ModuleClass.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/setup/@MODULE_NAME@.cpp.jinja2 similarity index 93% rename from pynestml/codegeneration/resources_nest/ModuleClass.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/setup/@MODULE_NAME@.cpp.jinja2 index 6d469b235..954c4ab21 100644 --- a/pynestml/codegeneration/resources_nest/ModuleClass.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/setup/@MODULE_NAME@.cpp.jinja2 @@ -1,5 +1,5 @@ {#/* -* ModuleClass.jinja2 +* @MODULE_NAME@.cpp.jinja2 * * This file is part of NEST. * @@ -67,6 +67,9 @@ {% for neuron in neurons %} #include "{{neuron.get_name()}}.h" {% endfor %} +{% for synapse in synapses %} +#include "{{synapse.get_name()}}.h" +{% endfor %} // -- Interface to dynamic module loader --------------------------------------- /* @@ -115,13 +118,6 @@ const std::string return std::string("{{moduleName}}"); // Return name of the module } -const std::string -{{moduleName}}::commandstring( void ) const -{ - // Instruct the interpreter to load {{moduleName}}-init.sli - return std::string( "({{moduleName}}-init) run" ); -} - //------------------------------------------------------------------------------------- void {{moduleName}}::init( SLIInterpreter* i ) @@ -129,4 +125,9 @@ void {% for neuron in neurons %} nest::kernel().model_manager.register_node_model<{{neuron.get_name()}}>("{{neuron.get_name()}}"); {% endfor %} -} // {{moduleName}}::init() \ No newline at end of file + + {% for synapse in synapses %} + nest::register_connection_model< nest::{{synapse.get_name()}} >( "{{synapse.get_name()}}" ); + {% endfor %} + +} // {{moduleName}}::init() diff --git a/pynestml/codegeneration/resources_nest/point_neuron/setup/@MODULE_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/setup/@MODULE_NAME@.h.jinja2 new file mode 100644 index 000000000..1cd9659d4 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/setup/@MODULE_NAME@.h.jinja2 @@ -0,0 +1,92 @@ +{# + * @MODULE_NAME@.h.jinja2 + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +/*{% set upperModuleName = moduleName.upper() %} + * {{moduleName}}.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + * {{now}} + */ + +#ifndef {{upperModuleName}}_H +#define {{upperModuleName}}_H + +#include "slimodule.h" +#include "slifunction.h" + +#include "nest.h" +#include "nest_impl.h" + + +/** +* Class defining your model. +* @note For each model, you must define one such class, with a unique name. +*/ +class {{moduleName}} : public SLIModule +{ +public: + // Interface functions ------------------------------------------ + + /** + * @note The constructor registers the module with the dynamic loader. + * Initialization proper is performed by the init() method. + */ + {{moduleName}}(); + + /** + * @note The destructor does not do much in modules. + */ + ~{{moduleName}}(); + + /** + * Initialize module by registering models with the network. + * @param SLIInterpreter* SLI interpreter + */ + void init( SLIInterpreter* ); + + /** + * Return the name of your model. + */ + const std::string name( void ) const; + +public: + // Classes implementing your functions ----------------------------- + +}; + +#endif diff --git a/pynestml/codegeneration/resources_nest/point_neuron/setup/CMakeLists.txt.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/setup/CMakeLists.txt.jinja2 new file mode 100644 index 000000000..019a833e4 --- /dev/null +++ b/pynestml/codegeneration/resources_nest/point_neuron/setup/CMakeLists.txt.jinja2 @@ -0,0 +1,293 @@ +# +# CMakeLists.txt.jinja2 +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# +# {{moduleName}}/CMakeLists.txt +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# This CMakeLists.txt is configured to build your external module for NEST. For +# illustrative reasons this module is called 'my' (change SHORT_NAME to your +# preferred module name). NEST requires you to extend the 'SLIModule' (see +# mymodule.h and mymodule.cpp as an example) and provide a module header +# (see MODULE_HEADER). The subsequent instructions +# +# The configuration requires a compiled and installed NEST; if `nest-config` is +# not in the PATH, please specify the absolute path with `-Dwith-nest=...`. +# +# For more informations on how to extend and use your module see: +# https://nest.github.io/nest-simulator/extension_modules + +# 1) Name your module here, i.e. add later with -Dexternal-modules=${moduleName}: +set( SHORT_NAME {{moduleName}} ) + +# the complete module name is here: +set( MODULE_NAME ${SHORT_NAME} ) + +# 2) Add all your sources here +set( MODULE_SOURCES + {{moduleName}}.h {{moduleName}}.cpp + {% for neuron in neurons %} + {{neuron.get_name()}}.cpp {{neuron.get_name()}}.h + {% endfor %} + ) + +# 3) We require a header name like this: +set( MODULE_HEADER ${MODULE_NAME}.h ) +# containing the class description of the class extending the SLIModule + +# 4) Specify your module version +set( MODULE_VERSION_MAJOR 1 ) +set( MODULE_VERSION_MINOR 0 ) +set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}" ) + +# Leave the call to "project(...)" for after the compiler is determined. + +# Set the `nest-config` executable to use during configuration. +set( with-nest OFF CACHE STRING "Specify the `nest-config` executable." ) + +# If it is not set, look for a `nest-config` in the PATH. +if ( NOT with-nest ) + # try find the program ourselves + find_program( NEST_CONFIG + NAMES nest-config + ) + if ( NEST_CONFIG STREQUAL "NEST_CONFIG-NOTFOUND" ) + message( FATAL_ERROR "Cannot find the program `nest-config`. Specify via -Dwith-nest=... ." ) + endif () +else () + set( NEST_CONFIG ${with-nest} ) +endif () + +# Use `nest-config` to get the compile and installation options used with the +# NEST installation. + +# Get the compiler that was used for NEST. +execute_process( + COMMAND ${NEST_CONFIG} --compiler + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_COMPILER + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# One check on first execution, if `nest-config` is working. +if ( NOT RES_VAR EQUAL 0 ) + message( FATAL_ERROR "Cannot run `${NEST_CONFIG}`. Please specify correct `nest-config` via -Dwith-nest=... " ) +endif () + +# Setting the compiler has to happen before the call to "project(...)" function. +set( CMAKE_CXX_COMPILER "${NEST_COMPILER}" ) + +project( ${MODULE_NAME} CXX ) + +# Get the install prefix. +execute_process( + COMMAND ${NEST_CONFIG} --prefix + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_PREFIX + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Get the CXXFLAGS. +execute_process( + COMMAND ${NEST_CONFIG} --cflags + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_CXXFLAGS + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Get the Includes. +execute_process( + COMMAND ${NEST_CONFIG} --includes + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_INCLUDES + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if ( NEST_INCLUDES ) + # make a cmake list + string( REPLACE " " ";" NEST_INCLUDES_LIST "${NEST_INCLUDES}" ) + foreach ( inc_complete ${NEST_INCLUDES_LIST} ) + # if it is actually a -Iincludedir + if ( "${inc_complete}" MATCHES "^-I.*" ) + # get the directory + string( REGEX REPLACE "^-I(.*)" "\\1" inc "${inc_complete}" ) + # and check whether it is a directory + if ( IS_DIRECTORY "${inc}" ) + include_directories( "${inc}" ) + endif () + endif () + endforeach () +endif () + +# Get, if NEST is build as a (mostly) static application. If yes, also only build +# static library. +execute_process( + COMMAND ${NEST_CONFIG} --static-libraries + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_STATIC_LIB + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if ( NEST_STATIC_LIB ) + set( BUILD_SHARED_LIBS OFF ) +else () + set( BUILD_SHARED_LIBS ON ) +endif () + +# Get all linked libraries. +execute_process( + COMMAND ${NEST_CONFIG} --libs + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_LIBS + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# on OS X +set( CMAKE_MACOSX_RPATH ON ) + + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + # Use the `NEST_PREFIX` as `CMAKE_INSTALL_PREFIX`. + set( CMAKE_INSTALL_PREFIX ${NEST_PREFIX} CACHE STRING "Install path prefix, prepended onto install directories." FORCE ) + # Retrieve libs folder in nest + execute_process( + COMMAND ${NEST_CONFIG} --libdir + RESULT_VARIABLE RES_VAR + OUTPUT_VARIABLE NEST_LIBDIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + # Append lib/nest to the install_dir + set( CMAKE_INSTALL_LIBDIR "${NEST_LIBDIR}/nest" CACHE STRING "object code libraries (lib/nest or lib64/nest or lib//nest on Debian)" FORCE ) +else() + # Check If CMAKE_INSTALL_PREFIX is not empty string + if("${CMAKE_INSTALL_PREFIX}" STREQUAL "") + message(FATAL_ERROR "CMAKE_INSTALL_PREFIX cannot be an empty string") + endif() + # Set lib folder to the given install_dir + set( CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX} CACHE STRING "object code libraries (lib/nest or lib64/nest or lib//nest on Debian)" FORCE ) +endif() + + +include( GNUInstallDirs ) + +# CPack stuff. Required for target `dist`. +set( CPACK_GENERATOR TGZ ) +set( CPACK_SOURCE_GENERATOR TGZ ) + +set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "NEST Module ${MODULE_NAME}" ) +set( CPACK_PACKAGE_VENDOR "NEST Initiative (http://www.nest-initiative.org/)" ) + +set( CPACK_PACKAGE_VERSION_MAJOR ${MODULE_VERSION_MAJOR} ) +set( CPACK_PACKAGE_VERSION_MINOR ${MODULE_VERSION_MINOR} ) +set( CPACK_PACKAGE_VERSION ${MODULE_VERSION} ) + +set( CPACK_SOURCE_IGNORE_FILES + "\\\\.gitignore" + "\\\\.git/" + "\\\\.travis\\\\.yml" + + # if we have in source builds + "/build/" + "/_CPack_Packages/" + "CMakeFiles/" + "cmake_install\\\\.cmake" + "Makefile.*" + "CMakeCache\\\\.txt" + "CPackConfig\\\\.cmake" + "CPackSourceConfig\\\\.cmake" + ) +set( CPACK_SOURCE_PACKAGE_FILE_NAME ${MODULE_NAME} ) + +set( CPACK_PACKAGE_INSTALL_DIRECTORY "${MODULE_NAME} ${MODULE_VERSION}" ) +include( CPack ) + +# add make dist target +add_custom_target( dist + COMMAND ${CMAKE_MAKE_PROGRAM} package_source + # not sure about this... seems, that it will be removed before dist... + # DEPENDS doc + COMMENT "Creating a source distribution from ${MODULE_NAME}..." + ) + + +if ( BUILD_SHARED_LIBS ) + # When building shared libraries, also create a module for loading at runtime + # with the `Install` command. + add_library( ${MODULE_NAME}_module MODULE ${MODULE_SOURCES} ) + set_target_properties( ${MODULE_NAME}_module + PROPERTIES + COMPILE_FLAGS "${NEST_CXXFLAGS} -DLTX_MODULE" + LINK_FLAGS "${NEST_LIBS}" + PREFIX "" + OUTPUT_NAME ${MODULE_NAME} ) + install( TARGETS ${MODULE_NAME}_module + DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif () + +# Build dynamic/static library for standard linking from NEST. +add_library( ${MODULE_NAME}_lib ${MODULE_SOURCES} ) +if ( BUILD_SHARED_LIBS ) + # Dynamic libraries are initiated by a `global` variable of the `SLIModule`, + # which is included, when the flag `LINKED_MODULE` is set. + target_compile_definitions( ${MODULE_NAME}_lib PRIVATE -DLINKED_MODULE ) +endif () +set_target_properties( ${MODULE_NAME}_lib + PROPERTIES + COMPILE_FLAGS "${NEST_CXXFLAGS}" + LINK_FLAGS "${NEST_LIBS}" + OUTPUT_NAME ${MODULE_NAME} ) + +message( "" ) +message( "-------------------------------------------------------" ) +message( "${MODULE_NAME} Configuration Summary" ) +message( "-------------------------------------------------------" ) +message( "" ) +message( "C++ compiler : ${CMAKE_CXX_COMPILER}" ) +message( "Build static libs : ${NEST_STATIC_LIB}" ) +message( "C++ compiler flags : ${CMAKE_CXX_FLAGS}" ) +message( "NEST compiler flags : ${NEST_CXXFLAGS}" ) +message( "NEST include dirs : ${NEST_INCLUDES}" ) +message( "NEST libraries flags : ${NEST_LIBS}" ) +message( "" ) +message( "-------------------------------------------------------" ) +message( "" ) +message( "You can now build and install '${MODULE_NAME}' using" ) +message( " make" ) +message( " make install" ) +message( "" ) +message( "The library file lib${MODULE_NAME}.so will be installed to" ) +message( " ${CMAKE_INSTALL_FULL_LIBDIR}" ) +message( "The module can be loaded into NEST using" ) +message( " (${MODULE_NAME}) Install (in SLI)" ) +message( " nest.Install(${MODULE_NAME}) (in PyNEST)" ) +message( "" ) diff --git a/pynestml/codegeneration/resources_nest/setup/__init__.py b/pynestml/codegeneration/resources_nest/point_neuron/setup/__init__.py similarity index 100% rename from pynestml/codegeneration/resources_nest/setup/__init__.py rename to pynestml/codegeneration/resources_nest/point_neuron/setup/__init__.py diff --git a/pynestml/codegeneration/resources_nest/setup/SLI_Init.jinja2 b/pynestml/codegeneration/resources_nest/setup/SLI_Init.jinja2 deleted file mode 100644 index 94065cdfb..000000000 --- a/pynestml/codegeneration/resources_nest/setup/SLI_Init.jinja2 +++ /dev/null @@ -1,28 +0,0 @@ -/* -* {{moduleName}}-init.sli -* -* This file is part of NEST. -* -* Copyright (C) 2004 The NEST Initiative -* -* NEST is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* NEST is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with NEST. If not, see . -* -*/ - -/* -* Initialization file for {{moduleName}}. -* Run automatically when {{moduleName}} is loaded. -*/ - -M_DEBUG ({{moduleName}}.sli) (Initializing SLI support for {{moduleName}}.) message \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/@NEURON_NAME@.cpp.jinja2 new file mode 100644 index 000000000..d6e4dd73f --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/@NEURON_NAME@.cpp.jinja2 @@ -0,0 +1,357 @@ +/* + * cm_default.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ +#include "{{neuronSpecificFileNamesCmSyns["main"]}}.h" + + +namespace nest +{ + +/* + * For some reason this code block is needed. However, I have found no + * difference in calling init_recordable_pointers() from the pre_run_hook() or calibrate() function, + * except that an unused-variable warning is generated in the code-checks + */ +template <> +void +DynamicRecordablesMap< {{neuronSpecificFileNamesCmSyns["main"]}} >::create( {{neuronSpecificFileNamesCmSyns["main"]}}& host ) +{ + host.init_recordables_pointers_(); +} + +/* ---------------------------------------------------------------- + * Default and copy constructor for node + * ---------------------------------------------------------------- */ + +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::{{neuronSpecificFileNamesCmSyns["main"]}}() + : ArchivingNode() + , c_tree_() + , syn_buffers_( 0 ) + , logger_( *this ) + , V_th_( -55.0 ) +{ + recordablesMap_.create( *this ); + recordables_values.resize( 0 ); +} + +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::{{neuronSpecificFileNamesCmSyns["main"]}}( const {{neuronSpecificFileNamesCmSyns["main"]}}& n ) + : ArchivingNode( n ) + , c_tree_( n.c_tree_ ) + , syn_buffers_( n.syn_buffers_ ) + , logger_( *this ) + , V_th_( n.V_th_ ) +{ + recordables_values.resize( 0 ); +} + +/* ---------------------------------------------------------------- + * Node initialization functions + * ---------------------------------------------------------------- + */ +void +{{neuronSpecificFileNamesCmSyns["main"]}}::get_status( DictionaryDatum& statusdict ) const +{ + def< double >( statusdict, names::V_th, V_th_ ); + ArchivingNode::get_status( statusdict ); + + // add all recordables to the status dictionary + ( *statusdict )[ names::recordables ] = recordablesMap_.get_list(); + + // We add a list of dicts with compartment information and + // a list of dicts with receptor information to the status dictionary + ArrayDatum compartment_ad; + ArrayDatum receptor_ad; + for ( long comp_idx_ = 0; comp_idx_ != c_tree_.get_size(); comp_idx_++ ) + { + DictionaryDatum dd = DictionaryDatum( new Dictionary ); + Compartment{{cm_unique_suffix}}* compartment = c_tree_.get_compartment( comp_idx_ ); + + // add compartment info + def< long >( dd, names::comp_idx, comp_idx_ ); + def< long >( dd, names::parent_idx, compartment->p_index ); + compartment_ad.push_back( dd ); + + // add receptor info + compartment->compartment_currents.add_receptor_info( receptor_ad, compartment->comp_index ); + } + // add compartment info and receptor info to the status dictionary + def< ArrayDatum >( statusdict, names::compartments, compartment_ad ); + def< ArrayDatum >( statusdict, names::receptors, receptor_ad ); +} + +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::set_status( const DictionaryDatum& statusdict ) +{ + updateValue< double >( statusdict, names::V_th, V_th_ ); + ArchivingNode::set_status( statusdict ); + + /** + * Add a compartment (or compartments) to the tree, so that the new compartment + * has the compartment specified by "parent_idx" as parent. The parent + * has to be in the tree, otherwise an error will be raised. We add either a + * single compartment or multiple compartments, depending on wether the + * entry was a list of dicts or a single dict + */ + if ( statusdict->known( names::compartments ) ) + { + /** + * Until an operator to explicititly append compartments is added to the + * API, we disable this functionality + */ + if ( c_tree_.get_size() > 0 ) + { + throw BadProperty( "\'compartments\' is already defined for this model" ); + } + + Datum* dat = ( *statusdict )[ names::compartments ].datum(); + ArrayDatum* ad = dynamic_cast< ArrayDatum* >( dat ); + DictionaryDatum* dd = dynamic_cast< DictionaryDatum* >( dat ); + + if ( ad != nullptr ) + { + // A list of compartments is provided, we add them all to the tree + for ( Token* tt = ( *ad ).begin(); tt != ( *ad ).end(); ++tt ) + { + // cast the Datum pointer stored within token dynamically to a + // DictionaryDatum pointer + add_compartment_( *dynamic_cast< DictionaryDatum* >( tt->datum() ) ); + } + } + else if ( dd != nullptr ) + { + // A single compartment is provided, we add add it to the tree + add_compartment_( *dd ); + } + else + { + throw BadProperty( + "\'compartments\' entry could not be identified, provide " + "list of parameter dicts for multiple compartments" ); + } + } + + /** + * Add a receptor (or receptors) to the tree, so that the new receptor + * targets the compartment specified by "comp_idx". The compartment + * has to be in the tree, otherwise an error will be raised. We add either a + * single receptor or multiple receptors, depending on wether the + * entry was a list of dicts or a single dict + */ + if ( statusdict->known( names::receptors ) ) + { + /** + * Until an operator to explicititly append receptors is added to the + * API, we disable this functionality + */ + if ( long( syn_buffers_.size() ) > 0 ) + { + throw BadProperty( "\'receptors\' is already defined for this model" ); + } + + Datum* dat = ( *statusdict )[ names::receptors ].datum(); + ArrayDatum* ad = dynamic_cast< ArrayDatum* >( dat ); + DictionaryDatum* dd = dynamic_cast< DictionaryDatum* >( dat ); + + if ( ad != nullptr ) + { + for ( Token* tt = ( *ad ).begin(); tt != ( *ad ).end(); ++tt ) + { + // cast the Datum pointer stored within token dynamically to a + // DictionaryDatum pointer + add_receptor_( *dynamic_cast< DictionaryDatum* >( tt->datum() ) ); + } + } + else if ( dd != nullptr ) + { + add_receptor_( *dd ); + } + else + { + throw BadProperty( + "\'receptors\' entry could not be identified, provide " + "list of parameter dicts for multiple receptors" ); + } + } + /** + * we need to initialize the recordables pointers to guarantee that the + * recordables of the new compartments and/or receptors will be in the + * recordables map + */ + init_recordables_pointers_(); +} +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::add_compartment_( DictionaryDatum& dd ) +{ + if ( dd->known( names::params ) ) + { + c_tree_.add_compartment( + getValue< long >( dd, names::parent_idx ), getValue< DictionaryDatum >( dd, names::params ) ); + } + else + { + c_tree_.add_compartment( getValue< long >( dd, names::parent_idx ) ); + } +} +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::add_receptor_( DictionaryDatum& dd ) +{ + const long compartment_idx = getValue< long >( dd, names::comp_idx ); + const std::string receptor_type = getValue< std::string >( dd, names::receptor_type ); + + // create a ringbuffer to collect spikes for the receptor + RingBuffer buffer; + + // add the ringbuffer to the global receptor vector + const size_t syn_idx = syn_buffers_.size(); + syn_buffers_.push_back( buffer ); + + // add the receptor to the compartment + Compartment{{cm_unique_suffix}}* compartment = c_tree_.get_compartment( compartment_idx ); + if ( dd->known( names::params ) ) + { + compartment->compartment_currents.add_synapse( + receptor_type, syn_idx, getValue< DictionaryDatum >( dd, names::params ) ); + } + else + { + compartment->compartment_currents.add_synapse( receptor_type, syn_idx ); + } +} + +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::init_recordables_pointers_() +{ + /** + * Get the map of all recordables (i.e. all state variables of the model): + * --> keys are state variable names suffixed by the compartment index for + * voltage (e.g. "v_comp1") or by the synapse index for receptor currents + * --> values are pointers to the specific state variables + */ + std::map< Name, double* > recordables = c_tree_.get_recordables(); + + for ( auto rec_it = recordables.begin(); rec_it != recordables.end(); rec_it++ ) + { + // check if name is already in recordables map + auto recname_it = find( recordables_names.begin(), recordables_names.end(), rec_it->first ); + if ( recname_it == recordables_names.end() ) + { + // recordable name is not yet in map, we need to add it + recordables_names.push_back( rec_it->first ); + recordables_values.push_back( rec_it->second ); + const long rec_idx = recordables_values.size() - 1; + // add the recordable to the recordable_name -> recordable_index map + recordablesMap_.insert( rec_it->first, DataAccessFunctor< {{neuronSpecificFileNamesCmSyns["main"]}} >( *this, rec_idx ) ); + } + else + { + // recordable name is in map, we update the pointer to the recordable + long index = recname_it - recordables_names.begin(); + recordables_values[ index ] = rec_it->second; + } + } +} + +void +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::calibrate() +{%- else %} +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::pre_run_hook() +{%- endif %} +{ + logger_.init(); + + // initialize the pointers within the compartment tree + c_tree_.init_pointers(); + // initialize the pointers to the synapse buffers for the receptor currents + c_tree_.set_syn_buffers( syn_buffers_ ); + // initialize the recordables pointers + init_recordables_pointers_(); + +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + c_tree_.calibrate(); +{%- else %} + c_tree_.pre_run_hook(); +{%- endif %} +} + +/** + * Update and spike handling functions + */ +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::update( Time const& origin, const long from, const long to ) +{ + assert( to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() ); + assert( from < to ); + + for ( long lag = from; lag < to; ++lag ) + { + const double v_0_prev = c_tree_.get_root()->v_comp; + + c_tree_.construct_matrix( lag ); + c_tree_.solve_matrix(); + + // threshold crossing + if ( c_tree_.get_root()->v_comp >= V_th_ && v_0_prev < V_th_ ) + { + set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); + + SpikeEvent se; + kernel().event_delivery_manager.send( *this, se, lag ); + } + + logger_.record_data( origin.get_steps() + lag ); + } +} + +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::handle( SpikeEvent& e ) +{ + if ( e.get_weight() < 0 ) + { + throw BadProperty( "Synaptic weights must be positive." ); + } + + assert( e.get_delay_steps() > 0 ); + assert( ( e.get_rport() >= 0 ) && ( ( size_t ) e.get_rport() < syn_buffers_.size() ) ); + + syn_buffers_[ e.get_rport() ].add_value( + e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); +} + +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::handle( CurrentEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + + const double c = e.get_current(); + const double w = e.get_weight(); + + Compartment{{cm_unique_suffix}}* compartment = c_tree_.get_compartment_opt( e.get_rport() ); + compartment->currents.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); +} + +void +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::handle( DataLoggingRequest& e ) +{ + logger_.handle( e ); +} + +} // namespace diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/@NEURON_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/@NEURON_NAME@.h.jinja2 new file mode 100644 index 000000000..a2bfa8a21 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/@NEURON_NAME@.h.jinja2 @@ -0,0 +1,343 @@ +/* + * {{neuronSpecificFileNamesCmSyns["main"]}}.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef CM_DEFAULT_H +#define CM_DEFAULT_H + +// Includes from nestkernel: +#include "archiving_node.h" +#include "event.h" +#include "nest_types.h" +#include "universal_data_logger.h" + +#include "{{neuronSpecificFileNamesCmSyns["compartmentcurrents"]}}.h" +#include "{{neuronSpecificFileNamesCmSyns["tree"]}}.h" + +namespace nest +{ + +/* BeginUserDocs: neuron, compartmental model + +Short description ++++++++++++++++++ + +A neuron model with user-defined dendrite structure. +Currently, AMPA, GABA or AMPA+NMDA receptors. + +Description ++++++++++++ + +``cm_default`` is an implementation of a compartmental model. The structure of the +neuron -- soma, dendrites, axon -- is user-defined at runtime by adding +compartments through ``nest.SetStatus()``. Each compartment can be assigned +receptors, also through ``nest.SetStatus()``. + +The default model is passive, but sodium and potassium currents can be added +by passing non-zero conductances ``g_Na`` and ``g_K`` with the parameter dictionary +when adding compartments. Receptors can be AMPA and/or NMDA (excitatory), and +GABA (inhibitory). Ion channel and receptor currents to the compartments can be +customized through NESTML + +Usage ++++++ + +The structure of the dendrite is user defined. Thus after creation of the neuron +in the standard manner: + +.. code-block:: Python + + cm = nest.Create('cm_default') + +compartments can be added as follows: + +.. code-block:: Python + + cm.compartments = [ + {"parent_idx": -1, "params": {"e_L": -65.}}, + {"parent_idx": 0, "params": {"e_L": -60., "g_C": 0.02}} + ] + +Each compartment is assigned an index, corresponding to the order in which they +were added. Subsequently, compartment indices are used to specify parent +compartments in the tree or are used to assign receptors to the compartments. +By convention, the first compartment is the root (soma), which has no parent. +In this case, ``parent_index`` is -1. + +Synaptic receptors can be added as follows: + +.. code-block:: Python + + cm.receptors = [{ + "comp_idx": 1, + "receptor_type": "AMPA", + "params": {"e_AMPA": 0., "tau_AMPA": 3.} + }] + +Similar to compartments, each receptor is assigned an index, starting at 0 and +corresponding to the order in which they are added. This index is used +subsequently to connect synapses to the receptor: + +.. code-block:: Python + + nest.Connect(pre, cm_model, syn_spec={ + 'synapse_model': 'static_synapse', 'weight': 5., 'delay': 0.5, + 'receptor_type': 2}) + +.. note:: + + In the ``nest.SetStatus()`` call, the ``receptor_type`` entry is a string + that specifies the type of receptor. In the ``nest.Connect()`` call, the + ``receptor_type`` entry is an integer that specifies the receptor index. + +.. note:: + + Each compartments' respective "receptors" entries can be a dictionary or a list + of dictionaries containing receptor details. When a dictionary is provided, + a single compartment receptor is added to the model. When a list of dicts + is provided, multiple compartments' receptors are added with a single + ``nest.SetStatus()`` call. + +Compartment{{cm_unique_suffix}} voltages can be recorded. To do so, create a multimeter in the +standard manner but specify the recorded voltages as +``v_comp{compartment_index}``. State variables for ion channels can be recorded as well, +using the syntax ``{state_variable_name}{compartment_index}``. For receptor state +variables, use the receptor index ``{state_variable_name}{receptor_index}``: + +.. code-block:: Python + + mm = nest.Create('multimeter', 1, {'record_from': ['v_comp0'}, ...}) + +Current generators can be connected to the model. In this case, the receptor +type is the compartment index: + +.. code-block:: Python + + dc = nest.Create('dc_generator', {...}) + nest.Connect(dc, cm, syn_spec={..., 'receptor_type': 0} + +Parameters +++++++++++ + +The following parameters can be set in the status dictionary. + +=========== ======= =========================================================== + V_th mV Spike threshold (default: -55.0 mV) +=========== ======= =========================================================== + +The following parameters can be used when adding compartments using ``SetStatus()`` + +=========== ======= =============================================================== + C_m uF Capacitance of compartment (default: 1 uF) + g_C uS Coupling conductance with parent compartment (default: 0.01 uS) + g_L uS Leak conductance of the compartment (default: 0.1 uS) + e_L mV Leak reversal of the compartment (default: -70. mV) +=========== ======= =============================================================== + +Ion channels and receptor types for the default model are hardcoded. +For ion channels, there is a Na-channel and a K-channel. Parameters can be set +by specifying the following entries in the ``SetStatus`` dictionary argument: + +=========== ======= =========================================================== + gbar_Na uS Maximal conductance Na channel (default: 0 uS) + e_Na mV Reversal Na channel default (default: 50 mV) + gbar_K uS Maximal conductance K channel (default: 0 uS) + e_K mV Reversal K channel (default: -85 mV) +=========== ======= =========================================================== + +For receptors, the choice is ``AMPA``, ``GABA`` or ``NMDA`` or ``AMPA_NMDA``. +Ion channels and receptor types can be customized with :doc:`NESTML `. + +If ``receptor_type`` is AMPA + +=========== ======= =========================================================== + e_AMPA mV AMPA reversal (default 0 mV) + tau_r_AMPA ms AMPA rise time (default .2 ms) + tau_d_AMPA ms AMPA decay time (default 3. ms) +=========== ======= =========================================================== + +If ``receptor_type`` is GABA + +=========== ======= =========================================================== + e_GABA mV GABA reversal (default -80 mV) + tau_r_GABA ms GABA rise time (default .2 ms) + tau_d_GABA ms GABA decay time (default 10. ms) +=========== ======= =========================================================== + +If ``receptor_type`` is NMDA + +=========== ======= =========================================================== + e_NMDA mV NMDA reversal (default 0 mV) + tau_r_NMDA ms NMDA rise time (default .2 ms) + tau_d_NMDA ms NMDA decay time (default 43. ms) +=========== ======= =========================================================== + +If ``receptor_type`` is AMPA_NMDA + +============ ======= =========================================================== + e_AMPA_NMDA mV NMDA reversal (default 0 mV) + tau_r_AMPA ms AMPA rise time (default .2 ms) + tau_d_AMPA ms AMPA decay time (default 3. ms) + tau_r_NMDA ms NMDA rise time (default .2 ms) + tau_d_NMDA ms NMDA decay time (default 43. ms) + NMDA_ratio (1) Ratio of NMDA versus AMPA channels +============ ======= =========================================================== + +Sends ++++++ + +SpikeEvent + +Receives +++++++++ + +SpikeEvent, CurrentEvent, DataLoggingRequest + +References +++++++++++ + +Data-driven reduction of dendritic morphologies with preserved dendro-somatic responses +WAM Wybo, J Jordan, B Ellenberger, UM Mengual, T Nevian, W Senn +Elife 10, `e60936 `_ + +See also +++++++++ + +NEURON simulator ;-D + +EndUserDocs*/ + +class {{neuronSpecificFileNamesCmSyns["main"]}} : public ArchivingNode +{ + +public: + {{neuronSpecificFileNamesCmSyns["main"]}}(); + {{neuronSpecificFileNamesCmSyns["main"]}}( const {{neuronSpecificFileNamesCmSyns["main"]}}& ); + + using Node::handle; + using Node::handles_test_event; + + port send_test_event( Node&, rport, synindex, bool ); + + void handle( SpikeEvent& ); + void handle( CurrentEvent& ); + void handle( DataLoggingRequest& ); + + port handles_test_event( SpikeEvent&, rport ); + port handles_test_event( CurrentEvent&, rport ); + port handles_test_event( DataLoggingRequest&, rport ); + + void get_status( DictionaryDatum& ) const; + void set_status( const DictionaryDatum& ); + +private: + void add_compartment_( DictionaryDatum& dd ); + void add_receptor_( DictionaryDatum& dd ); + + void init_recordables_pointers_(); +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate(); +{%- else %} + void pre_run_hook(); +{%- endif %} + + void update( Time const&, const long, const long ); + + CompTree{{cm_unique_suffix}} c_tree_; + std::vector< RingBuffer > syn_buffers_; + + // To record variables with DataAccessFunctor + double + get_state_element( size_t elem ) + { + return *recordables_values[ elem ]; + }; + + // The next classes need to be friends to access the State_ class/member + friend class DataAccessFunctor< {{neuronSpecificFileNamesCmSyns["main"]}} >; + friend class DynamicRecordablesMap< {{neuronSpecificFileNamesCmSyns["main"]}} >; + friend class DynamicUniversalDataLogger< {{neuronSpecificFileNamesCmSyns["main"]}} >; + + /* + internal ordering of all recordables in a vector + the vector 'recordables_values' stores pointers to all state variables + present in the model + */ + std::vector< Name > recordables_names; + std::vector< double* > recordables_values; + + //! Mapping of recordables names to access functions + DynamicRecordablesMap< {{neuronSpecificFileNamesCmSyns["main"]}} > recordablesMap_; + //! Logger for all analog data + DynamicUniversalDataLogger< {{neuronSpecificFileNamesCmSyns["main"]}} > logger_; + + double V_th_; +}; + + +inline port +nest::{{neuronSpecificFileNamesCmSyns["main"]}}::send_test_event( Node& target, rport receptor_type, synindex, bool ) +{ + SpikeEvent e; + e.set_sender( *this ); + return target.handles_test_event( e, receptor_type ); +} + +inline port +{{neuronSpecificFileNamesCmSyns["main"]}}::handles_test_event( SpikeEvent&, rport receptor_type ) +{ + if ( ( receptor_type < 0 ) or ( receptor_type >= static_cast< port >( syn_buffers_.size() ) ) ) + { + std::ostringstream msg; + msg << "Valid spike receptor ports for " << get_name() << " are in "; + msg << "[" << 0 << ", " << syn_buffers_.size() << "["; + throw UnknownPort( receptor_type, msg.str() ); + } + return receptor_type; +} + +inline port +{{neuronSpecificFileNamesCmSyns["main"]}}::handles_test_event( CurrentEvent&, rport receptor_type ) +{ + // if get_compartment returns nullptr, raise the error + if ( not c_tree_.get_compartment( long( receptor_type ), c_tree_.get_root(), 0 ) ) + { + std::ostringstream msg; + msg << "Valid current receptor ports for " << get_name() << " are in "; + msg << "[" << 0 << ", " << c_tree_.get_size() << "["; + throw UnknownPort( receptor_type, msg.str() ); + } + return receptor_type; +} + +inline port +{{neuronSpecificFileNamesCmSyns["main"]}}::handles_test_event( DataLoggingRequest& dlr, rport receptor_type ) +{ + if ( receptor_type != 0 ) + { + throw UnknownReceptorType( receptor_type, get_name() ); + } + return logger_.connect_logging_device( dlr, recordablesMap_ ); +} + +} // namespace + +#endif /* #ifndef CM_{cm_unique_suffix | upper }}_H */ diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/__init__.py b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/__init__.py new file mode 100644 index 000000000..2f830f260 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# +# __init__.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 new file mode 100644 index 000000000..6d3073669 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 @@ -0,0 +1,324 @@ +#include "{{neuronSpecificFileNamesCmSyns["compartmentcurrents"]}}.h" + +{%- set current_conductance_name_prefix = "g" %} +{%- set current_equilibrium_name_prefix = "e" %} +{% macro render_dynamic_channel_variable_name(variable_type, ion_channel_name) -%} + {%- if variable_type == "gbar" -%} + {{ current_conductance_name_prefix~"_"~ion_channel_name }} + {%- elif variable_type == "e" -%} + {{ current_equilibrium_name_prefix~"_"~ion_channel_name }} + {%- endif -%} +{%- endmacro -%} + +{%- macro render_state_variable_name(pure_variable_name, ion_channel_name) -%} + {{ pure_variable_name~"_"~ion_channel_name }} +{%- endmacro -%} + +{% macro render_time_resolution_variable(synapse_info) -%} +{# we assume here that there is only one such variable ! #} +{%- with %} +{%- for analytic_helper_name, analytic_helper_info in synapse_info["analytic_helpers"].items() -%} +{%- if analytic_helper_info["is_time_resolution"] -%} + {{ analytic_helper_name }} +{%- endif -%} +{%- endfor -%} +{% endwith %} +{%- endmacro %} + +{% macro render_function_return_type(function) -%} +{%- with -%} + {%- set symbol = function.get_scope().resolve_to_symbol(function.get_name(), SymbolKind.FUNCTION) -%} + {{ types_printer.convert(symbol.get_return_type()) }} +{%- endwith -%} +{%- endmacro -%} + +{% macro render_inline_expression_type(inline_expression) -%} +{%- with -%} + {%- set symbol = inline_expression.get_scope().resolve_to_symbol(inline_expression.variable_name, SymbolKind.VARIABLE) -%} + {{ types_printer.convert(symbol.get_type_symbol()) }} +{%- endwith -%} +{%- endmacro -%} + +{% macro render_static_channel_variable_name(variable_type, ion_channel_name) -%} + +{%- with %} +{%- for ion_channel_nm, channel_info in chan_info.items() -%} + {%- if ion_channel_nm == ion_channel_name -%} + {%- for variable_tp, variable_info in channel_info["channel_parameters"].items() -%} + {%- if variable_tp == variable_type -%} + {%- set variable = variable_info["parameter_block_variable"] -%} + {{ variable.name }} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%} +{% endwith %} + +{%- endmacro %} + +{% macro render_channel_function(function, ion_channel_name) -%} +{%- with %} +{{printer.print_function_definition(function, "nest::"~ion_channel_name)}} +{ +{%- filter indent(2,True) %} +{%- with ast = function.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +} +{% endwith %} +{%- endmacro %} + + +{%- with %} +{%- for ion_channel_name, channel_info in chan_info.items() %} + +// {{ion_channel_name}} channel ////////////////////////////////////////////////////////////////// +nest::{{ion_channel_name}}::{{ion_channel_name}}() + +{%- for pure_variable_name, variable_info in channel_info["gating_variables"].items() %} +// state variable {{pure_variable_name -}} +{%- set variable = variable_info["state_variable"] %} +{%- set rhs_expression = variable_info["rhs_expression"] %} +{% if loop.first %}: {% else %}, {% endif %} +{{- variable.name}}({{ printer.print_expression(rhs_expression, with_origins = False) -}}) +{%- endfor -%} + +{% for variable_type, variable_info in channel_info["channel_parameters"].items() %} +// channel parameter {{variable_type -}} +{%- set variable = variable_info["parameter_block_variable"] %} +{%- set rhs_expression = variable_info["rhs_expression"] %} +,{{- variable.name}}({{printer.print_expression(rhs_expression, with_origins = False) -}}) +{%- endfor -%} +{} + +nest::{{ion_channel_name}}::{{ion_channel_name}}(const DictionaryDatum& channel_params) + +{%- for pure_variable_name, variable_info in channel_info["gating_variables"].items() %} +// state variable {{pure_variable_name -}} +{%- set variable = variable_info["state_variable"] %} +{%- set rhs_expression = variable_info["rhs_expression"] %} +{% if loop.first %}: {% else %}, {% endif %} +{{- variable.name}}({{printer.print_expression(rhs_expression, with_origins = False) -}}) +{%- endfor -%} + +{% for variable_type, variable_info in channel_info["channel_parameters"].items() %} +// channel parameter {{variable_type -}} +{%- set variable = variable_info["parameter_block_variable"] %} +{%- set rhs_expression = variable_info["rhs_expression"] %} +,{{- variable.name}}({{printer.print_expression(rhs_expression, with_origins = False) -}}) +{%- endfor %} +// update {{ion_channel_name}} channel parameters +{ + {%- with %} + {%- for variable_type, variable_info in channel_info["channel_parameters"].items() %} + {%- set variable = variable_info["parameter_block_variable"] %} + {%- set dynamic_variable = render_dynamic_channel_variable_name(variable_type, ion_channel_name) %} + // {{ion_channel_name}} channel parameter {{dynamic_variable }} + if( channel_params->known( "{{variable.name}}" ) ) + {{variable.name}} = getValue< double >( channel_params, "{{variable.name}}" ); + {%- endfor -%} + {% endwith %} +} + +void +nest::{{ion_channel_name}}::append_recordables(std::map< Name, double* >* recordables, + const long compartment_idx) +{ + // add state variables to recordables map + {%- with %} + {%- for pure_variable_name, variable_info in channel_info["gating_variables"].items() %} + {%- set variable = variable_info["state_variable"] %} + ( *recordables )[ Name( "{{variable.name}}_" + std::to_string(compartment_idx) )] = &{{variable.name}}; + {%- endfor -%} + {% endwith %} +} + +std::pair< double, double > nest::{{ion_channel_name}}::f_numstep(const double v_comp) +{ + const double dt = Time::get_resolution().get_ms(); + + double g_val = 0., i_val = 0.; + {%- set inline_expression = channel_info["ASTInlineExpression"] %} + {%- set inline_expression_d = channel_info["inline_derivative"] %} + {%- set dynamic_variable = render_dynamic_channel_variable_name("gbar", ion_channel_name) %} + {%- set gbar_variable = channel_info["channel_parameters"]["gbar"]["parameter_block_variable"] %} + if ({{gbar_variable.name}} > 1e-9) + { + {% for pure_variable_name, variable_info in channel_info["gating_variables"].items() %} + // activation and timescale of state variable '{{pure_variable_name}}' + {%- set inner_variable = variable_info["ASTVariable"] %} + {%- set expected_functions_info = variable_info["expected_functions"] %} + {%- for expected_function_type, expected_function_info in expected_functions_info.items() %} + {%- set result_variable_name = expected_function_info["result_variable_name"] %} + {%- set function_to_call = expected_function_info["ASTFunction"] %} + {%- set function_parameters = function_to_call.get_parameters() %} + // {{expected_function_type}} + {{render_function_return_type(function_to_call)}} {{ result_variable_name }} = {{function_to_call.get_name()}}( + {%- for parameter in function_parameters -%} + {{- parameter.name }} + {%- endfor -%} + ); + {%- endfor %} + {%- endfor %} + + {% for pure_variable_name, variable_info in channel_info["gating_variables"].items() %} + // advance state variable {{pure_variable_name}} one timestep + {%- set inner_variable = variable_info["ASTVariable"] %} + {%- set expected_functions_info = variable_info["expected_functions"] %} + {%- set tau_result_variable_name = expected_functions_info["tau"]["result_variable_name"] %} + {%- set inf_result_variable_name = expected_functions_info["inf"]["result_variable_name"] %} + {%- set propagator = "p_"~pure_variable_name~"_"~ion_channel_name %} + {%- set state_variable = render_state_variable_name(pure_variable_name, ion_channel_name) %} + {{render_inline_expression_type(inline_expression)}} {{propagator}} = exp(-dt / {{tau_result_variable_name}}); // + {{state_variable}} *= {{propagator}} ; + {{state_variable}} += (1. - {{propagator}}) * {{inf_result_variable_name}}; + {%- endfor %} + + {% set g_dynamic = render_dynamic_channel_variable_name("gbar", ion_channel_name) %} + // compute the conductance of the {{ion_channel_name}} channel + double i_tot = {{ local_variables_printer.print_expression(inline_expression.get_expression(), with_origins = False) }}; + // derivative + double d_i_tot_dv = {{ local_variables_printer.print_expression(inline_expression_d, with_origins = False) }}; + + // for numerical integration + g_val = - d_i_tot_dv / 2.; + i_val = i_tot - d_i_tot_dv * v_comp / 2.; + } + + return std::make_pair(g_val, i_val); + +} + +{%- for pure_variable_name, state_variable_info in channel_info["gating_variables"].items() %} +{%- for function_type, function_info in state_variable_info["expected_functions"].items() %} +{{render_channel_function(function_info["ASTFunction"], ion_channel_name)}} +{%- endfor %} +{%- endfor %} + +{% endfor -%} +{% endwith %} +//////////////////////////////////////////////////////////////////////////////// + +{%- for synapse_name, synapse_info in syns_info.items() %} +// {{synapse_name}} synapse //////////////////////////////////////////////////////////////// +nest::{{synapse_name}}::{{synapse_name}}( const long syn_index ) + {%- for param_name, param_declaration in synapse_info["parameters_used"].items() %} + {% if loop.first %}: {% else %}, {% endif -%} + {{param_name}} ({{printer.print_expression(param_declaration.get_expression(), with_origins = False)}}) + {%- endfor %} +{ + syn_idx = syn_index; +} + +// {{synapse_name}} synapse //////////////////////////////////////////////////////////////// +nest::{{synapse_name}}::{{synapse_name}}( const long syn_index, const DictionaryDatum& receptor_params ) + {%- for param_name, param_declaration in synapse_info["parameters_used"].items() %} + {% if loop.first %}: {% else %}, {% endif -%} + {{param_name}} ({{printer.print_expression(param_declaration.get_expression(), with_origins = False)}}) + {%- endfor %} +{ + syn_idx = syn_index; + + // update parameters + {%- for param_name, param_declaration in synapse_info["parameters_used"].items() %} + if( receptor_params->known( "{{param_name}}" ) ) + {{param_name}} = getValue< double >( receptor_params, "{{param_name}}" ); + {%- endfor %} +} + +void +nest::{{synapse_name}}::append_recordables(std::map< Name, double* >* recordables) +{ + {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} + ( *recordables )[ Name( "{{convolution_info["kernel"]["name"]}}_" + std::to_string(syn_idx) )] = &{{convolution}}; + {%- endfor %} +} + +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +void nest::{{synapse_name}}::calibrate() +{%- else %} +void nest::{{synapse_name}}::pre_run_hook() +{%- endif %} +{ + + const double {{render_time_resolution_variable(synapse_info)}} = Time::get_resolution().get_ms(); + + // set propagators to ode toolbox returned value + {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} + {%- for state_variable_name, state_variable_info in convolution_info["analytic_solution"]["propagators"].items()%} + {{state_variable_name}} = {{local_variables_printer.print_expression(state_variable_info["init_expression"], with_origins = False)}}; + {%- endfor %} + {%- endfor %} + + // initial values for user defined states + // warning: this shadows class variables + {%- for state_name, state_declaration in synapse_info["states_used"].items() %} + double {{state_name}} = {{printer.print_expression(state_declaration.get_expression(), with_origins = False)}}; + {%- endfor %} + + // initial values for kernel state variables, set to zero + {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} + {%- for state_variable_name, state_variable_info in convolution_info["analytic_solution"]["kernel_states"].items()%} + {{state_variable_name}} = 0; + {%- endfor %} + {%- endfor %} + + // user declared internals in order they were declared + {%- for internal_name, internal_declaration in synapse_info["internals_used_declared"] %} + {{internal_name}} = {{printer.print_expression(internal_declaration.get_expression(), with_origins = False)}}; + {%- endfor %} + + {{synapse_info["buffer_name"]}}_->clear(); +} + +std::pair< double, double > nest::{{synapse_name}}::f_numstep( const double v_comp, const long lag ) +{ + // get spikes + double s_val = {{synapse_info["buffer_name"]}}_->get_value( lag ); // * g_norm_; + + // update kernel state variable / compute synaptic conductance + {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} + {%- for state_variable_name, state_variable_info in convolution_info["analytic_solution"]["kernel_states"].items()%} + {{state_variable_name}} = {{local_variables_printer.print_expression(state_variable_info["update_expression"], with_origins = False)}}; + {{state_variable_name}} += s_val * {{local_variables_printer.print_expression(state_variable_info["init_expression"], with_origins = False)}}; + + {%- endfor %} + {%- endfor %} + + // total current + // this expression should be the transformed inline expression + double i_tot = {{local_variables_printer.print_expression(synapse_info["inline_expression"].get_expression(), with_origins = False)}}; + + // derivative of that expression + // voltage derivative of total current + // compute derivative with respect to current with sympy + double d_i_tot_dv = {{local_variables_printer.print_expression(synapse_info["inline_expression_d"], with_origins = False)}}; + + // for numerical integration + double g_val = - d_i_tot_dv / 2.; + double i_val = i_tot - d_i_tot_dv * v_comp / 2.; + + return std::make_pair(g_val, i_val); + +} + +{%- for function in neuron.get_functions() %} +{{printer.print_function_definition(function, namespace = "nest::"+synapse_name)}} +{ +{%- filter indent(2,True) %} +{%- with ast = function.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfilter %} +} +{%- endfor %} + +// {{synapse_name}} synapse end /////////////////////////////////////////////////////////// +{%- endfor %} + + + + + + diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 new file mode 100644 index 000000000..a823c2e36 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 @@ -0,0 +1,348 @@ +#ifndef SYNAPSES_NEAT_H_{{cm_unique_suffix | upper }} +#define SYNAPSES_NEAT_H_{{cm_unique_suffix | upper }} + +#include + +#include "ring_buffer.h" + +{% macro render_variable_type(variable) -%} +{%- with -%} + {%- set symbol = variable.get_scope().resolve_to_symbol(variable.name, SymbolKind.VARIABLE) -%} + {{ types_printer.convert(symbol.type_symbol) }} +{%- endwith -%} +{%- endmacro %} + +namespace nest +{ + +{%- with %} +{%- for ion_channel_name, channel_info in chan_info.items() %} + +class {{ion_channel_name}}{ +private: +// user-defined parameters {{ion_channel_name}} channel (maximal conductance, reversal potential) + {%- for pure_variable_name, variable_info in channel_info["gating_variables"].items() %} + // state variable {{pure_variable_name -}} + {%- set variable = variable_info["state_variable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{render_variable_type(variable)}} {{ variable.name}} = {{printer.print_expression(rhs_expression, with_origins = False) -}}; + {%- endfor %} +// state variables {{ion_channel_name}} channel + {%- for variable_type, variable_info in channel_info["channel_parameters"].items() %} + // parameter {{variable_type -}} + {%- set variable = variable_info["parameter_block_variable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{render_variable_type(variable)}} {{ variable.name}} = {{printer.print_expression(rhs_expression, with_origins = False) -}}; + {%- endfor %} + +public: + // constructor, destructor + {{ion_channel_name}}(); + {{ion_channel_name}}(const DictionaryDatum& channel_params); + ~{{ion_channel_name}}(){}; + + // initialization channel +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate() { +{%- else %} + void pre_run_hook() { +{%- endif %} + {%- for pure_variable_name, variable_info in channel_info["gating_variables"].items() -%} + {%- set variable = variable_info["state_variable"] -%} + {%- set rhs_expression = variable_info["rhs_expression"] -%} + {{ variable.name}} = {{printer.print_expression(rhs_expression, with_origins = False) }}; + {%- endfor -%} + }; + void append_recordables(std::map< Name, double* >* recordables, + const long compartment_idx); + + // numerical integration step + std::pair< double, double > f_numstep( const double v_comp ); + + // function declarations +{%- for pure_variable_name, state_variable_info in channel_info["gating_variables"].items() %} +{% for function_type, function_info in state_variable_info["expected_functions"].items() %} + {{printer.print_function_declaration(function_info["ASTFunction"]) -}}; +{% endfor %} +{%- endfor %} + +}; +{% endfor -%} +{% endwith -%} + + +////////////////////////////////////////////////// synapses + +{% macro render_time_resolution_variable(synapse_info) -%} +{# we assume here that there is only one such variable ! #} +{%- with %} +{%- for analytic_helper_name, analytic_helper_info in synapse_info["analytic_helpers"].items() -%} +{%- if analytic_helper_info["is_time_resolution"] -%} + {{ analytic_helper_name }} +{%- endif -%} +{%- endfor -%} +{% endwith %} +{%- endmacro %} + +{%- with %} +{%- for synapse_name, synapse_info in syns_info.items() %} + +class {{synapse_name}}{ +private: + // global synapse index + long syn_idx = 0; + + // propagators, initialized via pre_run_hook() or calibrate() + {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} + {%- for state_variable_name, state_variable_info in convolution_info["analytic_solution"]["propagators"].items()%} + double {{state_variable_name}}; + {%- endfor %} + {%- endfor %} + + // kernel state variables, initialized via pre_run_hook() or calibrate() + {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} + {%- for state_variable_name, state_variable_info in convolution_info["analytic_solution"]["kernel_states"].items()%} + double {{state_variable_name}}; + {%- endfor %} + {%- endfor %} + + // user defined parameters, initialized via pre_run_hook() or calibrate() + {%- for param_name, param_declaration in synapse_info["parameters_used"].items() %} + double {{param_name}}; + {%- endfor %} + + // user declared internals in order they were declared, initialized via pre_run_hook() or calibrate() + {%- for internal_name, internal_declaration in synapse_info["internals_used_declared"] %} + double {{internal_name}}; + {%- endfor %} + + // spike buffer + RingBuffer* {{synapse_info["buffer_name"]}}_; + +public: + // constructor, destructor + {{synapse_name}}( const long syn_index); + {{synapse_name}}( const long syn_index, const DictionaryDatum& receptor_params); + ~{{synapse_name}}(){}; + + long + get_syn_idx() + { + return syn_idx; + }; + + // numerical integration step + std::pair< double, double > f_numstep( const double v_comp, const long lag ); + + // calibration +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate(); +{%- else %} + void pre_run_hook(); +{%- endif %} + void append_recordables(std::map< Name, double* >* recordables); + void set_buffer_ptr( std::vector< RingBuffer >& syn_buffers ) + { + {{synapse_info["buffer_name"]}}_ = &syn_buffers[ syn_idx ]; + }; + + // function declarations + {% for function in neuron.get_functions() %} + {{printer.print_function_declaration(function)}}; + {% endfor %} +}; + + +{% endfor -%} +{% endwith -%} + +///////////////////////////////////////////// currents + +{%- set channel_suffix = "_chan_" %} + +class CompartmentCurrents{{cm_unique_suffix}} { +private: + // ion channels +{% with %} + {%- for ion_channel_name, channel_info in chan_info.items() %} + {{ion_channel_name}} {{ion_channel_name}}{{channel_suffix}}; + {% endfor -%} +{% endwith %} + + // synapses + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + std::vector < {{synapse_name}} > {{synapse_name}}_syns_; + {% endfor -%} + {% endwith -%} + +public: + CompartmentCurrents{{cm_unique_suffix}}(){}; + explicit CompartmentCurrents{{cm_unique_suffix}}(const DictionaryDatum& channel_params) + { + {%- with %} + {%- for ion_channel_name, channel_info in chan_info.items() %} + {{ion_channel_name}}{{channel_suffix}} = {{ion_channel_name}}( channel_params ); + {% endfor -%} + {% endwith -%} + }; + ~CompartmentCurrents{{cm_unique_suffix}}(){}; + +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate() { +{%- else %} + void pre_run_hook() { +{%- endif %} + // initialization of the ion channels + {%- with %} + {%- for ion_channel_name, channel_info in chan_info.items() %} +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + {{ion_channel_name}}{{channel_suffix}}.calibrate(); +{%- else %} + {{ion_channel_name}}{{channel_suffix}}.pre_run_hook(); +{%- endif %} + {% endfor -%} + {% endwith -%} + + // initialization of synapses + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + // initialization of {{synapse_name}} synapses + for( auto syn_it = {{synapse_name}}_syns_.begin(); + syn_it != {{synapse_name}}_syns_.end(); + ++syn_it ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + syn_it->calibrate(); +{%- else %} + syn_it->pre_run_hook(); +{%- endif %} + } + {% endfor -%} + {% endwith -%} + }; + + void add_synapse( const std::string& type, const long syn_idx ) + { + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + {% if not loop.first %}else{% endif %} if ( type == "{{synapse_name}}" ) + { + {{synapse_name}}_syns_.push_back( {{synapse_name}}( syn_idx ) ); + } + {% endfor -%} + {% endwith -%} + else + { + assert( false ); + } + }; + void add_synapse( const std::string& type, const long syn_idx, const DictionaryDatum& receptor_params ) + { + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + {% if not loop.first %}else{% endif %} if ( type == "{{synapse_name}}" ) + { + {{synapse_name}}_syns_.push_back( {{synapse_name}}( syn_idx, receptor_params ) ); + } + {% endfor -%} + {% endwith -%} + else + { + assert( false ); + } + }; + + void + add_receptor_info( ArrayDatum& ad, const long compartment_index ) + { + + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + for( auto syn_it = {{synapse_name}}_syns_.begin(); syn_it != {{synapse_name}}_syns_.end(); syn_it++) + { + DictionaryDatum dd = DictionaryDatum( new Dictionary ); + def< long >( dd, names::receptor_idx, syn_it->get_syn_idx() ); + def< long >( dd, names::comp_idx, compartment_index ); + def< std::string >( dd, names::receptor_type, "{{synapse_name}}" ); + ad.push_back( dd ); + } + {% endfor -%} + {% endwith -%} + }; + + void + set_syn_buffers( std::vector< RingBuffer >& syn_buffers ) + { + // spike buffers for synapses + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + for( auto syn_it = {{synapse_name}}_syns_.begin(); syn_it != {{synapse_name}}_syns_.end(); syn_it++) + syn_it->set_buffer_ptr( syn_buffers ); + {% endfor -%} + {% endwith -%} + }; + + std::map< Name, double* > + get_recordables( const long compartment_idx ) + { + std::map< Name, double* > recordables; + + // append ion channel state variables to recordables + {%- with %} + {%- for ion_channel_name, channel_info in chan_info.items() %} + {{ion_channel_name}}{{channel_suffix}}.append_recordables( &recordables, compartment_idx ); + {% endfor -%} + {% endwith -%} + + // append synapse state variables to recordables + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + for( auto syn_it = {{synapse_name}}_syns_.begin(); syn_it != {{synapse_name}}_syns_.end(); syn_it++) + syn_it->append_recordables( &recordables ); + {% endfor -%} + {% endwith -%} + + return recordables; + }; + + std::pair< double, double > + f_numstep( const double v_comp, const long lag ) + { + std::pair< double, double > gi(0., 0.); + double g_val = 0.; + double i_val = 0.; + + {%- with %} + {%- for ion_channel_name, channel_info in chan_info.items() %} + // contribution of {{ion_channel_name}} channel + gi = {{ion_channel_name}}{{channel_suffix}}.f_numstep( v_comp ); + + g_val += gi.first; + i_val += gi.second; + + {% endfor -%} + {% endwith -%} + + {%- with %} + {%- for synapse_name, synapse_info in syns_info.items() %} + // contribution of {{synapse_name}} synapses + for( auto syn_it = {{synapse_name}}_syns_.begin(); + syn_it != {{synapse_name}}_syns_.end(); + ++syn_it ) + { + gi = syn_it->f_numstep( v_comp, lag ); + + g_val += gi.first; + i_val += gi.second; + } + {% endfor -%} + {% endwith -%} + + return std::make_pair(g_val, i_val); + }; +}; + +} // namespace + +#endif /* #ifndef SYNAPSES_NEAT_H_{{cm_unique_suffix | upper }} */ diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_tree_@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_tree_@NEURON_NAME@.cpp.jinja2 new file mode 100644 index 000000000..38bf6d446 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_tree_@NEURON_NAME@.cpp.jinja2 @@ -0,0 +1,515 @@ +/* + * cm_tree.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ +#include "{{neuronSpecificFileNamesCmSyns["tree"]}}.h" + + +nest::Compartment{{cm_unique_suffix}}::Compartment{{cm_unique_suffix}}( const long compartment_index, const long parent_index ) + : xx_( 0.0 ) + , yy_( 0.0 ) + , comp_index( compartment_index ) + , p_index( parent_index ) + , parent( nullptr ) + , v_comp( 0.0 ) + , ca( 1.0 ) + , gc( 0.01 ) + , gl( 0.1 ) + , el( -70. ) + , gg0( 0.0 ) + , ca__div__dt( 0.0 ) + , gl__div__2( 0.0 ) + , gc__div__2( 0.0 ) + , gl__times__el( 0.0 ) + , ff( 0.0 ) + , gg( 0.0 ) + , hh( 0.0 ) + , n_passed( 0 ) +{ + v_comp = el; + + compartment_currents = CompartmentCurrents{{cm_unique_suffix}}(); +} +nest::Compartment{{cm_unique_suffix}}::Compartment{{cm_unique_suffix}}( const long compartment_index, + const long parent_index, + const DictionaryDatum& compartment_params ) + : xx_( 0.0 ) + , yy_( 0.0 ) + , comp_index( compartment_index ) + , p_index( parent_index ) + , parent( nullptr ) + , v_comp( 0.0 ) + , ca( 1.0 ) + , gc( 0.01 ) + , gl( 0.1 ) + , el( -70. ) + , gg0( 0.0 ) + , ca__div__dt( 0.0 ) + , gl__div__2( 0.0 ) + , gc__div__2( 0.0 ) + , gl__times__el( 0.0 ) + , ff( 0.0 ) + , gg( 0.0 ) + , hh( 0.0 ) + , n_passed( 0 ) +{ + + updateValue< double >( compartment_params, names::C_m, ca ); + updateValue< double >( compartment_params, names::g_C, gc ); + updateValue< double >( compartment_params, names::g_L, gl ); + updateValue< double >( compartment_params, names::e_L, el ); + + v_comp = el; + + compartment_currents = CompartmentCurrents{{cm_unique_suffix}}( compartment_params ); +} + +void +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +nest::Compartment{{cm_unique_suffix}}::calibrate() +{%- else %} +nest::Compartment{{cm_unique_suffix}}::pre_run_hook() +{%- endif %} +{ +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + compartment_currents.calibrate(); +{%- else %} + compartment_currents.pre_run_hook(); +{%- endif %} + + const double dt = Time::get_resolution().get_ms(); + ca__div__dt = ca / dt; + gl__div__2 = gl / 2.; + gg0 = ca__div__dt + gl__div__2; + gc__div__2 = gc / 2.; + gl__times__el = gl * el; + + // initialize the buffer + currents.clear(); +} + +std::map< Name, double* > +nest::Compartment{{cm_unique_suffix}}::get_recordables() +{ + std::map< Name, double* > recordables = compartment_currents.get_recordables( comp_index ); + + recordables.insert( recordables.begin(), recordables.end() ); + recordables[ Name( "v_comp" + std::to_string( comp_index ) ) ] = &v_comp; + + return recordables; +} + +// for matrix construction +void +nest::Compartment{{cm_unique_suffix}}::construct_matrix_element( const long lag ) +{ + // matrix diagonal element + gg = gg0; + + if ( parent != nullptr ) + { + gg += gc__div__2; + // matrix off diagonal element + hh = -gc__div__2; + } + + for ( auto child_it = children.begin(); child_it != children.end(); ++child_it ) + { + gg += ( *child_it ).gc__div__2; + } + + // right hand side + ff = ( ca__div__dt - gl__div__2 ) * v_comp + gl__times__el; + + if ( parent != nullptr ) + { + ff -= gc__div__2 * ( v_comp - parent->v_comp ); + } + + for ( auto child_it = children.begin(); child_it != children.end(); ++child_it ) + { + ff -= ( *child_it ).gc__div__2 * ( v_comp - ( *child_it ).v_comp ); + } + + // add all currents to compartment + std::pair< double, double > gi = compartment_currents.f_numstep( v_comp, lag ); + gg += gi.first; + ff += gi.second; + + // add input current + ff += currents.get_value( lag ); +} + + +nest::CompTree{{cm_unique_suffix}}::CompTree{{cm_unique_suffix}}() + : root_( -1, -1 ) + , size_( 0 ) +{ + compartments_.resize( 0 ); + leafs_.resize( 0 ); +} + +/** + * Add a compartment to the tree structure via the python interface + * root shoud have -1 as parent index. Add root compartment first. + * Assumes parent of compartment is already added + */ +void +nest::CompTree{{cm_unique_suffix}}::add_compartment( const long parent_index ) +{ + Compartment{{cm_unique_suffix}}* compartment = new Compartment{{cm_unique_suffix}}( size_, parent_index ); + add_compartment( compartment, parent_index ); +} + +void +nest::CompTree{{cm_unique_suffix}}::add_compartment( const long parent_index, const DictionaryDatum& compartment_params ) +{ + Compartment{{cm_unique_suffix}}* compartment = new Compartment{{cm_unique_suffix}}( size_, parent_index, compartment_params ); + add_compartment( compartment, parent_index ); +} + +void +nest::CompTree{{cm_unique_suffix}}::add_compartment( Compartment{{cm_unique_suffix}}* compartment, const long parent_index ) +{ + size_++; + + if ( parent_index >= 0 ) + { + /** + * we do not raise an UnknownCompartment exception from within + * get_compartment(), because we want to print a more informative + * exception message + */ + Compartment{{cm_unique_suffix}}* parent = get_compartment( parent_index, get_root(), 0 ); + if ( parent == nullptr ) + { + std::string msg = "does not exist in tree, but was specified as a parent compartment"; + throw UnknownCompartment( parent_index, msg ); + } + + parent->children.push_back( *compartment ); + } + else + { + // we raise an error if the root already exists + if ( root_.comp_index >= 0 ) + { + std::string msg = ", the root, has already been instantiated"; + throw UnknownCompartment( root_.comp_index, msg ); + } + root_ = *compartment; + } + + compartment_indices_.push_back( compartment->comp_index ); + + set_compartments(); +} + +/** + * Get the compartment corresponding to the provided index in the tree. + * + * This function gets the compartments by a recursive search through the tree. + * + * The overloaded functions looks only in the subtree of the provided compartment, + * and also has the option to throw an error if no compartment corresponding to + * `compartment_index` is found in the tree + */ +nest::Compartment{{cm_unique_suffix}}* +nest::CompTree{{cm_unique_suffix}}::get_compartment( const long compartment_index ) const +{ + return get_compartment( compartment_index, get_root(), 1 ); +} + +nest::Compartment{{cm_unique_suffix}}* +nest::CompTree{{cm_unique_suffix}}::get_compartment( const long compartment_index, Compartment{{cm_unique_suffix}}* compartment, const long raise_flag ) const +{ + Compartment{{cm_unique_suffix}}* r_compartment = nullptr; + + if ( compartment->comp_index == compartment_index ) + { + r_compartment = compartment; + } + else + { + auto child_it = compartment->children.begin(); + while ( ( not r_compartment ) && child_it != compartment->children.end() ) + { + r_compartment = get_compartment( compartment_index, &( *child_it ), 0 ); + ++child_it; + } + } + + if ( ( not r_compartment ) && raise_flag ) + { + std::string msg = "does not exist in tree"; + throw UnknownCompartment( compartment_index, msg ); + } + + return r_compartment; +} + +/** + * Get the compartment corresponding to the provided index in the tree. Optimized + * trough the use of a pointer vector containing all compartments. Calling this + * function before CompTree{{cm_unique_suffix}}::init_pointers() is called will result in a segmentation + * fault + */ +nest::Compartment{{cm_unique_suffix}}* +nest::CompTree{{cm_unique_suffix}}::get_compartment_opt( const long compartment_idx ) const +{ + return compartments_[ compartment_idx ]; +} + +/** + * Initialize all tree structure pointers + */ +void +nest::CompTree{{cm_unique_suffix}}::init_pointers() +{ + set_parents(); + set_compartments(); + set_leafs(); +} + +/** + * For each compartments, sets its pointer towards its parent compartment + */ +void +nest::CompTree{{cm_unique_suffix}}::set_parents() +{ + for ( auto compartment_idx_it = compartment_indices_.begin(); compartment_idx_it != compartment_indices_.end(); + ++compartment_idx_it ) + { + Compartment{{cm_unique_suffix}}* comp_ptr = get_compartment( *compartment_idx_it ); + // will be nullptr if root + Compartment{{cm_unique_suffix}}* parent_ptr = get_compartment( comp_ptr->p_index, &root_, 0 ); + comp_ptr->parent = parent_ptr; + } +} + +/** + * Creates a vector of compartment pointers, organized in the order in which they were + * added by `add_compartment()` + */ +void +nest::CompTree{{cm_unique_suffix}}::set_compartments() +{ + compartments_.clear(); + + for ( auto compartment_idx_it = compartment_indices_.begin(); compartment_idx_it != compartment_indices_.end(); + ++compartment_idx_it ) + { + compartments_.push_back( get_compartment( *compartment_idx_it ) ); + } +} + +/** + * Creates a vector of compartment pointers of compartments that are also leafs of the tree. + */ +void +nest::CompTree{{cm_unique_suffix}}::set_leafs() +{ + leafs_.clear(); + for ( auto compartment_it = compartments_.begin(); compartment_it != compartments_.end(); ++compartment_it ) + { + if ( int( ( *compartment_it )->children.size() ) == 0 ) + { + leafs_.push_back( *compartment_it ); + } + } +} + +/** + * Initializes pointers for the spike buffers for all synapse receptors + */ +void +nest::CompTree{{cm_unique_suffix}}::set_syn_buffers( std::vector< RingBuffer >& syn_buffers ) +{ + for ( auto compartment_it = compartments_.begin(); compartment_it != compartments_.end(); ++compartment_it ) + { + ( *compartment_it )->compartment_currents.set_syn_buffers( syn_buffers ); + } +} + +/** + * Returns a map of variable names and pointers to the recordables + */ +std::map< Name, double* > +nest::CompTree{{cm_unique_suffix}}::get_recordables() +{ + std::map< Name, double* > recordables; + + /** + * add recordables for all compartments, suffixed by compartment_idx, + * to "recordables" + */ + for ( auto compartment_it = compartments_.begin(); compartment_it != compartments_.end(); ++compartment_it ) + { + std::map< Name, double* > recordables_comp = ( *compartment_it )->get_recordables(); + recordables.insert( recordables_comp.begin(), recordables_comp.end() ); + } + return recordables; +} + +/** + * Initialize state variables + */ +void +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +nest::CompTree{{cm_unique_suffix}}::calibrate() +{%- else %} +nest::CompTree{{cm_unique_suffix}}::pre_run_hook() +{%- endif %} +{ + if ( root_.comp_index < 0 ) + { + std::string msg = "does not exist in tree, meaning that no compartments have been added"; + throw UnknownCompartment( 0, msg ); + } + + // initialize the compartments + for ( auto compartment_it = compartments_.begin(); compartment_it != compartments_.end(); ++compartment_it ) + { +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + ( *compartment_it )->calibrate(); +{%- else %} + ( *compartment_it )->pre_run_hook(); +{%- endif %} + } +} + +/** + * Returns vector of voltage values, indices correspond to compartments in `compartments_` + */ +std::vector< double > +nest::CompTree{{cm_unique_suffix}}::get_voltage() const +{ + std::vector< double > v_comps; + for ( auto compartment_it = compartments_.cbegin(); compartment_it != compartments_.cend(); ++compartment_it ) + { + v_comps.push_back( ( *compartment_it )->v_comp ); + } + return v_comps; +} + +/** + * Return voltage of single compartment voltage, indicated by the compartment_index + */ +double +nest::CompTree{{cm_unique_suffix}}::get_compartment_voltage( const long compartment_index ) +{ + return compartments_[ compartment_index ]->v_comp; +} + +/** + * Construct the matrix equation to be solved to advance the model one timestep + */ +void +nest::CompTree{{cm_unique_suffix}}::construct_matrix( const long lag ) +{ + for ( auto compartment_it = compartments_.begin(); compartment_it != compartments_.end(); ++compartment_it ) + { + ( *compartment_it )->construct_matrix_element( lag ); + } +} + +/** + * Solve matrix with O(n) algorithm + */ +void +nest::CompTree{{cm_unique_suffix}}::solve_matrix() +{ + std::vector< Compartment{{cm_unique_suffix}}* >::iterator leaf_it = leafs_.begin(); + + // start the down sweep (puts to zero the sub diagonal matrix elements) + solve_matrix_downsweep( leafs_[ 0 ], leaf_it ); + + // do up sweep to set voltages + solve_matrix_upsweep( &root_, 0.0 ); +} + +void +nest::CompTree{{cm_unique_suffix}}::solve_matrix_downsweep( Compartment{{cm_unique_suffix}}* compartment, std::vector< Compartment{{cm_unique_suffix}}* >::iterator leaf_it ) +{ + // compute the input output transformation at compartment + std::pair< double, double > output = compartment->io(); + + // move on to the parent layer + if ( compartment->parent != nullptr ) + { + Compartment{{cm_unique_suffix}}* parent = compartment->parent; + // gather input from child layers + parent->gather_input( output ); + // move on to next compartments + ++parent->n_passed; + if ( parent->n_passed == int( parent->children.size() ) ) + { + parent->n_passed = 0; + // move on to next compartment + solve_matrix_downsweep( parent, leaf_it ); + } + else + { + // start at next leaf + ++leaf_it; + if ( leaf_it != leafs_.end() ) + { + solve_matrix_downsweep( *leaf_it, leaf_it ); + } + } + } +} + +void +nest::CompTree{{cm_unique_suffix}}::solve_matrix_upsweep( Compartment{{cm_unique_suffix}}* compartment, double vv ) +{ + // compute compartment voltage + vv = compartment->calc_v( vv ); + // move on to child compartments + for ( auto child_it = compartment->children.begin(); child_it != compartment->children.end(); ++child_it ) + { + solve_matrix_upsweep( &( *child_it ), vv ); + } +} + +/** + * Print the tree graph + */ +void +nest::CompTree{{cm_unique_suffix}}::print_tree() const +{ + // loop over all compartments + std::printf( ">>> CM tree with %d compartments <<<\n", int( compartments_.size() ) ); + for ( int ii = 0; ii < int( compartments_.size() ); ++ii ) + { + Compartment{{cm_unique_suffix}}* compartment = compartments_[ ii ]; + std::cout << " Compartment{{cm_unique_suffix}} " << compartment->comp_index << ": "; + std::cout << "C_m = " << compartment->ca << " nF, "; + std::cout << "g_L = " << compartment->gl << " uS, "; + std::cout << "e_L = " << compartment->el << " mV, "; + if ( compartment->parent != nullptr ) + { + std::cout << "Parent " << compartment->parent->comp_index << " --> "; + std::cout << "g_c = " << compartment->gc << " uS, "; + } + std::cout << std::endl; + } + std::cout << std::endl; +} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_tree_@NEURON_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_tree_@NEURON_NAME@.h.jinja2 new file mode 100644 index 000000000..6f63c778e --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_tree_@NEURON_NAME@.h.jinja2 @@ -0,0 +1,223 @@ +/* + * {{neuronSpecificFileNamesCmSyns["tree"]}}.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef CM_TREE_H +#define CM_TREE_H + +#include + +#include "nest_time.h" +#include "ring_buffer.h" + +// compartmental model +#include "{{neuronSpecificFileNamesCmSyns["compartmentcurrents"]}}.h" + +// Includes from libnestutil: +#include "dict_util.h" +#include "numerics.h" + +// Includes from nestkernel: +#include "exceptions.h" +#include "kernel_manager.h" +#include "universal_data_logger_impl.h" + +// Includes from sli: +#include "dict.h" +#include "dictutils.h" + + +namespace nest +{ + +class Compartment{{cm_unique_suffix}} +{ +private: + // aggragators for numerical integration + double xx_; + double yy_; + +public: + // compartment index + long comp_index; + // parent compartment index + long p_index; + // tree structure indices + Compartment{{cm_unique_suffix}}* parent; + std::vector< Compartment{{cm_unique_suffix}} > children; + // vector for synapses + CompartmentCurrents{{cm_unique_suffix}} compartment_currents; + + // buffer for currents + RingBuffer currents; + // voltage variable + double v_comp; + // electrical parameters + double ca; // compartment capacitance [uF] + double gc; // coupling conductance with parent (meaningless if root) [uS] + double gl; // leak conductance of compartment [uS] + double el; // leak current reversal potential [mV] + // auxiliary variables for efficienchy + double gg0; + double ca__div__dt; + double gl__div__2; + double gc__div__2; + double gl__times__el; + // for numerical integration + double ff; + double gg; + double hh; + // passage counter for recursion + int n_passed; + + // constructor, destructor + Compartment{{cm_unique_suffix}}( const long compartment_index, const long parent_index ); + Compartment{{cm_unique_suffix}}( const long compartment_index, const long parent_index, const DictionaryDatum& compartment_params ); + ~Compartment{{cm_unique_suffix}}(){}; + + // initialization +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate(); +{%- else %} + void pre_run_hook(); +{%- endif %} + std::map< Name, double* > get_recordables(); + + // matrix construction + void construct_matrix_element( const long lag ); + + // maxtrix inversion + inline void gather_input( const std::pair< double, double >& in ); + inline std::pair< double, double > io(); + inline double calc_v( const double v_in ); +}; // Compartment + + +/* +Short helper functions for solving the matrix equation. Can hopefully be inlined +*/ +inline void +nest::Compartment{{cm_unique_suffix}}::gather_input( const std::pair< double, double >& in ) +{ + xx_ += in.first; + yy_ += in.second; +} +inline std::pair< double, double > +nest::Compartment{{cm_unique_suffix}}::io() +{ + // include inputs from child compartments + gg -= xx_; + ff -= yy_; + + // output values + double g_val( hh * hh / gg ); + double f_val( ff * hh / gg ); + + return std::make_pair( g_val, f_val ); +} +inline double +nest::Compartment{{cm_unique_suffix}}::calc_v( const double v_in ) +{ + // reset recursion variables + xx_ = 0.0; + yy_ = 0.0; + + // compute voltage + v_comp = ( ff - v_in * hh ) / gg; + + return v_comp; +} + + +class CompTree{{cm_unique_suffix}} +{ +private: + /* + structural data containers for the compartment model + */ + mutable Compartment{{cm_unique_suffix}} root_; + std::vector< long > compartment_indices_; + std::vector< Compartment{{cm_unique_suffix}}* > compartments_; + std::vector< Compartment{{cm_unique_suffix}}* > leafs_; + + long size_ = 0; + + // recursion functions for matrix inversion + void solve_matrix_downsweep( Compartment{{cm_unique_suffix}}* compartment_ptr, std::vector< Compartment{{cm_unique_suffix}}* >::iterator leaf_it ); + void solve_matrix_upsweep( Compartment{{cm_unique_suffix}}* compartment, double vv ); + + // functions for pointer initialization + void set_parents(); + void set_compartments(); + void set_leafs(); + +public: + // constructor, destructor + CompTree{{cm_unique_suffix}}(); + ~CompTree{{cm_unique_suffix}}(){}; + + // initialization functions for tree structure + void add_compartment( const long parent_index ); + void add_compartment( const long parent_index, const DictionaryDatum& compartment_params ); + void add_compartment( Compartment{{cm_unique_suffix}}* compartment, const long parent_index ); +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} + void calibrate(); +{%- else %} + void pre_run_hook(); +{%- endif %} + + void init_pointers(); + void set_syn_buffers( std::vector< RingBuffer >& syn_buffers ); + std::map< Name, double* > get_recordables(); + + // get a compartment pointer from the tree + Compartment{{cm_unique_suffix}}* get_compartment( const long compartment_index ) const; + Compartment{{cm_unique_suffix}}* get_compartment( const long compartment_index, Compartment{{cm_unique_suffix}}* compartment, const long raise_flag ) const; + Compartment{{cm_unique_suffix}}* get_compartment_opt( const long compartment_indx ) const; + Compartment{{cm_unique_suffix}}* + get_root() const + { + return &root_; + }; + + // get tree size (number of compartments) + long + get_size() const + { + return size_; + }; + + // get voltage values + std::vector< double > get_voltage() const; + double get_compartment_voltage( const long compartment_index ); + + // construct the numerical integration matrix and vector + void construct_matrix( const long lag ); + // solve the matrix equation for next timestep voltage + void solve_matrix(); + + // print function + void print_tree() const; +}; // CompTree + +} // namespace + +#endif /* #ifndef CM_TREE_{{cm_unique_suffix | upper }}_H */ diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/AnalyticIntegrationStep_begin.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/AnalyticIntegrationStep_begin.jinja2 new file mode 100644 index 000000000..1e94b4dcf --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/AnalyticIntegrationStep_begin.jinja2 @@ -0,0 +1,10 @@ +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if uses_analytic_solver %} +{%- for variable_name in analytic_state_variables: %} +{%- set update_expr = update_expressions[variable_name] %} + double {{variable_name}}__tmp = {{printer.print_expression(update_expr)}}; +{%- endfor %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/AnalyticIntegrationStep_end.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/AnalyticIntegrationStep_end.jinja2 new file mode 100644 index 000000000..1cb559647 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/AnalyticIntegrationStep_end.jinja2 @@ -0,0 +1,11 @@ +{# + Generates a series of C++ statements which perform one integration step of all ODEs that are solved by the analytic integrator. +#} +/* replace analytically solvable variables with precisely integrated values */ +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if uses_analytic_solver %} +{%- for variable_name in analytic_state_variables: %} +{%- set variable_sym = analytic_variable_symbols[variable_name] %} +{{printer.print_origin(variable_sym)}}{{names.name(variable_sym)}} = {{variable_name}}__tmp; +{%- endfor %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/ApplySpikesFromBuffers.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ApplySpikesFromBuffers.jinja2 similarity index 99% rename from pynestml/codegeneration/resources_nest/directives/ApplySpikesFromBuffers.jinja2 rename to pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ApplySpikesFromBuffers.jinja2 index 45566934c..2ea939d33 100644 --- a/pynestml/codegeneration/resources_nest/directives/ApplySpikesFromBuffers.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ApplySpikesFromBuffers.jinja2 @@ -1,5 +1,4 @@ {% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} - {%- for ast in spike_updates %} {%- include "directives/Assignment.jinja2" %} {%- endfor %} diff --git a/pynestml/codegeneration/resources_nest/directives/Assignment.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Assignment.jinja2 similarity index 54% rename from pynestml/codegeneration/resources_nest/directives/Assignment.jinja2 rename to pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Assignment.jinja2 index 05a34efb7..a1840505b 100644 --- a/pynestml/codegeneration/resources_nest/directives/Assignment.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Assignment.jinja2 @@ -4,22 +4,21 @@ @param ast ASTAssignment #} {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} -{% set lhs_variable = assignments.lhs_variable(ast) -%} - +{%- set lhs_variable = assignments.lhs_variable(ast) %} {%- if lhs_variable is none %} {{ raise('Symbol with name "%s" could not be resolved' % ast.lhs.get_complete_name()) }} {%- endif %} - -{%- if assignments.is_vectorized_assignment(ast) -%} -for (long i=0; i < P_.{{assignments.print_size_parameter(ast)}}; i++) { - {%- if lhs_variable.has_vector_parameter() -%} - {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}}[i] - {%- else -%} - {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}} - {%- endif -%} +{%- if assignments.is_vectorized_assignment(ast) %} +for (long i=0; i < P_.{{assignments.print_size_parameter(ast)}}; i++) +{ +{%- if lhs_variable.has_vector_parameter() %} + {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}}[i] +{%- else %} + {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}} +{%- endif %} {{assignments.print_assignments_operation(ast)}} {{printer.print_expression(ast.get_expression())}}; } -{%- else -%} - {{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}} {{assignments.print_assignments_operation(ast)}} {{printer.print_expression(ast.get_expression())}}; -{%- endif -%} +{%- else %} +{{printer.print_origin(lhs_variable)}}{{names.name(lhs_variable)}} {{assignments.print_assignments_operation(ast)}} {{printer.print_expression(ast.get_expression())}}; +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Block.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Block.jinja2 new file mode 100644 index 000000000..d8dd993bf --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Block.jinja2 @@ -0,0 +1,13 @@ +{# + Handles a complex block statement + @grammar: Block = ( Stmt | NEWLINE )*; + @param ast ASTBlock +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- for statement in ast.get_stmts() %} +{%- filter indent(2) %} +{%- with stmt = statement %} +{%- include "directives/Statement.jinja2" %} +{%- endwith %} +{%- endfilter %} +{%- endfor %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/CompoundStatement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/CompoundStatement.jinja2 new file mode 100644 index 000000000..3705a62e1 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/CompoundStatement.jinja2 @@ -0,0 +1,18 @@ +{# + Handles the compound statement. + @grammar: Compound_Stmt = IF_Stmt | FOR_Stmt | WHILE_Stmt; +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if stmt.is_if_stmt() %} +{%- with ast = stmt.get_if_stmt() %} +{%- include "directives/IfStatement.jinja2" %} +{%- endwith %} +{%- elif stmt.is_for_stmt() %} +{%- with ast = stmt.get_for_stmt() %} +{%- include "directives/ForStatement.jinja2" %} +{%- endwith %} +{%- elif stmt.is_while_stmt() %} +{%- with ast = stmt.get_while_stmt() %} +{%- include "directives/WhileStatement.jinja2" %} +{%- endwith %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Declaration.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Declaration.jinja2 new file mode 100644 index 000000000..623376993 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Declaration.jinja2 @@ -0,0 +1,21 @@ +{# + Generates C++ declaration + @param ast ASTDeclaration +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- for variable in declarations.get_variables(ast) %} +{%- if ast.has_size_parameter() %} +{{declarations.print_variable_type(variable)}} {{variable.get_symbol_name()}}(P_.{{declarations.print_size_parameter(ast)}}); +{%- if ast.has_expression() %} +for (long i=0; i < get_{{declarations.print_size_parameter(ast)}}(); i++) { + {{variable.get_symbol_name()}}[i] = {{printer.print_expression(ast.getExpr())}}; +} +{%- endif %} +{%- else %} +{%- if ast.has_expression() %} +{{declarations.print_variable_type(variable)}} {{variable.get_symbol_name()}} = {{printer.print_expression(ast.get_expression())}}; +{%- else %} +{{declarations.print_variable_type(variable)}} {{variable.get_symbol_name()}}; +{%- endif %} +{%- endif %} +{%- endfor -%} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ForStatement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ForStatement.jinja2 new file mode 100644 index 000000000..e55a5761b --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ForStatement.jinja2 @@ -0,0 +1,13 @@ +{# + Generates C++ statements that implement for loop + @param ast ASTForStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +for( {{ast.get_variable()}} = {{printer.print_expression(ast.get_start_from())}}; + {{ast.get_variable()}} {{printer.print_comparison_operator(ast)}} {{printer.print_expression(ast.get_end_at())}}; + {{ast.get_variable()}} += {{ast.get_step()}} ) +{ +{%- with ast = ast.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/FunctionCall.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/FunctionCall.jinja2 new file mode 100644 index 000000000..96d6056c6 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/FunctionCall.jinja2 @@ -0,0 +1,15 @@ +{# + Generates C++ declaration + @param ast ASTFunctionCall +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if utils.is_integrate(ast) %} +{%- include "directives/AnalyticIntegrationStep_begin.jinja2" %} +{%- if uses_numeric_solver %} +{%- include "directives/GSLIntegrationStep.jinja2" %} +{%- endif %} +{%- include "directives/AnalyticIntegrationStep_end.jinja2" %} +{%- include "directives/ApplySpikesFromBuffers.jinja2" %} +{%- else %} +{{printer.print_method_call(ast, with_origin=False)}}; +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest/directives/GSLIntegrationStep.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/GSLIntegrationStep.jinja2 similarity index 92% rename from pynestml/codegeneration/resources_nest/directives/GSLIntegrationStep.jinja2 rename to pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/GSLIntegrationStep.jinja2 index bb1f53f3f..d4a836334 100644 --- a/pynestml/codegeneration/resources_nest/directives/GSLIntegrationStep.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/GSLIntegrationStep.jinja2 @@ -2,7 +2,7 @@ Generates a series of C++ statements which perform one integration step of all odes defined the neuron. #} -{% if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} __t = 0; // numerical integration with adaptive step size control: // ------------------------------------------------------ @@ -27,7 +27,8 @@ while ( __t < B_.__step ) &B_.__integration_step, // integration step size S_.ode_state); // neuronal state - if ( status != GSL_SUCCESS ) { + if ( status != GSL_SUCCESS ) + { throw nest::GSLSolverFailure( get_name(), status ); } } diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/IfStatement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/IfStatement.jinja2 new file mode 100644 index 000000000..23667c2c7 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/IfStatement.jinja2 @@ -0,0 +1,27 @@ +{# + Generates C++ declaration + @param ast ASTIfStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +if ({{printer.print_expression(ast.get_if_clause().get_condition())}}) +{ +{%- with ast = ast.get_if_clause().get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- for elif in ast.get_elif_clauses() %} +} +else if ({{printer.print_expression(elif.get_condition())}}) +{ +{%- with ast = elif.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endfor %} +{%- if ast.has_else_clause() %} +} +else +{ +{%- with ast = ast.get_else_clause().get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +{%- endif %} +} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ReturnStatement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ReturnStatement.jinja2 new file mode 100644 index 000000000..fc533a422 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/ReturnStatement.jinja2 @@ -0,0 +1,10 @@ +{# + Generates a single return statement in C++ syntax. + @param: ast A single ast-return stmt object. ASTReturnStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if ast.has_expression() %} +return {{printer.print_expression(ast.get_expression())}}; +{%- else %} +return; +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/SmallStatement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/SmallStatement.jinja2 new file mode 100644 index 000000000..f4eac1694 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/SmallStatement.jinja2 @@ -0,0 +1,22 @@ +{# + Generates a single small statement into equivalent C++ syntax. + @param stmt ASTSmallStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if stmt.is_assignment() %} +{%- with ast = stmt.get_assignment() %} +{%- include "directives/Assignment.jinja2" %} +{%- endwith %} +{%- elif stmt.is_function_call() %} +{%- with ast = stmt.get_function_call() %} +{%- include "directives/FunctionCall.jinja2" %} +{%- endwith %} +{%- elif stmt.is_declaration() %} +{%- with ast = stmt.get_declaration() %} +{%- include "directives/Declaration.jinja2" %} +{%- endwith %} +{%- elif stmt.is_return_stmt() %} +{%- with ast = stmt.get_return_stmt() %} +{%- include "directives/ReturnStatement.jinja2" %} +{%- endwith %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Statement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Statement.jinja2 new file mode 100644 index 000000000..4a1d3b13c --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/Statement.jinja2 @@ -0,0 +1,16 @@ +{# + Generates a single statement, either a simple or compound, to equivalent C++ syntax. + @param ast ASTSmallStmt or ASTCompoundStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +{%- if stmt.has_comment() %} +{{stmt.print_comment('//')}}{%- endif %} +{%- if stmt.is_small_stmt() %} +{%- with stmt = stmt.small_stmt %} +{%- include "directives/SmallStatement.jinja2" %} +{%- endwith %} +{%- elif stmt.is_compound_stmt() %} +{%- with stmt = stmt.compound_stmt %} +{%- include "directives/CompoundStatement.jinja2" %} +{%- endwith %} +{%- endif %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/WhileStatement.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/WhileStatement.jinja2 new file mode 100644 index 000000000..9414d9e1b --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/WhileStatement.jinja2 @@ -0,0 +1,11 @@ +{# + Generates C++ declaration + @param ast ASTWhileStmt +#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +while ( {{printer.print_expression(ast.get_condition())}}) +{ +{%- with ast = ast.get_block() %} +{%- include "directives/Block.jinja2" %} +{%- endwith %} +} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/__init__.py b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/__init__.py new file mode 100644 index 000000000..2f830f260 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/directives/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# +# __init__.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . diff --git a/pynestml/codegeneration/resources_nest/setup/CMakeLists.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/CMakeLists.txt.jinja2 similarity index 84% rename from pynestml/codegeneration/resources_nest/setup/CMakeLists.jinja2 rename to pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/CMakeLists.txt.jinja2 index 66f79e03e..62aa5dfbb 100644 --- a/pynestml/codegeneration/resources_nest/setup/CMakeLists.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/CMakeLists.txt.jinja2 @@ -1,5 +1,5 @@ -{# -# CMakeLists.jinja2 +# +# CMakeLists.txt.jinja2 # # This file is part of NEST. # @@ -37,8 +37,6 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -cmake_minimum_required( VERSION 2.8.12 ) - # This CMakeLists.txt is configured to build your external module for NEST. For # illustrative reasons this module is called 'my' (change SHORT_NAME to your # preferred module name). NEST requires you to extend the 'SLIModule' (see @@ -60,9 +58,16 @@ set( MODULE_NAME ${SHORT_NAME} ) # 2) Add all your sources here set( MODULE_SOURCES {{moduleName}}.h {{moduleName}}.cpp - {% for neuron in neurons %} - {{neuron.get_name()}}.cpp {{neuron.get_name()}}.h - {% endfor %} + {%- for neuron in neurons %} + {{perNeuronFileNamesCm[neuron.get_name()]["compartmentcurrents"]}}.cpp {{perNeuronFileNamesCm[neuron.get_name()]["compartmentcurrents"]}}.h + {{perNeuronFileNamesCm[neuron.get_name()]["main"]}}.cpp {{perNeuronFileNamesCm[neuron.get_name()]["main"]}}.h + {{perNeuronFileNamesCm[neuron.get_name()]["tree"]}}.cpp {{perNeuronFileNamesCm[neuron.get_name()]["tree"]}}.h + {% endfor -%} + + {# currently this will be empty as there are no shared files #} + {%- for cm_file_name in sharedFileNamesCmSyns.values() %} + {{cm_file_name}}.cpp {{cm_file_name}}.h + {% endfor -%} ) # 3) We require a header name like this: @@ -74,9 +79,6 @@ set( MODULE_VERSION_MAJOR 1 ) set( MODULE_VERSION_MINOR 0 ) set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}" ) -# 5) Leave the rest as is. All files in `sli` will be installed to -# `share/nest/sli/`, so that NEST will find the during initialization. - # Leave the call to "project(...)" for after the compiler is determined. # Set the `nest-config` executable to use during configuration. @@ -207,7 +209,7 @@ execute_process( # on OS X set( CMAKE_MACOSX_RPATH ON ) -# Install all stuff to NEST's install directories. +# Install all binaries to NEST's install directories. set( CMAKE_INSTALL_LIBDIR ${NEST_LIBDIR}/nest CACHE STRING "object code libraries (lib/nest or lib64/nest or lib//nest on Debian)" FORCE ) set( CMAKE_INSTALL_DOCDIR ${NEST_DOCDIR} CACHE STRING "documentation root (DATAROOTDIR/doc/nest)" FORCE ) set( CMAKE_INSTALL_DATADIR ${NEST_DATADIR} CACHE STRING "read-only architecture-independent data (DATAROOTDIR/nest)" FORCE ) @@ -282,38 +284,6 @@ set_target_properties( ${MODULE_NAME}_lib LINK_FLAGS "${NEST_LIBS}" OUTPUT_NAME ${MODULE_NAME} ) -# Install library, header and sli init files. -install( TARGETS ${MODULE_NAME}_lib DESTINATION ${CMAKE_INSTALL_LIBDIR} ) -install( FILES ${MODULE_HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -install( DIRECTORY sli DESTINATION ${CMAKE_INSTALL_DATADIR} ) - -# Install help. -if ( NOT CMAKE_CROSSCOMPILING ) - add_custom_target( generate_help ALL ) - # Extract help from all source files in the source code, put them in - # doc/help and generate a local help index in the build directory containing - # links to the help files. - add_custom_command( TARGET generate_help POST_BUILD - COMMAND python -B generate_help.py "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" - COMMAND python -B generate_helpindex.py "${PROJECT_BINARY_DIR}/doc" - WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}/${NEST_DATADIR}/help_generator" - COMMENT "Extracting help information; this may take a little while." - ) - # Copy the local doc/help directory to the global installation - # directory for documentation. - install( DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doc/help" - DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}" - ) - # Update the global help index to contain all help files that are - # located in the global installation directory for documentation. - install( CODE - "execute_process( - COMMAND python -B generate_helpindex.py \"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}\" - WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}/${NEST_DATADIR}/help_generator\" - )" - ) -endif () - message( "" ) message( "-------------------------------------------------------" ) message( "${MODULE_NAME} Configuration Summary" ) diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/ModuleClass.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/ModuleClass.cpp.jinja2 new file mode 100644 index 000000000..8c1dba6b0 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/ModuleClass.cpp.jinja2 @@ -0,0 +1,126 @@ +{#/* +* ModuleClass.cpp.jinja2 +* +* This file is part of NEST. +* +* Copyright (C) 2004 The NEST Initiative +* +* NEST is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* NEST is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NEST. If not, see . +* +*/#} +{%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} +/* +* {{moduleName}}.cpp +* +* This file is part of NEST. +* +* Copyright (C) 2004 The NEST Initiative +* +* NEST is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* NEST is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NEST. If not, see . +* +* {{now}} +*/ + +// Includes from nestkernel: +#include "connection_manager_impl.h" +#include "connector_model_impl.h" +#include "dynamicloader.h" +#include "exceptions.h" +#include "genericmodel_impl.h" +#include "kernel_manager.h" +#include "model.h" +#include "model_manager_impl.h" +#include "nestmodule.h" +#include "target_identifier.h" + +// Includes from sli: +#include "booldatum.h" +#include "integerdatum.h" +#include "sliexceptions.h" +#include "tokenarray.h" + +// include headers with your own stuff +#include "{{moduleName}}.h" + +{% for neuron in neurons %} +#include "{{perNeuronFileNamesCm[neuron.get_name()]["main"]}}.h" +{% endfor %} + +// -- Interface to dynamic module loader --------------------------------------- + +/* +* There are three scenarios, in which MyModule can be loaded by NEST: +* +* 1) When loading your module with `Install`, the dynamic module loader must +* be able to find your module. You make the module known to the loader by +* defining an instance of your module class in global scope. (LTX_MODULE is +* defined) This instance must have the name +* +* _LTX_mod +* +* The dynamicloader can then load modulename and search for symbol "mod" in it. +* +* 2) When you link the library dynamically with NEST during compilation, a new +* object has to be created. In the constructor the DynamicLoaderModule will +* register your module. (LINKED_MODULE is defined) +* +* 3) When you link the library statically with NEST during compilation, the +* registration will take place in the file `static_modules.h`, which is +* generated by cmake. +*/ +#if defined(LTX_MODULE) | defined(LINKED_MODULE) +{{moduleName}} {{moduleName}}_LTX_mod; +#endif + +// -- DynModule functions ------------------------------------------------------ + +{{moduleName}}::{{moduleName}}() +{ +#ifdef LINKED_MODULE + // register this module at the dynamic loader + // this is needed to allow for linking in this module at compile time + // all registered modules will be initialized by the main app's dynamic loader + nest::DynamicLoaderModule::registerLinkedModule( this ); +#endif +} + +{{moduleName}}::~{{moduleName}}() +{ +} + +const std::string +{{moduleName}}::name(void) const +{ + return std::string("{{moduleName}}"); // Return name of the module +} + +//------------------------------------------------------------------------------------- +void +{{moduleName}}::init( SLIInterpreter* i ) +{ + {% for neuron in neurons %} +nest::kernel().model_manager.register_node_model("{{perNeuronFileNamesCm[neuron.get_name()]["main"]}}"); + {% endfor %} +} // {{moduleName}}::init() \ No newline at end of file diff --git a/pynestml/codegeneration/resources_nest/ModuleHeader.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/ModuleHeader.h.jinja2 similarity index 88% rename from pynestml/codegeneration/resources_nest/ModuleHeader.jinja2 rename to pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/ModuleHeader.h.jinja2 index 0de517787..e5f6eaa02 100644 --- a/pynestml/codegeneration/resources_nest/ModuleHeader.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/ModuleHeader.h.jinja2 @@ -1,5 +1,5 @@ {# - * ModuleHeader.jinja2 + * ModuleHeader.h.jinja2 * * This file is part of NEST. * @@ -81,13 +81,6 @@ public: */ const std::string name( void ) const; - /** - * Return the name of a sli file to execute when {{moduleName}} is loaded. - * This mechanism can be used to define SLI commands associated with your - * module, in particular, set up type tries for functions you have defined. - */ - const std::string commandstring( void ) const; - public: // Classes implementing your functions ----------------------------- diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/__init__.py b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/__init__.py new file mode 100644 index 000000000..2f830f260 --- /dev/null +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/setup/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# +# __init__.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . diff --git a/pynestml/exceptions/__init__.py b/pynestml/exceptions/__init__.py index c91773794..5cfdc0a01 100644 --- a/pynestml/exceptions/__init__.py +++ b/pynestml/exceptions/__init__.py @@ -19,4 +19,4 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -all = ['deferred_logging_exception', 'implicit_cast_exception', 'implicit_magnitude_cast_exception'] +__all__ = ['generated_code_build_exception', 'implicit_cast_exception', 'implicit_magnitude_cast_exception', 'invalid_path_exception', 'invalid_target_exception'] diff --git a/pynestml/exceptions/code_generator_options_exception.py b/pynestml/exceptions/code_generator_options_exception.py new file mode 100644 index 000000000..376f02abe --- /dev/null +++ b/pynestml/exceptions/code_generator_options_exception.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# +# code_generator_options_exception.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + + +class CodeGeneratorOptionsException(Exception): + r""" + This exception is thrown whenever a non-existing option is passed to the code generator (or builder). + """ + pass diff --git a/pynestml/exceptions/deferred_logging_exception.py b/pynestml/exceptions/generated_code_build_exception.py similarity index 69% rename from pynestml/exceptions/deferred_logging_exception.py rename to pynestml/exceptions/generated_code_build_exception.py index 4d85e42ec..c847b35ce 100644 --- a/pynestml/exceptions/deferred_logging_exception.py +++ b/pynestml/exceptions/generated_code_build_exception.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# deferred_logging_exception.py +# generated_code_build_exception.py # # This file is part of NEST. # @@ -20,12 +20,8 @@ # along with NEST. If not, see . -class DeferredLoggingException(Exception): +class GeneratedCodeBuildException(Exception): """ - Exception holding code and message of a logging operation. - Used to defer logging until source position (or other data) can be determined + This exception is thrown whenever a failure occurs while building or installing the generated code for the target platform. """ - - def __init__(self, code, message): - self.code = code - self.message = message + pass diff --git a/pynestml/frontend/frontend_configuration.py b/pynestml/frontend/frontend_configuration.py index 66c7d49f4..a57d18ded 100644 --- a/pynestml/frontend/frontend_configuration.py +++ b/pynestml/frontend/frontend_configuration.py @@ -18,7 +18,11 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -import argparse # used for parsing of input arguments + +from typing import Any, Mapping, Optional, Sequence + +import argparse +import glob import os import re @@ -29,39 +33,48 @@ from pynestml.utils.logger import LoggingLevel from pynestml.utils.messages import Messages, MessageCode -help_input_path = 'Path to a single file or a directory containing the source models.' -help_target_path = 'Path to a target directory where models should be generated to. Standard is "target".' +help_input_path = 'One or more input path(s). Each path is a NESTML file, or a directory containing NESTML files. Directories will be searched recursively for files matching \'*.nestml\'.' +help_target_path = 'Path to a directory where generated code should be written to. Standard is "target".' +help_install_path = 'Path to the directory where the generated code will be installed.' help_target = 'Name of the target platform to build code for. Default is NEST.' help_logging = 'Indicates which messages shall be logged and printed to the screen. Standard is ERROR.' help_module = 'Indicates the name of the module. Optional. If not indicated, the name of the directory containing the models is used' help_log = 'Indicates whether a log file containing all messages shall be stored. Standard is NO.' help_suffix = 'A suffix string that will be appended to the name of all generated models.' help_dev = 'Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code.' +help_codegen_opts = 'Path to a JSON file containing additional options for the target platform code generator.' qualifier_input_path_arg = '--input_path' qualifier_target_path_arg = '--target_path' -qualifier_target_arg = '--target' +qualifier_install_path_arg = '--install_path' +qualifier_target_platform_arg = '--target_platform' qualifier_logging_level_arg = '--logging_level' qualifier_module_name_arg = '--module_name' qualifier_store_log_arg = '--store_log' qualifier_suffix_arg = '--suffix' qualifier_dev_arg = '--dev' +qualifier_codegen_opts_arg = '--codegen_opts' -class FrontendConfiguration(object): +class FrontendConfiguration: """ This class encapsulates all settings as handed over to the frontend at start of the toolchain. """ argument_parser = None paths_to_compilation_units = None - provided_path = None + provided_input_path = None logging_level = None target = None + install_path = None target_path = None + target_platform = None module_name = None store_log = False suffix = '' is_dev = False + codegen_opts = {} # type: Mapping[str, Any] + codegen_opts_fn = '' + compartmental_variable_name = "v_comp" @classmethod def parse_config(cls, args): @@ -70,6 +83,8 @@ def parse_config(cls, args): :param args: a set of arguments as handed over to the frontend :type args: list(str) """ + from pynestml.frontend.pynestml_frontend import get_known_targets + cls.argument_parser = argparse.ArgumentParser( description='''NESTML is a domain specific language that supports the specification of neuron models in a precise and concise syntax, based on the syntax of Python. Model @@ -80,64 +95,53 @@ def parse_config(cls, args): Version ''' + str(pynestml.__version__), formatter_class=argparse.RawDescriptionHelpFormatter) - cls.argument_parser.add_argument(qualifier_input_path_arg, metavar='PATH', + cls.argument_parser.add_argument(qualifier_input_path_arg, metavar='PATH', nargs='+', type=str, help=help_input_path, required=True) cls.argument_parser.add_argument(qualifier_target_path_arg, metavar='PATH', type=str, help=help_target_path) - cls.argument_parser.add_argument(qualifier_target_arg, choices=[ - 'NEST', 'autodoc', 'none'], type=str, help=help_target, default='NEST') + cls.argument_parser.add_argument(qualifier_install_path_arg, metavar='PATH', type=str, help=help_install_path) + cls.argument_parser.add_argument(qualifier_target_platform_arg, choices=get_known_targets(), type=str.upper, help=help_target, default='NEST') cls.argument_parser.add_argument(qualifier_logging_level_arg, metavar='{DEBUG, INFO, WARNING, ERROR, NONE}', choices=[ 'DEBUG', 'INFO', 'WARNING', 'WARNINGS', 'ERROR', 'ERRORS', 'NONE', 'NO'], type=str, help=help_logging, default='ERROR') cls.argument_parser.add_argument(qualifier_module_name_arg, metavar='NAME', type=str, help=help_module) cls.argument_parser.add_argument(qualifier_store_log_arg, action='store_true', help=help_log) cls.argument_parser.add_argument(qualifier_suffix_arg, metavar='SUFFIX', type=str, help=help_suffix, default='') cls.argument_parser.add_argument(qualifier_dev_arg, action='store_true', help=help_dev) + cls.argument_parser.add_argument(qualifier_codegen_opts_arg, metavar='PATH', type=str, help=help_codegen_opts, default='', dest='codegen_opts_fn') parsed_args = cls.argument_parser.parse_args(args) # initialize the logger - cls.logging_level = parsed_args.logging_level + cls.logging_level = Logger.level_to_string(Logger.string_to_level(parsed_args.logging_level)) Logger.init_logger(Logger.string_to_level(parsed_args.logging_level)) cls.handle_input_path(parsed_args.input_path) - cls.handle_target(parsed_args.target) + cls.handle_target_platform(parsed_args.target_platform) cls.handle_target_path(parsed_args.target_path) - - # parse or compose the module name - if parsed_args.module_name is not None: - if not parsed_args.module_name.endswith('module'): - raise Exception('Invalid module name specified ("' + parsed_args.module_name - + '"): the module name should end with the word "module"') - if not re.match(r'[a-zA-Z_][a-zA-Z0-9_]*\Z', parsed_args.module_name): - raise Exception('The specified module name ("' + parsed_args.module_name - + '") cannot be parsed as a C variable name') - cls.module_name = parsed_args.module_name - elif os.path.isfile(parsed_args.input_path): - cls.module_name = 'nestmlmodule' - Logger.log_message(code=MessageCode.MODULE_NAME_INFO, message='No module name specified; the generated module will be named "' - + cls.module_name + '"', log_level=LoggingLevel.INFO) - elif os.path.isdir(parsed_args.input_path): - cls.module_name = os.path.basename(os.path.normpath(parsed_args.input_path)) - if not re.match(r'[a-zA-Z_][a-zA-Z0-9_]*\Z', cls.module_name): - raise Exception('No module name specified; tried to use the input directory name ("' - + cls.module_name + '"), but it cannot be parsed as a C variable name') - if not cls.module_name.endswith('module'): - cls.module_name += 'module' - Logger.log_message(code=MessageCode.MODULE_NAME_INFO, message='No module name specified; the generated module will be named "' - + cls.module_name + '"', log_level=LoggingLevel.INFO) - else: - assert False # input_path should be either a file or a directory; failure should have been caught already by handle_input_path() + cls.handle_install_path(parsed_args.install_path) + cls.handle_module_name(parsed_args.module_name) + cls.handle_codegen_opts_fn(parsed_args.codegen_opts_fn) cls.store_log = parsed_args.store_log cls.suffix = parsed_args.suffix cls.is_dev = parsed_args.dev @classmethod - def get_path(cls): + def target_is_compartmental(cls): + if cls.get_target_platform() is None: + return False + + return cls.get_target_platform().upper() == 'NEST_COMPARTMENTAL' + + @classmethod + def getCompartmentalVariableName(cls): + return cls.compartmental_variable_name + + @classmethod + def get_provided_input_path(cls) -> Sequence[str]: """ - Returns the path to the handed over directory or file. - :return: a single path - :rtype: str + Returns the list of file and directory names as supplied by the user. + :return: a list of file and directory names """ - return cls.provided_path + return cls.provided_input_path @classmethod def get_files(cls): @@ -149,13 +153,13 @@ def get_files(cls): return cls.paths_to_compilation_units @classmethod - def get_target(cls): + def get_target_platform(cls): """ Get the name of the target platform. :return: None or "" in case no code needs to be generated :rtype: str """ - return cls.target + return cls.target_platform @classmethod def get_logging_level(cls): @@ -167,14 +171,21 @@ def get_logging_level(cls): return cls.logging_level @classmethod - def get_target_path(cls): + def get_target_path(cls) -> str: """ Returns the path to which models shall be generated to. :return: the target path. - :rtype: str """ return cls.target_path + @classmethod + def get_install_path(cls) -> str: + """ + Path to the directory where the generated code will be installed. + :return: the install path. + """ + return cls.install_path + @classmethod def get_module_name(cls): """ @@ -185,7 +196,7 @@ def get_module_name(cls): return cls.module_name @classmethod - def is_dev(cls): + def get_is_dev(cls): """ Returns whether the development mode has been enabled. :return: True if development mode is enabled, otherwise False. @@ -194,22 +205,66 @@ def is_dev(cls): return cls.is_dev @classmethod - def handle_target(cls, target): - if target is None or target.upper() == 'NONE': - target = '' # make sure `target` is always a string + def get_codegen_opts(cls): + """Get the code generator options dictionary""" + return cls.codegen_opts + + @classmethod + def set_codegen_opts(cls, codegen_opts): + """Set the code generator options dictionary""" + cls.codegen_opts = codegen_opts + + @classmethod + def handle_codegen_opts_fn(cls, codegen_opts_fn): + """If a filename of a JSON file containing code generator options is passed on the command line, read it into a Python dictionary""" + if codegen_opts_fn and not os.path.isfile(codegen_opts_fn): + raise Exception('The specified code generator options file ("' + codegen_opts_fn + '") cannot be found') + cls.codegen_opts_fn = codegen_opts_fn + cls.codegen_opts = {} + if cls.codegen_opts_fn: + # load optional code generator options from JSON + import json + if FrontendConfiguration.codegen_opts_fn: + with open(FrontendConfiguration.codegen_opts_fn) as json_file: + cls.codegen_opts = json.load(json_file) + Logger.log_message(message='Loaded code generator options from file: ' + FrontendConfiguration.codegen_opts_fn, + log_level=LoggingLevel.INFO) + if not cls.codegen_opts: + raise Exception('Errors occurred while processing code generator options file') + + @classmethod + def handle_module_name(cls, module_name): + """parse or compose the module name""" + if module_name is not None: + if not module_name.endswith('module'): + raise Exception('Invalid module name specified ("' + module_name + + '"): the module name should end with the word "module"') + if not re.match(r'[a-zA-Z_][a-zA-Z0-9_]*\Z', module_name): + raise Exception('The specified module name ("' + module_name + + '") cannot be parsed as a C variable name') + cls.module_name = module_name + else: + cls.module_name = 'nestmlmodule' + Logger.log_message(code=MessageCode.MODULE_NAME_INFO, message='No module name specified; the generated module will be named "' + + cls.module_name + '"', log_level=LoggingLevel.INFO) + + @classmethod + def handle_target_platform(cls, target_platform: Optional[str]): + if target_platform is None or target_platform.upper() == 'NONE': + target_platform = '' # make sure `target_platform` is always a string - from pynestml.codegeneration.codegenerator import CodeGenerator + from pynestml.frontend.pynestml_frontend import get_known_targets - if target.upper() not in CodeGenerator.get_known_targets(): - code, message = Messages.get_unknown_target(target) + if target_platform.upper() not in get_known_targets(): + code, message = Messages.get_unknown_target_platform(target_platform) Logger.log_message(None, code, message, None, LoggingLevel.ERROR) raise InvalidTargetException() - cls.target = target + cls.target_platform = target_platform @classmethod def handle_target_path(cls, path): - # check if a target has been selected, otherwise set to `[pynestml directory]/target` + r"""check if a target has been selected, otherwise set to `[pynestml directory]/target`""" if path is not None: if os.path.isabs(path): cls.target_path = path @@ -226,27 +281,60 @@ def handle_target_path(cls, path): os.makedirs(cls.target_path) @classmethod - def handle_input_path(cls, path): - if path is None or path == '': - # check if the mandatory path arg has been handed over, just terminate - raise InvalidPathException('No input path specified.') + def handle_install_path(cls, path): + if path is None: + return - cls.paths_to_compilation_units = list() if os.path.isabs(path): - cls.provided_path = path + cls.install_path = path else: - # a relative path, reconstruct it. get the parent dir where models, pynestml etc. is located - pynestml_dir = os.getcwd() - cls.provided_path = os.path.join(pynestml_dir, path) - - if os.path.isfile(cls.provided_path): - cls.paths_to_compilation_units.append(cls.provided_path) - elif os.path.isdir(cls.provided_path): - for filename in os.listdir(cls.provided_path): - if filename.endswith('.nestml'): - cls.paths_to_compilation_units.append(os.path.join(cls.provided_path, filename)) - else: - # input_path should be either a file or a directory - code, message = Messages.get_input_path_not_found(path=cls.provided_path) + cls.install_path = os.path.abspath(path) + + # check if the installation path exists + if not os.path.isdir(path): + raise InvalidPathException("Installation path \"" + str(path) + "\" not found.") + + @classmethod + def handle_input_path(cls, path) -> None: + """ + Sets cls.paths_to_compilation_units with a list of absolute paths to NESTML files. + + Use glob to search directories recursively. + """ + cls.provided_input_path = path + + if not path or path == ['']: + # mandatory path arg has not been handed over + code, message = Messages.get_input_path_not_found(path="") + Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR) + raise InvalidPathException(message) + + if type(path) is str: + path = [path] + + cls.paths_to_compilation_units = list() + for _path in path: + if not os.path.isabs(_path): + # turn relative to absolute path + pynestml_dir = os.getcwd() + _path = os.path.join(pynestml_dir, _path) + + if os.path.isfile(_path): + cls.paths_to_compilation_units.append(_path) + elif os.path.isdir(_path): + for fn in glob.glob(os.path.join(_path, "**", "*.nestml"), recursive=True): + cls.paths_to_compilation_units.append(os.path.join(_path, fn)) + else: + # input_path should be either a file or a directory + code, message = Messages.get_input_path_not_found(path=_path) + Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR) + raise InvalidPathException(message) + + if not cls.paths_to_compilation_units: + code, message = Messages.get_no_files_in_input_path(" ".join(path)) Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR) - raise Exception(message) + raise InvalidPathException(message) + + Logger.log_message(message="List of files that will be processed:", log_level=LoggingLevel.INFO) + for fn in cls.paths_to_compilation_units: + Logger.log_message(message=fn, log_level=LoggingLevel.INFO) diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index 9513446e5..8720c2bf9 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -19,58 +19,152 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple, Union + import os import sys from pynestml.cocos.co_cos_manager import CoCosManager -from pynestml.codegeneration.codegenerator import CodeGenerator +from pynestml.codegeneration.builder import Builder +from pynestml.codegeneration.code_generator import CodeGenerator +from pynestml.exceptions.code_generator_options_exception import CodeGeneratorOptionsException from pynestml.frontend.frontend_configuration import FrontendConfiguration, InvalidPathException, \ qualifier_store_log_arg, qualifier_module_name_arg, qualifier_logging_level_arg, \ - qualifier_target_arg, qualifier_target_path_arg, qualifier_input_path_arg, qualifier_suffix_arg, qualifier_dev_arg + qualifier_target_platform_arg, qualifier_target_path_arg, qualifier_input_path_arg, qualifier_suffix_arg, \ + qualifier_dev_arg, qualifier_codegen_opts_arg, qualifier_install_path_arg +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.predefined_units import PredefinedUnits from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.transformers.transformer import Transformer from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages from pynestml.utils.model_parser import ModelParser -from pynestml.utils.model_installer import install_nest as nest_installer -def to_nest(input_path, target_path=None, logging_level='ERROR', - module_name=None, store_log=False, suffix="", dev=False): - '''Translate NESTML files into their equivalent C++ code for the NEST simulator. +def get_known_targets(): + targets = ["NEST", "NEST_compartmental", "autodoc", "none"] + targets = [s.upper() for s in targets] + return targets + + +def transformers_from_target_name(target_name: str, options: Optional[Mapping[str, Any]] = None) -> Tuple[Transformer, Dict[str, Any]]: + """Static factory method that returns a list of new instances of a child class of Transformers""" + assert target_name.upper() in get_known_targets( + ), "Unknown target platform requested: \"" + str(target_name) + "\"" + + # default: no transformers (empty list); options unchanged + transformers: List[Transformer] = [] + if options is None: + options = {} + + if target_name.upper() == "NEST": + from pynestml.transformers.illegal_variable_name_transformer import IllegalVariableNameTransformer + from pynestml.transformers.synapse_post_neuron_transformer import SynapsePostNeuronTransformer + + # rewrite all C++ keywords + # from: https://docs.microsoft.com/en-us/cpp/cpp/keywords-cpp 2022-04-23 + variable_name_rewriter = IllegalVariableNameTransformer({"forbidden_names": ["alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t", "class", "compl", "concept", "const", "const_cast", "consteval", "constexpr", "constinit", "continue", "co_await", "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", + "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "requires", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"]}) + transformers.append(variable_name_rewriter) + + # co-generate neuron and synapse + synapse_post_neuron_co_generation = SynapsePostNeuronTransformer() + options = synapse_post_neuron_co_generation.set_options(options) + transformers.append(synapse_post_neuron_co_generation) + + return transformers, options + + +def code_generator_from_target_name(target_name: str, options: Optional[Mapping[str, Any]] = None) -> CodeGenerator: + """Static factory method that returns a new instance of a child class of CodeGenerator""" + assert target_name.upper() in get_known_targets( + ), "Unknown target platform requested: \"" + str(target_name) + "\"" + + if target_name.upper() == "NEST": + from pynestml.codegeneration.nest_code_generator import NESTCodeGenerator + return NESTCodeGenerator(options) + + if target_name.upper() == "AUTODOC": + from pynestml.codegeneration.autodoc_code_generator import AutoDocCodeGenerator + assert options is None or options == { + }, "\"autodoc\" code generator does not support options" + return AutoDocCodeGenerator() + + if target_name.upper() == "NEST_COMPARTMENTAL": + from pynestml.codegeneration.nest_compartmental_code_generator import NESTCompartmentalCodeGenerator + return NESTCompartmentalCodeGenerator() + + if target_name.upper() == "NONE": + # dummy/null target: user requested to not generate any code + code, message = Messages.get_no_code_generated() + Logger.log_message(None, code, message, None, LoggingLevel.INFO) + return CodeGenerator("", options) + + # cannot reach here due to earlier assert -- silence + assert "Unknown code generator requested: " + target_name + # static checker warnings + + +def builder_from_target_name(target_name: str, options: Optional[Mapping[str, Any]] = None) -> Builder: + r"""Static factory method that returns a new instance of a child class of Builder""" + from pynestml.frontend.pynestml_frontend import get_known_targets + + assert target_name.upper() in get_known_targets( + ), "Unknown target platform requested: \"" + str(target_name) + "\"" + + if target_name.upper() in ["NEST", "NEST_COMPARTMENTAL"]: + from pynestml.codegeneration.nest_builder import NESTBuilder + return NESTBuilder(options) + + return None # no builder requested or available + + +def generate_target(input_path: Union[str, Sequence[str]], target_platform: str, target_path=None, + install_path: str = None, logging_level="ERROR", module_name=None, store_log=False, suffix="", + dev=False, codegen_opts: Optional[Mapping[str, Any]] = None): + r"""Generate and build code for the given target platform. Parameters ---------- - input_path : str - Path to the NESTML file or to a folder containing NESTML files to convert to NEST code. + input_path : str **or** Sequence[str] + One or more input path(s). Each path is a NESTML file, or a directory containing NESTML files. Directories will be searched recursively for files matching ``*.nestml``. + target_platform : str + The name of the target platform to generate code for. target_path : str, optional (default: append "target" to `input_path`) - Path to the generated C++ code and install files. - logging_level : str, optional (default: 'ERROR') - Sets which level of information should be displayed duing code generation (among 'ERROR', 'WARNING', 'INFO', or 'NO'). + Path to target directory where generated code will be written into. Default is ``target``, which will be created in the current working directory if it does not yet exist. + logging_level : str, optional (default: "ERROR") + Sets the logging level, i.e., which level of messages should be printed. Default is ERROR, available are: DEBUG, INFO, WARNING, ERROR, NO. module_name : str, optional (default: "nestmlmodule") - Name of the module, which will be used to import the model in NEST via `nest.Install(module_name)`. + Sets the name of the module which shall be generated. Default is the name of the directory containing the models. The name has to end in ``module``. Default is ``nestmlmodule``. store_log : bool, optional (default: False) - Whether the log should be saved to file. + Stores a log.txt containing all messages in JSON notation. Default is OFF. suffix : str, optional (default: "") - Suffix which will be appended to the model's name (internal use to avoid naming conflicts with existing NEST models). + A suffix string that will be appended to the name of all generated models. + install_path + Path to the directory where the generated code will be installed. dev : bool, optional (default: False) Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code. - ''' - # if target_path is not None and not os.path.isabs(target_path): - # print('PyNestML: Please provide absolute target path!') - # return + codegen_opts : Optional[Mapping[str, Any]] + A dictionary containing additional options for the target code generator. + """ args = list() args.append(qualifier_input_path_arg) - args.append(str(input_path)) + if type(input_path) is str: + args.append(str(input_path)) + else: + for s in input_path: + args.append(s) if target_path is not None: args.append(qualifier_target_path_arg) args.append(str(target_path)) - args.append(qualifier_target_arg) - args.append(str("NEST")) + args.append(qualifier_target_platform_arg) + args.append(target_platform) + args.append(qualifier_logging_level_arg) args.append(str(logging_level)) @@ -85,43 +179,97 @@ def to_nest(input_path, target_path=None, logging_level='ERROR', args.append(qualifier_suffix_arg) args.append(suffix) + if install_path is not None: + args.append(qualifier_install_path_arg) + args.append(str(install_path)) + if dev: args.append(qualifier_dev_arg) FrontendConfiguration.parse_config(args) + + if codegen_opts: + FrontendConfiguration.set_codegen_opts(codegen_opts) + if not process() == 0: raise Exception("Error(s) occurred while processing the model") -def install_nest(models_path, nest_path): - # type: (str,str) -> None - ''' - This procedure can be used to install generated models into the NEST - simulator. +def generate_nest_target(input_path: Union[str, Sequence[str]], target_path: Optional[str] = None, + install_path: Optional[str] = None, logging_level="ERROR", + module_name=None, store_log: bool = False, suffix: str = "", + dev: bool = False, codegen_opts: Optional[Mapping[str, Any]] = None): + r"""Generate and build code for NEST Simulator. Parameters ---------- - models_path : str - Path to the generated models, which should contain the - (automatically generated) CMake file. - nest_path : str - Path to the NEST installation, which should point to the main directory - where NEST is installed. This folder contains the bin/, lib(64)/, - include/, and share/ folders of the NEST install. Most importantly, the - bin/ folder should contain the "nest-config" script. This path is - passed through the -Dwith-nest argument of the CMake command during the - installation of the generated NEST module. The suffix /bin/nest-config - will be automatically attached to `nest_path`. - ''' - nest_installer(models_path, nest_path) - - -def main(): - """Returns the process exit code: 0 for success, > 0 for failure""" + input_path : str **or** Sequence[str] + Path to the NESTML file(s) or to folder(s) containing NESTML files to convert to NEST code. + target_path : str, optional (default: append "target" to `input_path`) + Path to the generated C++ code and install files. + logging_level : str, optional (default: "ERROR") + Sets which level of information should be displayed duing code generation (among "ERROR", "WARNING", "INFO", or "NO"). + module_name : str, optional (default: "nestmlmodule") + Name of the module, which will be used to import the model in NEST via `nest.Install(module_name)`. + store_log : bool, optional (default: False) + Whether the log should be saved to file. + suffix : str, optional (default: "") + A suffix string that will be appended to the name of all generated models. + install_path + Path to the directory where the generated NEST extension module will be installed into. If the parameter is not specified, the module will be installed into the NEST Simulator installation directory, as reported by nest-config. + dev : bool, optional (default: False) + Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code. + codegen_opts : Optional[Mapping[str, Any]] + A dictionary containing additional options for the target code generator. + """ + generate_target(input_path, target_platform="NEST", target_path=target_path, logging_level=logging_level, + module_name=module_name, store_log=store_log, suffix=suffix, install_path=install_path, + dev=dev, codegen_opts=codegen_opts) + + +def generate_nest_compartmental_target(input_path: Union[str, Sequence[str]], target_path: Optional[str] = None, + install_path: Optional[str] = None, logging_level="ERROR", + module_name=None, store_log: bool = False, suffix: str = "", + dev: bool = False, codegen_opts: Optional[Mapping[str, Any]] = None): + r"""Generate and build compartmental model code for NEST Simulator. + + Parameters + ---------- + input_path : str **or** Sequence[str] + Path to the NESTML file(s) or to folder(s) containing NESTML files to convert to NEST code. + target_path : str, optional (default: append "target" to `input_path`) + Path to the generated C++ code and install files. + logging_level : str, optional (default: "ERROR") + Sets which level of information should be displayed duing code generation (among "ERROR", "WARNING", "INFO", or "NO"). + module_name : str, optional (default: "nestmlmodule") + Name of the module, which will be used to import the model in NEST via `nest.Install(module_name)`. + store_log : bool, optional (default: False) + Whether the log should be saved to file. + suffix : str, optional (default: "") + A suffix string that will be appended to the name of all generated models. + install_path + Path to the directory where the generated NEST extension module will be installed into. If the parameter is not specified, the module will be installed into the NEST Simulator installation directory, as reported by nest-config. + dev : bool, optional (default: False) + Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code. + codegen_opts : Optional[Mapping[str, Any]] + A dictionary containing additional options for the target code generator. + """ + generate_target(input_path, target_platform="NEST_compartmental", target_path=target_path, + logging_level=logging_level, module_name=module_name, store_log=store_log, + suffix=suffix, install_path=install_path, dev=dev, codegen_opts=codegen_opts) + + +def main() -> int: + """ + Entry point for the command-line application. + + Returns + ------- + The process exit code: 0 for success, > 0 for failure + """ try: FrontendConfiguration.parse_config(sys.argv[1:]) - except InvalidPathException: - print('Not a valid path to model or directory: "%s"!' % FrontendConfiguration.get_path()) + except InvalidPathException as e: return 1 # the default Python recursion limit is 1000, which might not be enough in practice when running an AST visitor on a deep tree, e.g. containing an automatically generated expression sys.setrecursionlimit(10000) @@ -130,7 +278,9 @@ def main(): def process(): - """ + r""" + The main toolchain workflow entry point. For all models: parse, validate, transform, generate code and build. + Returns ------- errors_occurred : bool @@ -141,43 +291,81 @@ def process(): # init log dir create_report_dir() + # The handed over parameters seem to be correct, proceed with the main routine init_predefined() + # now proceed to parse all models compilation_units = list() nestml_files = FrontendConfiguration.get_files() + if not type(nestml_files) is list: nestml_files = [nestml_files] + for nestml_file in nestml_files: parsed_unit = ModelParser.parse_model(nestml_file) if parsed_unit is not None: compilation_units.append(parsed_unit) + + # initialize and set options for transformers, code generator and builder + codegen_and_builder_opts = FrontendConfiguration.get_codegen_opts() + transformers, codegen_and_builder_opts = transformers_from_target_name(FrontendConfiguration.get_target_platform(), + options=codegen_and_builder_opts) + _codeGenerator = code_generator_from_target_name( + FrontendConfiguration.get_target_platform()) + codegen_and_builder_opts = _codeGenerator.set_options( + codegen_and_builder_opts) + _builder = builder_from_target_name( + FrontendConfiguration.get_target_platform()) + + if _builder is not None: + codegen_and_builder_opts = _builder.set_options( + codegen_and_builder_opts) + + if len(codegen_and_builder_opts) > 0: + raise CodeGeneratorOptionsException( + "The code generator option(s) \"" + ", ".join(codegen_and_builder_opts.keys()) + "\" do not exist.") + if len(compilation_units) > 0: - # generate a list of all neurons - neurons = list() + # generate a list of all neurons + synapses + models: Sequence[Union[ASTNeuron, ASTSynapse]] = [] for compilationUnit in compilation_units: - neurons.extend(compilationUnit.get_neuron_list()) - # check if across two files two neurons with same name have been defined - CoCosManager.check_not_two_neurons_across_units(compilation_units) + models.extend(compilationUnit.get_neuron_list()) + models.extend(compilationUnit.get_synapse_list()) + + # check that no models with duplicate names have been defined + CoCosManager.check_no_duplicate_compilation_unit_names(models) + # now exclude those which are broken, i.e. have errors. if not FrontendConfiguration.is_dev: - for neuron in neurons: - if Logger.has_errors(neuron): - code, message = Messages.get_neuron_contains_errors(neuron.get_name()) - Logger.log_message(node=neuron, code=code, message=message, - error_position=neuron.get_source_position(), - log_level=LoggingLevel.INFO) - neurons.remove(neuron) + for model in models: + if Logger.has_errors(model): + code, message = Messages.get_model_contains_errors( + model.get_name()) + Logger.log_message(node=model, code=code, message=message, + error_position=model.get_source_position(), + log_level=LoggingLevel.WARNING) + models.remove(model) errors_occurred = True + + # run transformers + for transformer in transformers: + models = transformer.transform(models) + # perform code generation - _codeGenerator = CodeGenerator(target=FrontendConfiguration.get_target()) - _codeGenerator.generate_code(neurons) - for neuron in neurons: - if Logger.has_errors(neuron): + _codeGenerator.generate_code(models) + for model in models: + if Logger.has_errors(model): errors_occurred = True break + + # perform build + if not errors_occurred and _builder is not None: + _builder.build() + if FrontendConfiguration.store_log: store_log_to_file() + return errors_occurred @@ -190,11 +378,12 @@ def init_predefined(): def create_report_dir(): - if not os.path.isdir(os.path.join(FrontendConfiguration.get_target_path(), '..', 'report')): - os.makedirs(os.path.join(FrontendConfiguration.get_target_path(), '..', 'report')) + if not os.path.isdir(os.path.join(FrontendConfiguration.get_target_path(), os.pardir, "report")): + os.makedirs(os.path.join(FrontendConfiguration.get_target_path(), os.pardir, "report")) + FrontendConfiguration.get_target_path(), "..", "report")) def store_log_to_file(): - with open(str(os.path.join(FrontendConfiguration.get_target_path(), '..', 'report', - 'log')) + '.txt', 'w+') as f: + with open(str(os.path.join(FrontendConfiguration.get_target_path(), os.pardir, "report", + "log")) + ".txt", "w+") as f: f.write(str(Logger.get_json_format())) diff --git a/pynestml/generated/PyNestMLLexer.interp b/pynestml/generated/PyNestMLLexer.interp deleted file mode 100644 index dd63b1864..000000000 --- a/pynestml/generated/PyNestMLLexer.interp +++ /dev/null @@ -1,270 +0,0 @@ -token literal names: -null -null -null -null -null -null -'end' -'integer' -'real' -'string' -'boolean' -'void' -'function' -'inline' -'return' -'if' -'elif' -'else' -'for' -'while' -'in' -'step' -'inf' -'and' -'or' -'not' -'recordable' -'kernel' -'neuron' -'state' -'parameters' -'internals' -'initial_values' -'update' -'equations' -'input' -'output' -'current' -'spike' -'inhibitory' -'excitatory' -'...' -'(' -')' -'+' -'~' -'|' -'^' -'&' -'[' -'<-' -']' -'[[' -']]' -'<<' -'>>' -'<' -'>' -'<=' -'+=' -'-=' -'*=' -'/=' -'==' -'!=' -'<>' -'>=' -',' -'-' -'=' -'*' -'**' -'/' -'%' -'?' -':' -';' -'\'' -null -null -null -null -null - -token symbolic names: -null -SL_COMMENT -ML_COMMENT -NEWLINE -WS -LINE_ESCAPE -END_KEYWORD -INTEGER_KEYWORD -REAL_KEYWORD -STRING_KEYWORD -BOOLEAN_KEYWORD -VOID_KEYWORD -FUNCTION_KEYWORD -INLINE_KEYWORD -RETURN_KEYWORD -IF_KEYWORD -ELIF_KEYWORD -ELSE_KEYWORD -FOR_KEYWORD -WHILE_KEYWORD -IN_KEYWORD -STEP_KEYWORD -INF_KEYWORD -AND_KEYWORD -OR_KEYWORD -NOT_KEYWORD -RECORDABLE_KEYWORD -KERNEL_KEYWORD -NEURON_KEYWORD -STATE_KEYWORD -PARAMETERS_KEYWORD -INTERNALS_KEYWORD -INITIAL_VALUES_KEYWORD -UPDATE_KEYWORD -EQUATIONS_KEYWORD -INPUT_KEYWORD -OUTPUT_KEYWORD -CURRENT_KEYWORD -SPIKE_KEYWORD -INHIBITORY_KEYWORD -EXCITATORY_KEYWORD -ELLIPSIS -LEFT_PAREN -RIGHT_PAREN -PLUS -TILDE -PIPE -CARET -AMPERSAND -LEFT_SQUARE_BRACKET -LEFT_ANGLE_MINUS -RIGHT_SQUARE_BRACKET -LEFT_LEFT_SQUARE -RIGHT_RIGHT_SQUARE -LEFT_LEFT_ANGLE -RIGHT_RIGHT_ANGLE -LEFT_ANGLE -RIGHT_ANGLE -LEFT_ANGLE_EQUALS -PLUS_EQUALS -MINUS_EQUALS -STAR_EQUALS -FORWARD_SLASH_EQUALS -EQUALS_EQUALS -EXCLAMATION_EQUALS -LEFT_ANGLE_RIGHT_ANGLE -RIGHT_ANGLE_EQUALS -COMMA -MINUS -EQUALS -STAR -STAR_STAR -FORWARD_SLASH -PERCENT -QUESTION -COLON -SEMICOLON -DIFFERENTIAL_ORDER -BOOLEAN_LITERAL -STRING_LITERAL -NAME -UNSIGNED_INTEGER -FLOAT - -rule names: -SL_COMMENT -ML_COMMENT -NEWLINE -WS -LINE_ESCAPE -END_KEYWORD -INTEGER_KEYWORD -REAL_KEYWORD -STRING_KEYWORD -BOOLEAN_KEYWORD -VOID_KEYWORD -FUNCTION_KEYWORD -INLINE_KEYWORD -RETURN_KEYWORD -IF_KEYWORD -ELIF_KEYWORD -ELSE_KEYWORD -FOR_KEYWORD -WHILE_KEYWORD -IN_KEYWORD -STEP_KEYWORD -INF_KEYWORD -AND_KEYWORD -OR_KEYWORD -NOT_KEYWORD -RECORDABLE_KEYWORD -KERNEL_KEYWORD -NEURON_KEYWORD -STATE_KEYWORD -PARAMETERS_KEYWORD -INTERNALS_KEYWORD -INITIAL_VALUES_KEYWORD -UPDATE_KEYWORD -EQUATIONS_KEYWORD -INPUT_KEYWORD -OUTPUT_KEYWORD -CURRENT_KEYWORD -SPIKE_KEYWORD -INHIBITORY_KEYWORD -EXCITATORY_KEYWORD -ELLIPSIS -LEFT_PAREN -RIGHT_PAREN -PLUS -TILDE -PIPE -CARET -AMPERSAND -LEFT_SQUARE_BRACKET -LEFT_ANGLE_MINUS -RIGHT_SQUARE_BRACKET -LEFT_LEFT_SQUARE -RIGHT_RIGHT_SQUARE -LEFT_LEFT_ANGLE -RIGHT_RIGHT_ANGLE -LEFT_ANGLE -RIGHT_ANGLE -LEFT_ANGLE_EQUALS -PLUS_EQUALS -MINUS_EQUALS -STAR_EQUALS -FORWARD_SLASH_EQUALS -EQUALS_EQUALS -EXCLAMATION_EQUALS -LEFT_ANGLE_RIGHT_ANGLE -RIGHT_ANGLE_EQUALS -COMMA -MINUS -EQUALS -STAR -STAR_STAR -FORWARD_SLASH -PERCENT -QUESTION -COLON -SEMICOLON -DIFFERENTIAL_ORDER -BOOLEAN_LITERAL -STRING_LITERAL -NAME -UNSIGNED_INTEGER -FLOAT -POINT_FLOAT -EXPONENT_FLOAT -EXPONENT - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN -null -null -COMMENT -NEW_LINE - -mode names: -DEFAULT_MODE - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 84, 632, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 3, 2, 3, 2, 7, 2, 176, 10, 2, 12, 2, 14, 2, 179, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 187, 10, 3, 12, 3, 14, 3, 190, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 199, 10, 3, 12, 3, 14, 3, 202, 11, 3, 3, 3, 3, 3, 3, 3, 5, 3, 207, 10, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 5, 4, 214, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 5, 6, 224, 10, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 69, 3, 69, 3, 70, 3, 70, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 74, 3, 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 5, 79, 578, 10, 79, 3, 80, 3, 80, 5, 80, 582, 10, 80, 3, 80, 7, 80, 585, 10, 80, 12, 80, 14, 80, 588, 11, 80, 3, 80, 3, 80, 3, 81, 5, 81, 593, 10, 81, 3, 81, 7, 81, 596, 10, 81, 12, 81, 14, 81, 599, 11, 81, 3, 82, 6, 82, 602, 10, 82, 13, 82, 14, 82, 603, 3, 83, 3, 83, 5, 83, 608, 10, 83, 3, 84, 5, 84, 611, 10, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 5, 84, 618, 10, 84, 3, 85, 3, 85, 5, 85, 622, 10, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 5, 86, 629, 10, 86, 3, 86, 3, 86, 4, 188, 200, 2, 87, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, 151, 77, 153, 78, 155, 79, 157, 80, 159, 81, 161, 82, 163, 83, 165, 84, 167, 2, 169, 2, 171, 2, 3, 2, 8, 4, 2, 12, 12, 15, 15, 4, 2, 11, 11, 34, 34, 6, 2, 38, 38, 67, 92, 97, 97, 99, 124, 7, 2, 38, 38, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59, 4, 2, 71, 71, 103, 103, 2, 646, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 3, 173, 3, 2, 2, 2, 5, 206, 3, 2, 2, 2, 7, 213, 3, 2, 2, 2, 9, 217, 3, 2, 2, 2, 11, 221, 3, 2, 2, 2, 13, 229, 3, 2, 2, 2, 15, 233, 3, 2, 2, 2, 17, 241, 3, 2, 2, 2, 19, 246, 3, 2, 2, 2, 21, 253, 3, 2, 2, 2, 23, 261, 3, 2, 2, 2, 25, 266, 3, 2, 2, 2, 27, 275, 3, 2, 2, 2, 29, 282, 3, 2, 2, 2, 31, 289, 3, 2, 2, 2, 33, 292, 3, 2, 2, 2, 35, 297, 3, 2, 2, 2, 37, 302, 3, 2, 2, 2, 39, 306, 3, 2, 2, 2, 41, 312, 3, 2, 2, 2, 43, 315, 3, 2, 2, 2, 45, 320, 3, 2, 2, 2, 47, 324, 3, 2, 2, 2, 49, 328, 3, 2, 2, 2, 51, 331, 3, 2, 2, 2, 53, 335, 3, 2, 2, 2, 55, 346, 3, 2, 2, 2, 57, 353, 3, 2, 2, 2, 59, 360, 3, 2, 2, 2, 61, 366, 3, 2, 2, 2, 63, 377, 3, 2, 2, 2, 65, 387, 3, 2, 2, 2, 67, 402, 3, 2, 2, 2, 69, 409, 3, 2, 2, 2, 71, 419, 3, 2, 2, 2, 73, 425, 3, 2, 2, 2, 75, 432, 3, 2, 2, 2, 77, 440, 3, 2, 2, 2, 79, 446, 3, 2, 2, 2, 81, 457, 3, 2, 2, 2, 83, 468, 3, 2, 2, 2, 85, 472, 3, 2, 2, 2, 87, 474, 3, 2, 2, 2, 89, 476, 3, 2, 2, 2, 91, 478, 3, 2, 2, 2, 93, 480, 3, 2, 2, 2, 95, 482, 3, 2, 2, 2, 97, 484, 3, 2, 2, 2, 99, 486, 3, 2, 2, 2, 101, 488, 3, 2, 2, 2, 103, 491, 3, 2, 2, 2, 105, 493, 3, 2, 2, 2, 107, 496, 3, 2, 2, 2, 109, 499, 3, 2, 2, 2, 111, 502, 3, 2, 2, 2, 113, 505, 3, 2, 2, 2, 115, 507, 3, 2, 2, 2, 117, 509, 3, 2, 2, 2, 119, 512, 3, 2, 2, 2, 121, 515, 3, 2, 2, 2, 123, 518, 3, 2, 2, 2, 125, 521, 3, 2, 2, 2, 127, 524, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 530, 3, 2, 2, 2, 133, 533, 3, 2, 2, 2, 135, 536, 3, 2, 2, 2, 137, 538, 3, 2, 2, 2, 139, 540, 3, 2, 2, 2, 141, 542, 3, 2, 2, 2, 143, 544, 3, 2, 2, 2, 145, 547, 3, 2, 2, 2, 147, 549, 3, 2, 2, 2, 149, 551, 3, 2, 2, 2, 151, 553, 3, 2, 2, 2, 153, 555, 3, 2, 2, 2, 155, 557, 3, 2, 2, 2, 157, 577, 3, 2, 2, 2, 159, 579, 3, 2, 2, 2, 161, 592, 3, 2, 2, 2, 163, 601, 3, 2, 2, 2, 165, 607, 3, 2, 2, 2, 167, 617, 3, 2, 2, 2, 169, 621, 3, 2, 2, 2, 171, 628, 3, 2, 2, 2, 173, 177, 7, 37, 2, 2, 174, 176, 10, 2, 2, 2, 175, 174, 3, 2, 2, 2, 176, 179, 3, 2, 2, 2, 177, 175, 3, 2, 2, 2, 177, 178, 3, 2, 2, 2, 178, 180, 3, 2, 2, 2, 179, 177, 3, 2, 2, 2, 180, 181, 8, 2, 2, 2, 181, 4, 3, 2, 2, 2, 182, 183, 7, 49, 2, 2, 183, 184, 7, 44, 2, 2, 184, 188, 3, 2, 2, 2, 185, 187, 11, 2, 2, 2, 186, 185, 3, 2, 2, 2, 187, 190, 3, 2, 2, 2, 188, 189, 3, 2, 2, 2, 188, 186, 3, 2, 2, 2, 189, 191, 3, 2, 2, 2, 190, 188, 3, 2, 2, 2, 191, 192, 7, 44, 2, 2, 192, 207, 7, 49, 2, 2, 193, 194, 7, 36, 2, 2, 194, 195, 7, 36, 2, 2, 195, 196, 7, 36, 2, 2, 196, 200, 3, 2, 2, 2, 197, 199, 11, 2, 2, 2, 198, 197, 3, 2, 2, 2, 199, 202, 3, 2, 2, 2, 200, 201, 3, 2, 2, 2, 200, 198, 3, 2, 2, 2, 201, 203, 3, 2, 2, 2, 202, 200, 3, 2, 2, 2, 203, 204, 7, 36, 2, 2, 204, 205, 7, 36, 2, 2, 205, 207, 7, 36, 2, 2, 206, 182, 3, 2, 2, 2, 206, 193, 3, 2, 2, 2, 207, 208, 3, 2, 2, 2, 208, 209, 8, 3, 2, 2, 209, 6, 3, 2, 2, 2, 210, 211, 7, 15, 2, 2, 211, 214, 7, 12, 2, 2, 212, 214, 9, 2, 2, 2, 213, 210, 3, 2, 2, 2, 213, 212, 3, 2, 2, 2, 214, 215, 3, 2, 2, 2, 215, 216, 8, 4, 3, 2, 216, 8, 3, 2, 2, 2, 217, 218, 9, 3, 2, 2, 218, 219, 3, 2, 2, 2, 219, 220, 8, 5, 4, 2, 220, 10, 3, 2, 2, 2, 221, 223, 7, 94, 2, 2, 222, 224, 7, 15, 2, 2, 223, 222, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 225, 3, 2, 2, 2, 225, 226, 7, 12, 2, 2, 226, 227, 3, 2, 2, 2, 227, 228, 8, 6, 4, 2, 228, 12, 3, 2, 2, 2, 229, 230, 7, 103, 2, 2, 230, 231, 7, 112, 2, 2, 231, 232, 7, 102, 2, 2, 232, 14, 3, 2, 2, 2, 233, 234, 7, 107, 2, 2, 234, 235, 7, 112, 2, 2, 235, 236, 7, 118, 2, 2, 236, 237, 7, 103, 2, 2, 237, 238, 7, 105, 2, 2, 238, 239, 7, 103, 2, 2, 239, 240, 7, 116, 2, 2, 240, 16, 3, 2, 2, 2, 241, 242, 7, 116, 2, 2, 242, 243, 7, 103, 2, 2, 243, 244, 7, 99, 2, 2, 244, 245, 7, 110, 2, 2, 245, 18, 3, 2, 2, 2, 246, 247, 7, 117, 2, 2, 247, 248, 7, 118, 2, 2, 248, 249, 7, 116, 2, 2, 249, 250, 7, 107, 2, 2, 250, 251, 7, 112, 2, 2, 251, 252, 7, 105, 2, 2, 252, 20, 3, 2, 2, 2, 253, 254, 7, 100, 2, 2, 254, 255, 7, 113, 2, 2, 255, 256, 7, 113, 2, 2, 256, 257, 7, 110, 2, 2, 257, 258, 7, 103, 2, 2, 258, 259, 7, 99, 2, 2, 259, 260, 7, 112, 2, 2, 260, 22, 3, 2, 2, 2, 261, 262, 7, 120, 2, 2, 262, 263, 7, 113, 2, 2, 263, 264, 7, 107, 2, 2, 264, 265, 7, 102, 2, 2, 265, 24, 3, 2, 2, 2, 266, 267, 7, 104, 2, 2, 267, 268, 7, 119, 2, 2, 268, 269, 7, 112, 2, 2, 269, 270, 7, 101, 2, 2, 270, 271, 7, 118, 2, 2, 271, 272, 7, 107, 2, 2, 272, 273, 7, 113, 2, 2, 273, 274, 7, 112, 2, 2, 274, 26, 3, 2, 2, 2, 275, 276, 7, 107, 2, 2, 276, 277, 7, 112, 2, 2, 277, 278, 7, 110, 2, 2, 278, 279, 7, 107, 2, 2, 279, 280, 7, 112, 2, 2, 280, 281, 7, 103, 2, 2, 281, 28, 3, 2, 2, 2, 282, 283, 7, 116, 2, 2, 283, 284, 7, 103, 2, 2, 284, 285, 7, 118, 2, 2, 285, 286, 7, 119, 2, 2, 286, 287, 7, 116, 2, 2, 287, 288, 7, 112, 2, 2, 288, 30, 3, 2, 2, 2, 289, 290, 7, 107, 2, 2, 290, 291, 7, 104, 2, 2, 291, 32, 3, 2, 2, 2, 292, 293, 7, 103, 2, 2, 293, 294, 7, 110, 2, 2, 294, 295, 7, 107, 2, 2, 295, 296, 7, 104, 2, 2, 296, 34, 3, 2, 2, 2, 297, 298, 7, 103, 2, 2, 298, 299, 7, 110, 2, 2, 299, 300, 7, 117, 2, 2, 300, 301, 7, 103, 2, 2, 301, 36, 3, 2, 2, 2, 302, 303, 7, 104, 2, 2, 303, 304, 7, 113, 2, 2, 304, 305, 7, 116, 2, 2, 305, 38, 3, 2, 2, 2, 306, 307, 7, 121, 2, 2, 307, 308, 7, 106, 2, 2, 308, 309, 7, 107, 2, 2, 309, 310, 7, 110, 2, 2, 310, 311, 7, 103, 2, 2, 311, 40, 3, 2, 2, 2, 312, 313, 7, 107, 2, 2, 313, 314, 7, 112, 2, 2, 314, 42, 3, 2, 2, 2, 315, 316, 7, 117, 2, 2, 316, 317, 7, 118, 2, 2, 317, 318, 7, 103, 2, 2, 318, 319, 7, 114, 2, 2, 319, 44, 3, 2, 2, 2, 320, 321, 7, 107, 2, 2, 321, 322, 7, 112, 2, 2, 322, 323, 7, 104, 2, 2, 323, 46, 3, 2, 2, 2, 324, 325, 7, 99, 2, 2, 325, 326, 7, 112, 2, 2, 326, 327, 7, 102, 2, 2, 327, 48, 3, 2, 2, 2, 328, 329, 7, 113, 2, 2, 329, 330, 7, 116, 2, 2, 330, 50, 3, 2, 2, 2, 331, 332, 7, 112, 2, 2, 332, 333, 7, 113, 2, 2, 333, 334, 7, 118, 2, 2, 334, 52, 3, 2, 2, 2, 335, 336, 7, 116, 2, 2, 336, 337, 7, 103, 2, 2, 337, 338, 7, 101, 2, 2, 338, 339, 7, 113, 2, 2, 339, 340, 7, 116, 2, 2, 340, 341, 7, 102, 2, 2, 341, 342, 7, 99, 2, 2, 342, 343, 7, 100, 2, 2, 343, 344, 7, 110, 2, 2, 344, 345, 7, 103, 2, 2, 345, 54, 3, 2, 2, 2, 346, 347, 7, 109, 2, 2, 347, 348, 7, 103, 2, 2, 348, 349, 7, 116, 2, 2, 349, 350, 7, 112, 2, 2, 350, 351, 7, 103, 2, 2, 351, 352, 7, 110, 2, 2, 352, 56, 3, 2, 2, 2, 353, 354, 7, 112, 2, 2, 354, 355, 7, 103, 2, 2, 355, 356, 7, 119, 2, 2, 356, 357, 7, 116, 2, 2, 357, 358, 7, 113, 2, 2, 358, 359, 7, 112, 2, 2, 359, 58, 3, 2, 2, 2, 360, 361, 7, 117, 2, 2, 361, 362, 7, 118, 2, 2, 362, 363, 7, 99, 2, 2, 363, 364, 7, 118, 2, 2, 364, 365, 7, 103, 2, 2, 365, 60, 3, 2, 2, 2, 366, 367, 7, 114, 2, 2, 367, 368, 7, 99, 2, 2, 368, 369, 7, 116, 2, 2, 369, 370, 7, 99, 2, 2, 370, 371, 7, 111, 2, 2, 371, 372, 7, 103, 2, 2, 372, 373, 7, 118, 2, 2, 373, 374, 7, 103, 2, 2, 374, 375, 7, 116, 2, 2, 375, 376, 7, 117, 2, 2, 376, 62, 3, 2, 2, 2, 377, 378, 7, 107, 2, 2, 378, 379, 7, 112, 2, 2, 379, 380, 7, 118, 2, 2, 380, 381, 7, 103, 2, 2, 381, 382, 7, 116, 2, 2, 382, 383, 7, 112, 2, 2, 383, 384, 7, 99, 2, 2, 384, 385, 7, 110, 2, 2, 385, 386, 7, 117, 2, 2, 386, 64, 3, 2, 2, 2, 387, 388, 7, 107, 2, 2, 388, 389, 7, 112, 2, 2, 389, 390, 7, 107, 2, 2, 390, 391, 7, 118, 2, 2, 391, 392, 7, 107, 2, 2, 392, 393, 7, 99, 2, 2, 393, 394, 7, 110, 2, 2, 394, 395, 7, 97, 2, 2, 395, 396, 7, 120, 2, 2, 396, 397, 7, 99, 2, 2, 397, 398, 7, 110, 2, 2, 398, 399, 7, 119, 2, 2, 399, 400, 7, 103, 2, 2, 400, 401, 7, 117, 2, 2, 401, 66, 3, 2, 2, 2, 402, 403, 7, 119, 2, 2, 403, 404, 7, 114, 2, 2, 404, 405, 7, 102, 2, 2, 405, 406, 7, 99, 2, 2, 406, 407, 7, 118, 2, 2, 407, 408, 7, 103, 2, 2, 408, 68, 3, 2, 2, 2, 409, 410, 7, 103, 2, 2, 410, 411, 7, 115, 2, 2, 411, 412, 7, 119, 2, 2, 412, 413, 7, 99, 2, 2, 413, 414, 7, 118, 2, 2, 414, 415, 7, 107, 2, 2, 415, 416, 7, 113, 2, 2, 416, 417, 7, 112, 2, 2, 417, 418, 7, 117, 2, 2, 418, 70, 3, 2, 2, 2, 419, 420, 7, 107, 2, 2, 420, 421, 7, 112, 2, 2, 421, 422, 7, 114, 2, 2, 422, 423, 7, 119, 2, 2, 423, 424, 7, 118, 2, 2, 424, 72, 3, 2, 2, 2, 425, 426, 7, 113, 2, 2, 426, 427, 7, 119, 2, 2, 427, 428, 7, 118, 2, 2, 428, 429, 7, 114, 2, 2, 429, 430, 7, 119, 2, 2, 430, 431, 7, 118, 2, 2, 431, 74, 3, 2, 2, 2, 432, 433, 7, 101, 2, 2, 433, 434, 7, 119, 2, 2, 434, 435, 7, 116, 2, 2, 435, 436, 7, 116, 2, 2, 436, 437, 7, 103, 2, 2, 437, 438, 7, 112, 2, 2, 438, 439, 7, 118, 2, 2, 439, 76, 3, 2, 2, 2, 440, 441, 7, 117, 2, 2, 441, 442, 7, 114, 2, 2, 442, 443, 7, 107, 2, 2, 443, 444, 7, 109, 2, 2, 444, 445, 7, 103, 2, 2, 445, 78, 3, 2, 2, 2, 446, 447, 7, 107, 2, 2, 447, 448, 7, 112, 2, 2, 448, 449, 7, 106, 2, 2, 449, 450, 7, 107, 2, 2, 450, 451, 7, 100, 2, 2, 451, 452, 7, 107, 2, 2, 452, 453, 7, 118, 2, 2, 453, 454, 7, 113, 2, 2, 454, 455, 7, 116, 2, 2, 455, 456, 7, 123, 2, 2, 456, 80, 3, 2, 2, 2, 457, 458, 7, 103, 2, 2, 458, 459, 7, 122, 2, 2, 459, 460, 7, 101, 2, 2, 460, 461, 7, 107, 2, 2, 461, 462, 7, 118, 2, 2, 462, 463, 7, 99, 2, 2, 463, 464, 7, 118, 2, 2, 464, 465, 7, 113, 2, 2, 465, 466, 7, 116, 2, 2, 466, 467, 7, 123, 2, 2, 467, 82, 3, 2, 2, 2, 468, 469, 7, 48, 2, 2, 469, 470, 7, 48, 2, 2, 470, 471, 7, 48, 2, 2, 471, 84, 3, 2, 2, 2, 472, 473, 7, 42, 2, 2, 473, 86, 3, 2, 2, 2, 474, 475, 7, 43, 2, 2, 475, 88, 3, 2, 2, 2, 476, 477, 7, 45, 2, 2, 477, 90, 3, 2, 2, 2, 478, 479, 7, 128, 2, 2, 479, 92, 3, 2, 2, 2, 480, 481, 7, 126, 2, 2, 481, 94, 3, 2, 2, 2, 482, 483, 7, 96, 2, 2, 483, 96, 3, 2, 2, 2, 484, 485, 7, 40, 2, 2, 485, 98, 3, 2, 2, 2, 486, 487, 7, 93, 2, 2, 487, 100, 3, 2, 2, 2, 488, 489, 7, 62, 2, 2, 489, 490, 7, 47, 2, 2, 490, 102, 3, 2, 2, 2, 491, 492, 7, 95, 2, 2, 492, 104, 3, 2, 2, 2, 493, 494, 7, 93, 2, 2, 494, 495, 7, 93, 2, 2, 495, 106, 3, 2, 2, 2, 496, 497, 7, 95, 2, 2, 497, 498, 7, 95, 2, 2, 498, 108, 3, 2, 2, 2, 499, 500, 7, 62, 2, 2, 500, 501, 7, 62, 2, 2, 501, 110, 3, 2, 2, 2, 502, 503, 7, 64, 2, 2, 503, 504, 7, 64, 2, 2, 504, 112, 3, 2, 2, 2, 505, 506, 7, 62, 2, 2, 506, 114, 3, 2, 2, 2, 507, 508, 7, 64, 2, 2, 508, 116, 3, 2, 2, 2, 509, 510, 7, 62, 2, 2, 510, 511, 7, 63, 2, 2, 511, 118, 3, 2, 2, 2, 512, 513, 7, 45, 2, 2, 513, 514, 7, 63, 2, 2, 514, 120, 3, 2, 2, 2, 515, 516, 7, 47, 2, 2, 516, 517, 7, 63, 2, 2, 517, 122, 3, 2, 2, 2, 518, 519, 7, 44, 2, 2, 519, 520, 7, 63, 2, 2, 520, 124, 3, 2, 2, 2, 521, 522, 7, 49, 2, 2, 522, 523, 7, 63, 2, 2, 523, 126, 3, 2, 2, 2, 524, 525, 7, 63, 2, 2, 525, 526, 7, 63, 2, 2, 526, 128, 3, 2, 2, 2, 527, 528, 7, 35, 2, 2, 528, 529, 7, 63, 2, 2, 529, 130, 3, 2, 2, 2, 530, 531, 7, 62, 2, 2, 531, 532, 7, 64, 2, 2, 532, 132, 3, 2, 2, 2, 533, 534, 7, 64, 2, 2, 534, 535, 7, 63, 2, 2, 535, 134, 3, 2, 2, 2, 536, 537, 7, 46, 2, 2, 537, 136, 3, 2, 2, 2, 538, 539, 7, 47, 2, 2, 539, 138, 3, 2, 2, 2, 540, 541, 7, 63, 2, 2, 541, 140, 3, 2, 2, 2, 542, 543, 7, 44, 2, 2, 543, 142, 3, 2, 2, 2, 544, 545, 7, 44, 2, 2, 545, 546, 7, 44, 2, 2, 546, 144, 3, 2, 2, 2, 547, 548, 7, 49, 2, 2, 548, 146, 3, 2, 2, 2, 549, 550, 7, 39, 2, 2, 550, 148, 3, 2, 2, 2, 551, 552, 7, 65, 2, 2, 552, 150, 3, 2, 2, 2, 553, 554, 7, 60, 2, 2, 554, 152, 3, 2, 2, 2, 555, 556, 7, 61, 2, 2, 556, 154, 3, 2, 2, 2, 557, 558, 7, 41, 2, 2, 558, 156, 3, 2, 2, 2, 559, 560, 7, 118, 2, 2, 560, 561, 7, 116, 2, 2, 561, 562, 7, 119, 2, 2, 562, 578, 7, 103, 2, 2, 563, 564, 7, 86, 2, 2, 564, 565, 7, 116, 2, 2, 565, 566, 7, 119, 2, 2, 566, 578, 7, 103, 2, 2, 567, 568, 7, 104, 2, 2, 568, 569, 7, 99, 2, 2, 569, 570, 7, 110, 2, 2, 570, 571, 7, 117, 2, 2, 571, 578, 7, 103, 2, 2, 572, 573, 7, 72, 2, 2, 573, 574, 7, 99, 2, 2, 574, 575, 7, 110, 2, 2, 575, 576, 7, 117, 2, 2, 576, 578, 7, 103, 2, 2, 577, 559, 3, 2, 2, 2, 577, 563, 3, 2, 2, 2, 577, 567, 3, 2, 2, 2, 577, 572, 3, 2, 2, 2, 578, 158, 3, 2, 2, 2, 579, 581, 7, 36, 2, 2, 580, 582, 9, 4, 2, 2, 581, 580, 3, 2, 2, 2, 582, 586, 3, 2, 2, 2, 583, 585, 9, 5, 2, 2, 584, 583, 3, 2, 2, 2, 585, 588, 3, 2, 2, 2, 586, 584, 3, 2, 2, 2, 586, 587, 3, 2, 2, 2, 587, 589, 3, 2, 2, 2, 588, 586, 3, 2, 2, 2, 589, 590, 7, 36, 2, 2, 590, 160, 3, 2, 2, 2, 591, 593, 9, 4, 2, 2, 592, 591, 3, 2, 2, 2, 593, 597, 3, 2, 2, 2, 594, 596, 9, 5, 2, 2, 595, 594, 3, 2, 2, 2, 596, 599, 3, 2, 2, 2, 597, 595, 3, 2, 2, 2, 597, 598, 3, 2, 2, 2, 598, 162, 3, 2, 2, 2, 599, 597, 3, 2, 2, 2, 600, 602, 9, 6, 2, 2, 601, 600, 3, 2, 2, 2, 602, 603, 3, 2, 2, 2, 603, 601, 3, 2, 2, 2, 603, 604, 3, 2, 2, 2, 604, 164, 3, 2, 2, 2, 605, 608, 5, 167, 84, 2, 606, 608, 5, 169, 85, 2, 607, 605, 3, 2, 2, 2, 607, 606, 3, 2, 2, 2, 608, 166, 3, 2, 2, 2, 609, 611, 5, 163, 82, 2, 610, 609, 3, 2, 2, 2, 610, 611, 3, 2, 2, 2, 611, 612, 3, 2, 2, 2, 612, 613, 7, 48, 2, 2, 613, 618, 5, 163, 82, 2, 614, 615, 5, 163, 82, 2, 615, 616, 7, 48, 2, 2, 616, 618, 3, 2, 2, 2, 617, 610, 3, 2, 2, 2, 617, 614, 3, 2, 2, 2, 618, 168, 3, 2, 2, 2, 619, 622, 5, 163, 82, 2, 620, 622, 5, 167, 84, 2, 621, 619, 3, 2, 2, 2, 621, 620, 3, 2, 2, 2, 622, 623, 3, 2, 2, 2, 623, 624, 9, 7, 2, 2, 624, 625, 5, 171, 86, 2, 625, 170, 3, 2, 2, 2, 626, 629, 5, 89, 45, 2, 627, 629, 5, 137, 69, 2, 628, 626, 3, 2, 2, 2, 628, 627, 3, 2, 2, 2, 628, 629, 3, 2, 2, 2, 629, 630, 3, 2, 2, 2, 630, 631, 5, 163, 82, 2, 631, 172, 3, 2, 2, 2, 22, 2, 177, 188, 200, 206, 213, 223, 577, 581, 584, 586, 592, 595, 597, 603, 607, 610, 617, 621, 628, 5, 2, 4, 2, 2, 5, 2, 2, 3, 2] \ No newline at end of file diff --git a/pynestml/generated/PyNestMLLexer.py b/pynestml/generated/PyNestMLLexer.py index c9e4764a5..e59c23db0 100644 --- a/pynestml/generated/PyNestMLLexer.py +++ b/pynestml/generated/PyNestMLLexer.py @@ -1,288 +1,261 @@ -# Generated from PyNestMLLexer.g4 by ANTLR 4.7.1 -# encoding: utf-8 -from __future__ import print_function +# Generated from PyNestMLLexer.g4 by ANTLR 4.10 from antlr4 import * from io import StringIO import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO def serializedATN(): - with StringIO() as buf: - buf.write(u"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2") - buf.write(u"T\u0278\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4") - buf.write(u"\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r") - buf.write(u"\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22") - buf.write(u"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4") - buf.write(u"\30\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35") - buf.write(u"\t\35\4\36\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4") - buf.write(u"$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t") - buf.write(u",\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63") - buf.write(u"\t\63\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\4") - buf.write(u"9\t9\4:\t:\4;\t;\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA") - buf.write(u"\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I\tI\4J\t") - buf.write(u"J\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S") - buf.write(u"\tS\4T\tT\4U\tU\4V\tV\3\2\3\2\7\2\u00b0\n\2\f\2\16\2") - buf.write(u"\u00b3\13\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u00bb\n\3\f\3") - buf.write(u"\16\3\u00be\13\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\7\3\u00c7") - buf.write(u"\n\3\f\3\16\3\u00ca\13\3\3\3\3\3\3\3\5\3\u00cf\n\3\3") - buf.write(u"\3\3\3\3\4\3\4\3\4\5\4\u00d6\n\4\3\4\3\4\3\5\3\5\3\5") - buf.write(u"\3\5\3\6\3\6\5\6\u00e0\n\6\3\6\3\6\3\6\3\6\3\7\3\7\3") - buf.write(u"\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3") - buf.write(u"\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13") - buf.write(u"\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r") - buf.write(u"\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16") - buf.write(u"\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3") - buf.write(u"\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22") - buf.write(u"\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3") - buf.write(u"\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27") - buf.write(u"\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\32\3\32\3") - buf.write(u"\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33") - buf.write(u"\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3") - buf.write(u"\35\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36") - buf.write(u"\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3") - buf.write(u"\37\3\37\3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3") - buf.write(u"!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3") - buf.write(u"\"\3\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3") - buf.write(u"$\3%\3%\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3&\3&\3&\3\'\3") - buf.write(u"\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3") - buf.write(u")\3)\3)\3)\3)\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3,") - buf.write(u"\3,\3-\3-\3.\3.\3/\3/\3\60\3\60\3\61\3\61\3\62\3\62\3") - buf.write(u"\63\3\63\3\63\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66") - buf.write(u"\3\67\3\67\3\67\38\38\38\39\39\3:\3:\3;\3;\3;\3<\3<\3") - buf.write(u"<\3=\3=\3=\3>\3>\3>\3?\3?\3?\3@\3@\3@\3A\3A\3A\3B\3B") - buf.write(u"\3B\3C\3C\3C\3D\3D\3E\3E\3F\3F\3G\3G\3H\3H\3H\3I\3I\3") - buf.write(u"J\3J\3K\3K\3L\3L\3M\3M\3N\3N\3O\3O\3O\3O\3O\3O\3O\3O") - buf.write(u"\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\5O\u0242\nO\3P\3P\5P\u0246") - buf.write(u"\nP\3P\7P\u0249\nP\fP\16P\u024c\13P\3P\3P\3Q\5Q\u0251") - buf.write(u"\nQ\3Q\7Q\u0254\nQ\fQ\16Q\u0257\13Q\3R\6R\u025a\nR\r") - buf.write(u"R\16R\u025b\3S\3S\5S\u0260\nS\3T\5T\u0263\nT\3T\3T\3") - buf.write(u"T\3T\3T\5T\u026a\nT\3U\3U\5U\u026e\nU\3U\3U\3U\3V\3V") - buf.write(u"\5V\u0275\nV\3V\3V\4\u00bc\u00c8\2W\3\3\5\4\7\5\t\6\13") - buf.write(u"\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37") - buf.write(u"\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34") - buf.write(u"\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60") - buf.write(u"_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u{?}@\177A\u0081") - buf.write(u"B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091") - buf.write(u"J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1") - buf.write(u"R\u00a3S\u00a5T\u00a7\2\u00a9\2\u00ab\2\3\2\b\4\2\f\f") - buf.write(u"\17\17\4\2\13\13\"\"\6\2&&C\\aac|\7\2&&\62;C\\aac|\3") - buf.write(u"\2\62;\4\2GGgg\2\u0286\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3") - buf.write(u"\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2") - buf.write(u"\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2") - buf.write(u"\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2") - buf.write(u"\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)") - buf.write(u"\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2") - buf.write(u"\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2") - buf.write(u"\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2") - buf.write(u"\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2") - buf.write(u"\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3") - buf.write(u"\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2") - buf.write(u"a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2") - buf.write(u"\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2") - buf.write(u"\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2") - buf.write(u"\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2") - buf.write(u"\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b") - buf.write(u"\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2") - buf.write(u"\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2") - buf.write(u"\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f") - buf.write(u"\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2") - buf.write(u"\2\2\3\u00ad\3\2\2\2\5\u00ce\3\2\2\2\7\u00d5\3\2\2\2") - buf.write(u"\t\u00d9\3\2\2\2\13\u00dd\3\2\2\2\r\u00e5\3\2\2\2\17") - buf.write(u"\u00e9\3\2\2\2\21\u00f1\3\2\2\2\23\u00f6\3\2\2\2\25\u00fd") - buf.write(u"\3\2\2\2\27\u0105\3\2\2\2\31\u010a\3\2\2\2\33\u0113\3") - buf.write(u"\2\2\2\35\u011a\3\2\2\2\37\u0121\3\2\2\2!\u0124\3\2\2") - buf.write(u"\2#\u0129\3\2\2\2%\u012e\3\2\2\2\'\u0132\3\2\2\2)\u0138") - buf.write(u"\3\2\2\2+\u013b\3\2\2\2-\u0140\3\2\2\2/\u0144\3\2\2\2") - buf.write(u"\61\u0148\3\2\2\2\63\u014b\3\2\2\2\65\u014f\3\2\2\2\67") - buf.write(u"\u015a\3\2\2\29\u0161\3\2\2\2;\u0168\3\2\2\2=\u016e\3") - buf.write(u"\2\2\2?\u0179\3\2\2\2A\u0183\3\2\2\2C\u0192\3\2\2\2E") - buf.write(u"\u0199\3\2\2\2G\u01a3\3\2\2\2I\u01a9\3\2\2\2K\u01b0\3") - buf.write(u"\2\2\2M\u01b8\3\2\2\2O\u01be\3\2\2\2Q\u01c9\3\2\2\2S") - buf.write(u"\u01d4\3\2\2\2U\u01d8\3\2\2\2W\u01da\3\2\2\2Y\u01dc\3") - buf.write(u"\2\2\2[\u01de\3\2\2\2]\u01e0\3\2\2\2_\u01e2\3\2\2\2a") - buf.write(u"\u01e4\3\2\2\2c\u01e6\3\2\2\2e\u01e8\3\2\2\2g\u01eb\3") - buf.write(u"\2\2\2i\u01ed\3\2\2\2k\u01f0\3\2\2\2m\u01f3\3\2\2\2o") - buf.write(u"\u01f6\3\2\2\2q\u01f9\3\2\2\2s\u01fb\3\2\2\2u\u01fd\3") - buf.write(u"\2\2\2w\u0200\3\2\2\2y\u0203\3\2\2\2{\u0206\3\2\2\2}") - buf.write(u"\u0209\3\2\2\2\177\u020c\3\2\2\2\u0081\u020f\3\2\2\2") - buf.write(u"\u0083\u0212\3\2\2\2\u0085\u0215\3\2\2\2\u0087\u0218") - buf.write(u"\3\2\2\2\u0089\u021a\3\2\2\2\u008b\u021c\3\2\2\2\u008d") - buf.write(u"\u021e\3\2\2\2\u008f\u0220\3\2\2\2\u0091\u0223\3\2\2") - buf.write(u"\2\u0093\u0225\3\2\2\2\u0095\u0227\3\2\2\2\u0097\u0229") - buf.write(u"\3\2\2\2\u0099\u022b\3\2\2\2\u009b\u022d\3\2\2\2\u009d") - buf.write(u"\u0241\3\2\2\2\u009f\u0243\3\2\2\2\u00a1\u0250\3\2\2") - buf.write(u"\2\u00a3\u0259\3\2\2\2\u00a5\u025f\3\2\2\2\u00a7\u0269") - buf.write(u"\3\2\2\2\u00a9\u026d\3\2\2\2\u00ab\u0274\3\2\2\2\u00ad") - buf.write(u"\u00b1\7%\2\2\u00ae\u00b0\n\2\2\2\u00af\u00ae\3\2\2\2") - buf.write(u"\u00b0\u00b3\3\2\2\2\u00b1\u00af\3\2\2\2\u00b1\u00b2") - buf.write(u"\3\2\2\2\u00b2\u00b4\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b4") - buf.write(u"\u00b5\b\2\2\2\u00b5\4\3\2\2\2\u00b6\u00b7\7\61\2\2\u00b7") - buf.write(u"\u00b8\7,\2\2\u00b8\u00bc\3\2\2\2\u00b9\u00bb\13\2\2") - buf.write(u"\2\u00ba\u00b9\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc\u00bd") - buf.write(u"\3\2\2\2\u00bc\u00ba\3\2\2\2\u00bd\u00bf\3\2\2\2\u00be") - buf.write(u"\u00bc\3\2\2\2\u00bf\u00c0\7,\2\2\u00c0\u00cf\7\61\2") - buf.write(u"\2\u00c1\u00c2\7$\2\2\u00c2\u00c3\7$\2\2\u00c3\u00c4") - buf.write(u"\7$\2\2\u00c4\u00c8\3\2\2\2\u00c5\u00c7\13\2\2\2\u00c6") - buf.write(u"\u00c5\3\2\2\2\u00c7\u00ca\3\2\2\2\u00c8\u00c9\3\2\2") - buf.write(u"\2\u00c8\u00c6\3\2\2\2\u00c9\u00cb\3\2\2\2\u00ca\u00c8") - buf.write(u"\3\2\2\2\u00cb\u00cc\7$\2\2\u00cc\u00cd\7$\2\2\u00cd") - buf.write(u"\u00cf\7$\2\2\u00ce\u00b6\3\2\2\2\u00ce\u00c1\3\2\2\2") - buf.write(u"\u00cf\u00d0\3\2\2\2\u00d0\u00d1\b\3\2\2\u00d1\6\3\2") - buf.write(u"\2\2\u00d2\u00d3\7\17\2\2\u00d3\u00d6\7\f\2\2\u00d4\u00d6") - buf.write(u"\t\2\2\2\u00d5\u00d2\3\2\2\2\u00d5\u00d4\3\2\2\2\u00d6") - buf.write(u"\u00d7\3\2\2\2\u00d7\u00d8\b\4\3\2\u00d8\b\3\2\2\2\u00d9") - buf.write(u"\u00da\t\3\2\2\u00da\u00db\3\2\2\2\u00db\u00dc\b\5\4") - buf.write(u"\2\u00dc\n\3\2\2\2\u00dd\u00df\7^\2\2\u00de\u00e0\7\17") - buf.write(u"\2\2\u00df\u00de\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0\u00e1") - buf.write(u"\3\2\2\2\u00e1\u00e2\7\f\2\2\u00e2\u00e3\3\2\2\2\u00e3") - buf.write(u"\u00e4\b\6\4\2\u00e4\f\3\2\2\2\u00e5\u00e6\7g\2\2\u00e6") - buf.write(u"\u00e7\7p\2\2\u00e7\u00e8\7f\2\2\u00e8\16\3\2\2\2\u00e9") - buf.write(u"\u00ea\7k\2\2\u00ea\u00eb\7p\2\2\u00eb\u00ec\7v\2\2\u00ec") - buf.write(u"\u00ed\7g\2\2\u00ed\u00ee\7i\2\2\u00ee\u00ef\7g\2\2\u00ef") - buf.write(u"\u00f0\7t\2\2\u00f0\20\3\2\2\2\u00f1\u00f2\7t\2\2\u00f2") - buf.write(u"\u00f3\7g\2\2\u00f3\u00f4\7c\2\2\u00f4\u00f5\7n\2\2\u00f5") - buf.write(u"\22\3\2\2\2\u00f6\u00f7\7u\2\2\u00f7\u00f8\7v\2\2\u00f8") - buf.write(u"\u00f9\7t\2\2\u00f9\u00fa\7k\2\2\u00fa\u00fb\7p\2\2\u00fb") - buf.write(u"\u00fc\7i\2\2\u00fc\24\3\2\2\2\u00fd\u00fe\7d\2\2\u00fe") - buf.write(u"\u00ff\7q\2\2\u00ff\u0100\7q\2\2\u0100\u0101\7n\2\2\u0101") - buf.write(u"\u0102\7g\2\2\u0102\u0103\7c\2\2\u0103\u0104\7p\2\2\u0104") - buf.write(u"\26\3\2\2\2\u0105\u0106\7x\2\2\u0106\u0107\7q\2\2\u0107") - buf.write(u"\u0108\7k\2\2\u0108\u0109\7f\2\2\u0109\30\3\2\2\2\u010a") - buf.write(u"\u010b\7h\2\2\u010b\u010c\7w\2\2\u010c\u010d\7p\2\2\u010d") - buf.write(u"\u010e\7e\2\2\u010e\u010f\7v\2\2\u010f\u0110\7k\2\2\u0110") - buf.write(u"\u0111\7q\2\2\u0111\u0112\7p\2\2\u0112\32\3\2\2\2\u0113") - buf.write(u"\u0114\7k\2\2\u0114\u0115\7p\2\2\u0115\u0116\7n\2\2\u0116") - buf.write(u"\u0117\7k\2\2\u0117\u0118\7p\2\2\u0118\u0119\7g\2\2\u0119") - buf.write(u"\34\3\2\2\2\u011a\u011b\7t\2\2\u011b\u011c\7g\2\2\u011c") - buf.write(u"\u011d\7v\2\2\u011d\u011e\7w\2\2\u011e\u011f\7t\2\2\u011f") - buf.write(u"\u0120\7p\2\2\u0120\36\3\2\2\2\u0121\u0122\7k\2\2\u0122") - buf.write(u"\u0123\7h\2\2\u0123 \3\2\2\2\u0124\u0125\7g\2\2\u0125") - buf.write(u"\u0126\7n\2\2\u0126\u0127\7k\2\2\u0127\u0128\7h\2\2\u0128") - buf.write(u"\"\3\2\2\2\u0129\u012a\7g\2\2\u012a\u012b\7n\2\2\u012b") - buf.write(u"\u012c\7u\2\2\u012c\u012d\7g\2\2\u012d$\3\2\2\2\u012e") - buf.write(u"\u012f\7h\2\2\u012f\u0130\7q\2\2\u0130\u0131\7t\2\2\u0131") - buf.write(u"&\3\2\2\2\u0132\u0133\7y\2\2\u0133\u0134\7j\2\2\u0134") - buf.write(u"\u0135\7k\2\2\u0135\u0136\7n\2\2\u0136\u0137\7g\2\2\u0137") - buf.write(u"(\3\2\2\2\u0138\u0139\7k\2\2\u0139\u013a\7p\2\2\u013a") - buf.write(u"*\3\2\2\2\u013b\u013c\7u\2\2\u013c\u013d\7v\2\2\u013d") - buf.write(u"\u013e\7g\2\2\u013e\u013f\7r\2\2\u013f,\3\2\2\2\u0140") - buf.write(u"\u0141\7k\2\2\u0141\u0142\7p\2\2\u0142\u0143\7h\2\2\u0143") - buf.write(u".\3\2\2\2\u0144\u0145\7c\2\2\u0145\u0146\7p\2\2\u0146") - buf.write(u"\u0147\7f\2\2\u0147\60\3\2\2\2\u0148\u0149\7q\2\2\u0149") - buf.write(u"\u014a\7t\2\2\u014a\62\3\2\2\2\u014b\u014c\7p\2\2\u014c") - buf.write(u"\u014d\7q\2\2\u014d\u014e\7v\2\2\u014e\64\3\2\2\2\u014f") - buf.write(u"\u0150\7t\2\2\u0150\u0151\7g\2\2\u0151\u0152\7e\2\2\u0152") - buf.write(u"\u0153\7q\2\2\u0153\u0154\7t\2\2\u0154\u0155\7f\2\2\u0155") - buf.write(u"\u0156\7c\2\2\u0156\u0157\7d\2\2\u0157\u0158\7n\2\2\u0158") - buf.write(u"\u0159\7g\2\2\u0159\66\3\2\2\2\u015a\u015b\7m\2\2\u015b") - buf.write(u"\u015c\7g\2\2\u015c\u015d\7t\2\2\u015d\u015e\7p\2\2\u015e") - buf.write(u"\u015f\7g\2\2\u015f\u0160\7n\2\2\u01608\3\2\2\2\u0161") - buf.write(u"\u0162\7p\2\2\u0162\u0163\7g\2\2\u0163\u0164\7w\2\2\u0164") - buf.write(u"\u0165\7t\2\2\u0165\u0166\7q\2\2\u0166\u0167\7p\2\2\u0167") - buf.write(u":\3\2\2\2\u0168\u0169\7u\2\2\u0169\u016a\7v\2\2\u016a") - buf.write(u"\u016b\7c\2\2\u016b\u016c\7v\2\2\u016c\u016d\7g\2\2\u016d") - buf.write(u"<\3\2\2\2\u016e\u016f\7r\2\2\u016f\u0170\7c\2\2\u0170") - buf.write(u"\u0171\7t\2\2\u0171\u0172\7c\2\2\u0172\u0173\7o\2\2\u0173") - buf.write(u"\u0174\7g\2\2\u0174\u0175\7v\2\2\u0175\u0176\7g\2\2\u0176") - buf.write(u"\u0177\7t\2\2\u0177\u0178\7u\2\2\u0178>\3\2\2\2\u0179") - buf.write(u"\u017a\7k\2\2\u017a\u017b\7p\2\2\u017b\u017c\7v\2\2\u017c") - buf.write(u"\u017d\7g\2\2\u017d\u017e\7t\2\2\u017e\u017f\7p\2\2\u017f") - buf.write(u"\u0180\7c\2\2\u0180\u0181\7n\2\2\u0181\u0182\7u\2\2\u0182") - buf.write(u"@\3\2\2\2\u0183\u0184\7k\2\2\u0184\u0185\7p\2\2\u0185") - buf.write(u"\u0186\7k\2\2\u0186\u0187\7v\2\2\u0187\u0188\7k\2\2\u0188") - buf.write(u"\u0189\7c\2\2\u0189\u018a\7n\2\2\u018a\u018b\7a\2\2\u018b") - buf.write(u"\u018c\7x\2\2\u018c\u018d\7c\2\2\u018d\u018e\7n\2\2\u018e") - buf.write(u"\u018f\7w\2\2\u018f\u0190\7g\2\2\u0190\u0191\7u\2\2\u0191") - buf.write(u"B\3\2\2\2\u0192\u0193\7w\2\2\u0193\u0194\7r\2\2\u0194") - buf.write(u"\u0195\7f\2\2\u0195\u0196\7c\2\2\u0196\u0197\7v\2\2\u0197") - buf.write(u"\u0198\7g\2\2\u0198D\3\2\2\2\u0199\u019a\7g\2\2\u019a") - buf.write(u"\u019b\7s\2\2\u019b\u019c\7w\2\2\u019c\u019d\7c\2\2\u019d") - buf.write(u"\u019e\7v\2\2\u019e\u019f\7k\2\2\u019f\u01a0\7q\2\2\u01a0") - buf.write(u"\u01a1\7p\2\2\u01a1\u01a2\7u\2\2\u01a2F\3\2\2\2\u01a3") - buf.write(u"\u01a4\7k\2\2\u01a4\u01a5\7p\2\2\u01a5\u01a6\7r\2\2\u01a6") - buf.write(u"\u01a7\7w\2\2\u01a7\u01a8\7v\2\2\u01a8H\3\2\2\2\u01a9") - buf.write(u"\u01aa\7q\2\2\u01aa\u01ab\7w\2\2\u01ab\u01ac\7v\2\2\u01ac") - buf.write(u"\u01ad\7r\2\2\u01ad\u01ae\7w\2\2\u01ae\u01af\7v\2\2\u01af") - buf.write(u"J\3\2\2\2\u01b0\u01b1\7e\2\2\u01b1\u01b2\7w\2\2\u01b2") - buf.write(u"\u01b3\7t\2\2\u01b3\u01b4\7t\2\2\u01b4\u01b5\7g\2\2\u01b5") - buf.write(u"\u01b6\7p\2\2\u01b6\u01b7\7v\2\2\u01b7L\3\2\2\2\u01b8") - buf.write(u"\u01b9\7u\2\2\u01b9\u01ba\7r\2\2\u01ba\u01bb\7k\2\2\u01bb") - buf.write(u"\u01bc\7m\2\2\u01bc\u01bd\7g\2\2\u01bdN\3\2\2\2\u01be") - buf.write(u"\u01bf\7k\2\2\u01bf\u01c0\7p\2\2\u01c0\u01c1\7j\2\2\u01c1") - buf.write(u"\u01c2\7k\2\2\u01c2\u01c3\7d\2\2\u01c3\u01c4\7k\2\2\u01c4") - buf.write(u"\u01c5\7v\2\2\u01c5\u01c6\7q\2\2\u01c6\u01c7\7t\2\2\u01c7") - buf.write(u"\u01c8\7{\2\2\u01c8P\3\2\2\2\u01c9\u01ca\7g\2\2\u01ca") - buf.write(u"\u01cb\7z\2\2\u01cb\u01cc\7e\2\2\u01cc\u01cd\7k\2\2\u01cd") - buf.write(u"\u01ce\7v\2\2\u01ce\u01cf\7c\2\2\u01cf\u01d0\7v\2\2\u01d0") - buf.write(u"\u01d1\7q\2\2\u01d1\u01d2\7t\2\2\u01d2\u01d3\7{\2\2\u01d3") - buf.write(u"R\3\2\2\2\u01d4\u01d5\7\60\2\2\u01d5\u01d6\7\60\2\2\u01d6") - buf.write(u"\u01d7\7\60\2\2\u01d7T\3\2\2\2\u01d8\u01d9\7*\2\2\u01d9") - buf.write(u"V\3\2\2\2\u01da\u01db\7+\2\2\u01dbX\3\2\2\2\u01dc\u01dd") - buf.write(u"\7-\2\2\u01ddZ\3\2\2\2\u01de\u01df\7\u0080\2\2\u01df") - buf.write(u"\\\3\2\2\2\u01e0\u01e1\7~\2\2\u01e1^\3\2\2\2\u01e2\u01e3") - buf.write(u"\7`\2\2\u01e3`\3\2\2\2\u01e4\u01e5\7(\2\2\u01e5b\3\2") - buf.write(u"\2\2\u01e6\u01e7\7]\2\2\u01e7d\3\2\2\2\u01e8\u01e9\7") - buf.write(u">\2\2\u01e9\u01ea\7/\2\2\u01eaf\3\2\2\2\u01eb\u01ec\7") - buf.write(u"_\2\2\u01ech\3\2\2\2\u01ed\u01ee\7]\2\2\u01ee\u01ef\7") - buf.write(u"]\2\2\u01efj\3\2\2\2\u01f0\u01f1\7_\2\2\u01f1\u01f2\7") - buf.write(u"_\2\2\u01f2l\3\2\2\2\u01f3\u01f4\7>\2\2\u01f4\u01f5\7") - buf.write(u">\2\2\u01f5n\3\2\2\2\u01f6\u01f7\7@\2\2\u01f7\u01f8\7") - buf.write(u"@\2\2\u01f8p\3\2\2\2\u01f9\u01fa\7>\2\2\u01far\3\2\2") - buf.write(u"\2\u01fb\u01fc\7@\2\2\u01fct\3\2\2\2\u01fd\u01fe\7>\2") - buf.write(u"\2\u01fe\u01ff\7?\2\2\u01ffv\3\2\2\2\u0200\u0201\7-\2") - buf.write(u"\2\u0201\u0202\7?\2\2\u0202x\3\2\2\2\u0203\u0204\7/\2") - buf.write(u"\2\u0204\u0205\7?\2\2\u0205z\3\2\2\2\u0206\u0207\7,\2") - buf.write(u"\2\u0207\u0208\7?\2\2\u0208|\3\2\2\2\u0209\u020a\7\61") - buf.write(u"\2\2\u020a\u020b\7?\2\2\u020b~\3\2\2\2\u020c\u020d\7") - buf.write(u"?\2\2\u020d\u020e\7?\2\2\u020e\u0080\3\2\2\2\u020f\u0210") - buf.write(u"\7#\2\2\u0210\u0211\7?\2\2\u0211\u0082\3\2\2\2\u0212") - buf.write(u"\u0213\7>\2\2\u0213\u0214\7@\2\2\u0214\u0084\3\2\2\2") - buf.write(u"\u0215\u0216\7@\2\2\u0216\u0217\7?\2\2\u0217\u0086\3") - buf.write(u"\2\2\2\u0218\u0219\7.\2\2\u0219\u0088\3\2\2\2\u021a\u021b") - buf.write(u"\7/\2\2\u021b\u008a\3\2\2\2\u021c\u021d\7?\2\2\u021d") - buf.write(u"\u008c\3\2\2\2\u021e\u021f\7,\2\2\u021f\u008e\3\2\2\2") - buf.write(u"\u0220\u0221\7,\2\2\u0221\u0222\7,\2\2\u0222\u0090\3") - buf.write(u"\2\2\2\u0223\u0224\7\61\2\2\u0224\u0092\3\2\2\2\u0225") - buf.write(u"\u0226\7\'\2\2\u0226\u0094\3\2\2\2\u0227\u0228\7A\2\2") - buf.write(u"\u0228\u0096\3\2\2\2\u0229\u022a\7<\2\2\u022a\u0098\3") - buf.write(u"\2\2\2\u022b\u022c\7=\2\2\u022c\u009a\3\2\2\2\u022d\u022e") - buf.write(u"\7)\2\2\u022e\u009c\3\2\2\2\u022f\u0230\7v\2\2\u0230") - buf.write(u"\u0231\7t\2\2\u0231\u0232\7w\2\2\u0232\u0242\7g\2\2\u0233") - buf.write(u"\u0234\7V\2\2\u0234\u0235\7t\2\2\u0235\u0236\7w\2\2\u0236") - buf.write(u"\u0242\7g\2\2\u0237\u0238\7h\2\2\u0238\u0239\7c\2\2\u0239") - buf.write(u"\u023a\7n\2\2\u023a\u023b\7u\2\2\u023b\u0242\7g\2\2\u023c") - buf.write(u"\u023d\7H\2\2\u023d\u023e\7c\2\2\u023e\u023f\7n\2\2\u023f") - buf.write(u"\u0240\7u\2\2\u0240\u0242\7g\2\2\u0241\u022f\3\2\2\2") - buf.write(u"\u0241\u0233\3\2\2\2\u0241\u0237\3\2\2\2\u0241\u023c") - buf.write(u"\3\2\2\2\u0242\u009e\3\2\2\2\u0243\u0245\7$\2\2\u0244") - buf.write(u"\u0246\t\4\2\2\u0245\u0244\3\2\2\2\u0246\u024a\3\2\2") - buf.write(u"\2\u0247\u0249\t\5\2\2\u0248\u0247\3\2\2\2\u0249\u024c") - buf.write(u"\3\2\2\2\u024a\u0248\3\2\2\2\u024a\u024b\3\2\2\2\u024b") - buf.write(u"\u024d\3\2\2\2\u024c\u024a\3\2\2\2\u024d\u024e\7$\2\2") - buf.write(u"\u024e\u00a0\3\2\2\2\u024f\u0251\t\4\2\2\u0250\u024f") - buf.write(u"\3\2\2\2\u0251\u0255\3\2\2\2\u0252\u0254\t\5\2\2\u0253") - buf.write(u"\u0252\3\2\2\2\u0254\u0257\3\2\2\2\u0255\u0253\3\2\2") - buf.write(u"\2\u0255\u0256\3\2\2\2\u0256\u00a2\3\2\2\2\u0257\u0255") - buf.write(u"\3\2\2\2\u0258\u025a\t\6\2\2\u0259\u0258\3\2\2\2\u025a") - buf.write(u"\u025b\3\2\2\2\u025b\u0259\3\2\2\2\u025b\u025c\3\2\2") - buf.write(u"\2\u025c\u00a4\3\2\2\2\u025d\u0260\5\u00a7T\2\u025e\u0260") - buf.write(u"\5\u00a9U\2\u025f\u025d\3\2\2\2\u025f\u025e\3\2\2\2\u0260") - buf.write(u"\u00a6\3\2\2\2\u0261\u0263\5\u00a3R\2\u0262\u0261\3\2") - buf.write(u"\2\2\u0262\u0263\3\2\2\2\u0263\u0264\3\2\2\2\u0264\u0265") - buf.write(u"\7\60\2\2\u0265\u026a\5\u00a3R\2\u0266\u0267\5\u00a3") - buf.write(u"R\2\u0267\u0268\7\60\2\2\u0268\u026a\3\2\2\2\u0269\u0262") - buf.write(u"\3\2\2\2\u0269\u0266\3\2\2\2\u026a\u00a8\3\2\2\2\u026b") - buf.write(u"\u026e\5\u00a3R\2\u026c\u026e\5\u00a7T\2\u026d\u026b") - buf.write(u"\3\2\2\2\u026d\u026c\3\2\2\2\u026e\u026f\3\2\2\2\u026f") - buf.write(u"\u0270\t\7\2\2\u0270\u0271\5\u00abV\2\u0271\u00aa\3\2") - buf.write(u"\2\2\u0272\u0275\5Y-\2\u0273\u0275\5\u0089E\2\u0274\u0272") - buf.write(u"\3\2\2\2\u0274\u0273\3\2\2\2\u0274\u0275\3\2\2\2\u0275") - buf.write(u"\u0276\3\2\2\2\u0276\u0277\5\u00a3R\2\u0277\u00ac\3\2") - buf.write(u"\2\2\26\2\u00b1\u00bc\u00c8\u00ce\u00d5\u00df\u0241\u0245") - buf.write(u"\u0248\u024a\u0250\u0253\u0255\u025b\u025f\u0262\u0269") - buf.write(u"\u026d\u0274\5\2\4\2\2\5\2\2\3\2") - return buf.getvalue() - + return [ + 4,0,88,688,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, + 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, + 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, + 26,7,26,2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7, + 32,2,33,7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2, + 39,7,39,2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,2,44,7,44,2,45,7, + 45,2,46,7,46,2,47,7,47,2,48,7,48,2,49,7,49,2,50,7,50,2,51,7,51,2, + 52,7,52,2,53,7,53,2,54,7,54,2,55,7,55,2,56,7,56,2,57,7,57,2,58,7, + 58,2,59,7,59,2,60,7,60,2,61,7,61,2,62,7,62,2,63,7,63,2,64,7,64,2, + 65,7,65,2,66,7,66,2,67,7,67,2,68,7,68,2,69,7,69,2,70,7,70,2,71,7, + 71,2,72,7,72,2,73,7,73,2,74,7,74,2,75,7,75,2,76,7,76,2,77,7,77,2, + 78,7,78,2,79,7,79,2,80,7,80,2,81,7,81,2,82,7,82,2,83,7,83,2,84,7, + 84,2,85,7,85,2,86,7,86,2,87,7,87,2,88,7,88,2,89,7,89,2,90,7,90,2, + 91,7,91,1,0,1,0,1,0,1,0,1,1,3,1,191,8,1,1,1,1,1,1,2,1,2,1,2,1,2, + 1,3,1,3,1,3,1,3,1,3,1,4,1,4,5,4,206,8,4,10,4,12,4,209,9,4,1,4,1, + 4,4,4,213,8,4,11,4,12,4,214,1,4,1,4,1,5,1,5,5,5,221,8,5,10,5,12, + 5,224,9,5,1,5,1,5,1,5,1,5,1,6,3,6,231,8,6,1,6,1,6,1,7,1,7,1,7,1, + 7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,1,10, + 1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11, + 1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13, + 1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15, + 1,15,1,15,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18, + 1,18,1,18,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,1,21, + 1,21,1,21,1,22,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23,1,24,1,24, + 1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,27,1,27,1,27,1,27, + 1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,28, + 1,28,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30, + 1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,31,1,31,1,32,1,32,1,32,1,32, + 1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1,33, + 1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,35,1,35, + 1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36, + 1,36,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38, + 1,38,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39,1,39,1,39,1,39, + 1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,41,1,41,1,41,1,41, + 1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,42,1,42,1,42, + 1,42,1,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43, + 1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44, + 1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,45,1,45,1,46,1,46,1,46,1,46, + 1,47,1,47,1,48,1,48,1,49,1,49,1,50,1,50,1,51,1,51,1,52,1,52,1,53, + 1,53,1,54,1,54,1,55,1,55,1,55,1,56,1,56,1,57,1,57,1,57,1,58,1,58, + 1,58,1,59,1,59,1,59,1,60,1,60,1,60,1,61,1,61,1,62,1,62,1,63,1,63, + 1,63,1,64,1,64,1,64,1,65,1,65,1,65,1,66,1,66,1,66,1,67,1,67,1,67, + 1,68,1,68,1,68,1,69,1,69,1,69,1,70,1,70,1,70,1,71,1,71,1,71,1,72, + 1,72,1,73,1,73,1,74,1,74,1,75,1,75,1,76,1,76,1,76,1,77,1,77,1,78, + 1,78,1,79,1,79,1,80,1,80,1,81,1,81,1,81,1,82,1,82,1,83,1,83,1,84, + 1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84, + 1,84,1,84,1,84,1,84,3,84,622,8,84,1,85,1,85,1,85,4,85,627,8,85,11, + 85,12,85,628,1,85,3,85,632,8,85,1,85,3,85,635,8,85,1,85,3,85,638, + 8,85,1,85,5,85,641,8,85,10,85,12,85,644,9,85,1,85,1,85,1,86,3,86, + 649,8,86,1,86,5,86,652,8,86,10,86,12,86,655,9,86,1,87,4,87,658,8, + 87,11,87,12,87,659,1,88,1,88,3,88,664,8,88,1,89,3,89,667,8,89,1, + 89,1,89,1,89,1,89,1,89,3,89,674,8,89,1,90,1,90,3,90,678,8,90,1,90, + 1,90,1,90,1,91,1,91,3,91,685,8,91,1,91,1,91,2,207,214,0,92,1,1,3, + 0,5,2,7,3,9,4,11,5,13,6,15,7,17,8,19,9,21,10,23,11,25,12,27,13,29, + 14,31,15,33,16,35,17,37,18,39,19,41,20,43,21,45,22,47,23,49,24,51, + 25,53,26,55,27,57,28,59,29,61,30,63,31,65,32,67,33,69,34,71,35,73, + 36,75,37,77,38,79,39,81,40,83,41,85,42,87,43,89,44,91,45,93,46,95, + 47,97,48,99,49,101,50,103,51,105,52,107,53,109,54,111,55,113,56, + 115,57,117,58,119,59,121,60,123,61,125,62,127,63,129,64,131,65,133, + 66,135,67,137,68,139,69,141,70,143,71,145,72,147,73,149,74,151,75, + 153,76,155,77,157,78,159,79,161,80,163,81,165,82,167,83,169,84,171, + 85,173,86,175,87,177,88,179,0,181,0,183,0,1,0,7,2,0,9,9,32,32,2, + 0,10,10,13,13,4,0,10,10,13,13,34,34,92,92,4,0,36,36,65,90,95,95, + 97,122,5,0,36,36,48,57,65,90,95,95,97,122,1,0,48,57,2,0,69,69,101, + 101,705,0,1,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0, + 0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0, + 0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0, + 0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0, + 0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0, + 0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0, + 0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0, + 0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0, + 0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0,0,0,91,1,0, + 0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0,0,0,101,1, + 0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109,1,0,0,0,0, + 111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0,117,1,0,0,0,0,119,1,0, + 0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0,0,0,0,127,1,0,0,0,0,129, + 1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0,0,135,1,0,0,0,0,137,1,0,0,0, + 0,139,1,0,0,0,0,141,1,0,0,0,0,143,1,0,0,0,0,145,1,0,0,0,0,147,1, + 0,0,0,0,149,1,0,0,0,0,151,1,0,0,0,0,153,1,0,0,0,0,155,1,0,0,0,0, + 157,1,0,0,0,0,159,1,0,0,0,0,161,1,0,0,0,0,163,1,0,0,0,0,165,1,0, + 0,0,0,167,1,0,0,0,0,169,1,0,0,0,0,171,1,0,0,0,0,173,1,0,0,0,0,175, + 1,0,0,0,0,177,1,0,0,0,1,185,1,0,0,0,3,190,1,0,0,0,5,194,1,0,0,0, + 7,198,1,0,0,0,9,203,1,0,0,0,11,218,1,0,0,0,13,230,1,0,0,0,15,234, + 1,0,0,0,17,238,1,0,0,0,19,246,1,0,0,0,21,251,1,0,0,0,23,258,1,0, + 0,0,25,266,1,0,0,0,27,271,1,0,0,0,29,280,1,0,0,0,31,287,1,0,0,0, + 33,294,1,0,0,0,35,297,1,0,0,0,37,302,1,0,0,0,39,307,1,0,0,0,41,311, + 1,0,0,0,43,317,1,0,0,0,45,320,1,0,0,0,47,325,1,0,0,0,49,329,1,0, + 0,0,51,333,1,0,0,0,53,336,1,0,0,0,55,340,1,0,0,0,57,351,1,0,0,0, + 59,358,1,0,0,0,61,365,1,0,0,0,63,373,1,0,0,0,65,379,1,0,0,0,67,390, + 1,0,0,0,69,400,1,0,0,0,71,407,1,0,0,0,73,417,1,0,0,0,75,423,1,0, + 0,0,77,430,1,0,0,0,79,441,1,0,0,0,81,451,1,0,0,0,83,457,1,0,0,0, + 85,468,1,0,0,0,87,479,1,0,0,0,89,492,1,0,0,0,91,507,1,0,0,0,93,509, + 1,0,0,0,95,513,1,0,0,0,97,515,1,0,0,0,99,517,1,0,0,0,101,519,1,0, + 0,0,103,521,1,0,0,0,105,523,1,0,0,0,107,525,1,0,0,0,109,527,1,0, + 0,0,111,529,1,0,0,0,113,532,1,0,0,0,115,534,1,0,0,0,117,537,1,0, + 0,0,119,540,1,0,0,0,121,543,1,0,0,0,123,546,1,0,0,0,125,548,1,0, + 0,0,127,550,1,0,0,0,129,553,1,0,0,0,131,556,1,0,0,0,133,559,1,0, + 0,0,135,562,1,0,0,0,137,565,1,0,0,0,139,568,1,0,0,0,141,571,1,0, + 0,0,143,574,1,0,0,0,145,577,1,0,0,0,147,579,1,0,0,0,149,581,1,0, + 0,0,151,583,1,0,0,0,153,585,1,0,0,0,155,588,1,0,0,0,157,590,1,0, + 0,0,159,592,1,0,0,0,161,594,1,0,0,0,163,596,1,0,0,0,165,599,1,0, + 0,0,167,601,1,0,0,0,169,621,1,0,0,0,171,623,1,0,0,0,173,648,1,0, + 0,0,175,657,1,0,0,0,177,663,1,0,0,0,179,673,1,0,0,0,181,677,1,0, + 0,0,183,684,1,0,0,0,185,186,5,34,0,0,186,187,5,34,0,0,187,188,5, + 34,0,0,188,2,1,0,0,0,189,191,5,13,0,0,190,189,1,0,0,0,190,191,1, + 0,0,0,191,192,1,0,0,0,192,193,5,10,0,0,193,4,1,0,0,0,194,195,7,0, + 0,0,195,196,1,0,0,0,196,197,6,2,0,0,197,6,1,0,0,0,198,199,5,92,0, + 0,199,200,3,3,1,0,200,201,1,0,0,0,201,202,6,3,0,0,202,8,1,0,0,0, + 203,207,3,1,0,0,204,206,9,0,0,0,205,204,1,0,0,0,206,209,1,0,0,0, + 207,208,1,0,0,0,207,205,1,0,0,0,208,210,1,0,0,0,209,207,1,0,0,0, + 210,212,3,1,0,0,211,213,3,3,1,0,212,211,1,0,0,0,213,214,1,0,0,0, + 214,215,1,0,0,0,214,212,1,0,0,0,215,216,1,0,0,0,216,217,6,4,1,0, + 217,10,1,0,0,0,218,222,5,35,0,0,219,221,8,1,0,0,220,219,1,0,0,0, + 221,224,1,0,0,0,222,220,1,0,0,0,222,223,1,0,0,0,223,225,1,0,0,0, + 224,222,1,0,0,0,225,226,3,3,1,0,226,227,1,0,0,0,227,228,6,5,1,0, + 228,12,1,0,0,0,229,231,5,13,0,0,230,229,1,0,0,0,230,231,1,0,0,0, + 231,232,1,0,0,0,232,233,5,10,0,0,233,14,1,0,0,0,234,235,5,101,0, + 0,235,236,5,110,0,0,236,237,5,100,0,0,237,16,1,0,0,0,238,239,5,105, + 0,0,239,240,5,110,0,0,240,241,5,116,0,0,241,242,5,101,0,0,242,243, + 5,103,0,0,243,244,5,101,0,0,244,245,5,114,0,0,245,18,1,0,0,0,246, + 247,5,114,0,0,247,248,5,101,0,0,248,249,5,97,0,0,249,250,5,108,0, + 0,250,20,1,0,0,0,251,252,5,115,0,0,252,253,5,116,0,0,253,254,5,114, + 0,0,254,255,5,105,0,0,255,256,5,110,0,0,256,257,5,103,0,0,257,22, + 1,0,0,0,258,259,5,98,0,0,259,260,5,111,0,0,260,261,5,111,0,0,261, + 262,5,108,0,0,262,263,5,101,0,0,263,264,5,97,0,0,264,265,5,110,0, + 0,265,24,1,0,0,0,266,267,5,118,0,0,267,268,5,111,0,0,268,269,5,105, + 0,0,269,270,5,100,0,0,270,26,1,0,0,0,271,272,5,102,0,0,272,273,5, + 117,0,0,273,274,5,110,0,0,274,275,5,99,0,0,275,276,5,116,0,0,276, + 277,5,105,0,0,277,278,5,111,0,0,278,279,5,110,0,0,279,28,1,0,0,0, + 280,281,5,105,0,0,281,282,5,110,0,0,282,283,5,108,0,0,283,284,5, + 105,0,0,284,285,5,110,0,0,285,286,5,101,0,0,286,30,1,0,0,0,287,288, + 5,114,0,0,288,289,5,101,0,0,289,290,5,116,0,0,290,291,5,117,0,0, + 291,292,5,114,0,0,292,293,5,110,0,0,293,32,1,0,0,0,294,295,5,105, + 0,0,295,296,5,102,0,0,296,34,1,0,0,0,297,298,5,101,0,0,298,299,5, + 108,0,0,299,300,5,105,0,0,300,301,5,102,0,0,301,36,1,0,0,0,302,303, + 5,101,0,0,303,304,5,108,0,0,304,305,5,115,0,0,305,306,5,101,0,0, + 306,38,1,0,0,0,307,308,5,102,0,0,308,309,5,111,0,0,309,310,5,114, + 0,0,310,40,1,0,0,0,311,312,5,119,0,0,312,313,5,104,0,0,313,314,5, + 105,0,0,314,315,5,108,0,0,315,316,5,101,0,0,316,42,1,0,0,0,317,318, + 5,105,0,0,318,319,5,110,0,0,319,44,1,0,0,0,320,321,5,115,0,0,321, + 322,5,116,0,0,322,323,5,101,0,0,323,324,5,112,0,0,324,46,1,0,0,0, + 325,326,5,105,0,0,326,327,5,110,0,0,327,328,5,102,0,0,328,48,1,0, + 0,0,329,330,5,97,0,0,330,331,5,110,0,0,331,332,5,100,0,0,332,50, + 1,0,0,0,333,334,5,111,0,0,334,335,5,114,0,0,335,52,1,0,0,0,336,337, + 5,110,0,0,337,338,5,111,0,0,338,339,5,116,0,0,339,54,1,0,0,0,340, + 341,5,114,0,0,341,342,5,101,0,0,342,343,5,99,0,0,343,344,5,111,0, + 0,344,345,5,114,0,0,345,346,5,100,0,0,346,347,5,97,0,0,347,348,5, + 98,0,0,348,349,5,108,0,0,349,350,5,101,0,0,350,56,1,0,0,0,351,352, + 5,107,0,0,352,353,5,101,0,0,353,354,5,114,0,0,354,355,5,110,0,0, + 355,356,5,101,0,0,356,357,5,108,0,0,357,58,1,0,0,0,358,359,5,110, + 0,0,359,360,5,101,0,0,360,361,5,117,0,0,361,362,5,114,0,0,362,363, + 5,111,0,0,363,364,5,110,0,0,364,60,1,0,0,0,365,366,5,115,0,0,366, + 367,5,121,0,0,367,368,5,110,0,0,368,369,5,97,0,0,369,370,5,112,0, + 0,370,371,5,115,0,0,371,372,5,101,0,0,372,62,1,0,0,0,373,374,5,115, + 0,0,374,375,5,116,0,0,375,376,5,97,0,0,376,377,5,116,0,0,377,378, + 5,101,0,0,378,64,1,0,0,0,379,380,5,112,0,0,380,381,5,97,0,0,381, + 382,5,114,0,0,382,383,5,97,0,0,383,384,5,109,0,0,384,385,5,101,0, + 0,385,386,5,116,0,0,386,387,5,101,0,0,387,388,5,114,0,0,388,389, + 5,115,0,0,389,66,1,0,0,0,390,391,5,105,0,0,391,392,5,110,0,0,392, + 393,5,116,0,0,393,394,5,101,0,0,394,395,5,114,0,0,395,396,5,110, + 0,0,396,397,5,97,0,0,397,398,5,108,0,0,398,399,5,115,0,0,399,68, + 1,0,0,0,400,401,5,117,0,0,401,402,5,112,0,0,402,403,5,100,0,0,403, + 404,5,97,0,0,404,405,5,116,0,0,405,406,5,101,0,0,406,70,1,0,0,0, + 407,408,5,101,0,0,408,409,5,113,0,0,409,410,5,117,0,0,410,411,5, + 97,0,0,411,412,5,116,0,0,412,413,5,105,0,0,413,414,5,111,0,0,414, + 415,5,110,0,0,415,416,5,115,0,0,416,72,1,0,0,0,417,418,5,105,0,0, + 418,419,5,110,0,0,419,420,5,112,0,0,420,421,5,117,0,0,421,422,5, + 116,0,0,422,74,1,0,0,0,423,424,5,111,0,0,424,425,5,117,0,0,425,426, + 5,116,0,0,426,427,5,112,0,0,427,428,5,117,0,0,428,429,5,116,0,0, + 429,76,1,0,0,0,430,431,5,99,0,0,431,432,5,111,0,0,432,433,5,110, + 0,0,433,434,5,116,0,0,434,435,5,105,0,0,435,436,5,110,0,0,436,437, + 5,117,0,0,437,438,5,111,0,0,438,439,5,117,0,0,439,440,5,115,0,0, + 440,78,1,0,0,0,441,442,5,111,0,0,442,443,5,110,0,0,443,444,5,82, + 0,0,444,445,5,101,0,0,445,446,5,99,0,0,446,447,5,101,0,0,447,448, + 5,105,0,0,448,449,5,118,0,0,449,450,5,101,0,0,450,80,1,0,0,0,451, + 452,5,115,0,0,452,453,5,112,0,0,453,454,5,105,0,0,454,455,5,107, + 0,0,455,456,5,101,0,0,456,82,1,0,0,0,457,458,5,105,0,0,458,459,5, + 110,0,0,459,460,5,104,0,0,460,461,5,105,0,0,461,462,5,98,0,0,462, + 463,5,105,0,0,463,464,5,116,0,0,464,465,5,111,0,0,465,466,5,114, + 0,0,466,467,5,121,0,0,467,84,1,0,0,0,468,469,5,101,0,0,469,470,5, + 120,0,0,470,471,5,99,0,0,471,472,5,105,0,0,472,473,5,116,0,0,473, + 474,5,97,0,0,474,475,5,116,0,0,475,476,5,111,0,0,476,477,5,114,0, + 0,477,478,5,121,0,0,478,86,1,0,0,0,479,480,5,64,0,0,480,481,5,104, + 0,0,481,482,5,111,0,0,482,483,5,109,0,0,483,484,5,111,0,0,484,485, + 5,103,0,0,485,486,5,101,0,0,486,487,5,110,0,0,487,488,5,101,0,0, + 488,489,5,111,0,0,489,490,5,117,0,0,490,491,5,115,0,0,491,88,1,0, + 0,0,492,493,5,64,0,0,493,494,5,104,0,0,494,495,5,101,0,0,495,496, + 5,116,0,0,496,497,5,101,0,0,497,498,5,114,0,0,498,499,5,111,0,0, + 499,500,5,103,0,0,500,501,5,101,0,0,501,502,5,110,0,0,502,503,5, + 101,0,0,503,504,5,111,0,0,504,505,5,117,0,0,505,506,5,115,0,0,506, + 90,1,0,0,0,507,508,5,64,0,0,508,92,1,0,0,0,509,510,5,46,0,0,510, + 511,5,46,0,0,511,512,5,46,0,0,512,94,1,0,0,0,513,514,5,40,0,0,514, + 96,1,0,0,0,515,516,5,41,0,0,516,98,1,0,0,0,517,518,5,43,0,0,518, + 100,1,0,0,0,519,520,5,126,0,0,520,102,1,0,0,0,521,522,5,124,0,0, + 522,104,1,0,0,0,523,524,5,94,0,0,524,106,1,0,0,0,525,526,5,38,0, + 0,526,108,1,0,0,0,527,528,5,91,0,0,528,110,1,0,0,0,529,530,5,60, + 0,0,530,531,5,45,0,0,531,112,1,0,0,0,532,533,5,93,0,0,533,114,1, + 0,0,0,534,535,5,91,0,0,535,536,5,91,0,0,536,116,1,0,0,0,537,538, + 5,93,0,0,538,539,5,93,0,0,539,118,1,0,0,0,540,541,5,60,0,0,541,542, + 5,60,0,0,542,120,1,0,0,0,543,544,5,62,0,0,544,545,5,62,0,0,545,122, + 1,0,0,0,546,547,5,60,0,0,547,124,1,0,0,0,548,549,5,62,0,0,549,126, + 1,0,0,0,550,551,5,60,0,0,551,552,5,61,0,0,552,128,1,0,0,0,553,554, + 5,43,0,0,554,555,5,61,0,0,555,130,1,0,0,0,556,557,5,45,0,0,557,558, + 5,61,0,0,558,132,1,0,0,0,559,560,5,42,0,0,560,561,5,61,0,0,561,134, + 1,0,0,0,562,563,5,47,0,0,563,564,5,61,0,0,564,136,1,0,0,0,565,566, + 5,61,0,0,566,567,5,61,0,0,567,138,1,0,0,0,568,569,5,33,0,0,569,570, + 5,61,0,0,570,140,1,0,0,0,571,572,5,60,0,0,572,573,5,62,0,0,573,142, + 1,0,0,0,574,575,5,62,0,0,575,576,5,61,0,0,576,144,1,0,0,0,577,578, + 5,44,0,0,578,146,1,0,0,0,579,580,5,45,0,0,580,148,1,0,0,0,581,582, + 5,61,0,0,582,150,1,0,0,0,583,584,5,42,0,0,584,152,1,0,0,0,585,586, + 5,42,0,0,586,587,5,42,0,0,587,154,1,0,0,0,588,589,5,47,0,0,589,156, + 1,0,0,0,590,591,5,37,0,0,591,158,1,0,0,0,592,593,5,63,0,0,593,160, + 1,0,0,0,594,595,5,58,0,0,595,162,1,0,0,0,596,597,5,58,0,0,597,598, + 5,58,0,0,598,164,1,0,0,0,599,600,5,59,0,0,600,166,1,0,0,0,601,602, + 5,39,0,0,602,168,1,0,0,0,603,604,5,116,0,0,604,605,5,114,0,0,605, + 606,5,117,0,0,606,622,5,101,0,0,607,608,5,84,0,0,608,609,5,114,0, + 0,609,610,5,117,0,0,610,622,5,101,0,0,611,612,5,102,0,0,612,613, + 5,97,0,0,613,614,5,108,0,0,614,615,5,115,0,0,615,622,5,101,0,0,616, + 617,5,70,0,0,617,618,5,97,0,0,618,619,5,108,0,0,619,620,5,115,0, + 0,620,622,5,101,0,0,621,603,1,0,0,0,621,607,1,0,0,0,621,611,1,0, + 0,0,621,616,1,0,0,0,622,170,1,0,0,0,623,642,5,34,0,0,624,637,5,92, + 0,0,625,627,7,0,0,0,626,625,1,0,0,0,627,628,1,0,0,0,628,626,1,0, + 0,0,628,629,1,0,0,0,629,634,1,0,0,0,630,632,5,13,0,0,631,630,1,0, + 0,0,631,632,1,0,0,0,632,633,1,0,0,0,633,635,5,10,0,0,634,631,1,0, + 0,0,634,635,1,0,0,0,635,638,1,0,0,0,636,638,9,0,0,0,637,626,1,0, + 0,0,637,636,1,0,0,0,638,641,1,0,0,0,639,641,8,2,0,0,640,624,1,0, + 0,0,640,639,1,0,0,0,641,644,1,0,0,0,642,640,1,0,0,0,642,643,1,0, + 0,0,643,645,1,0,0,0,644,642,1,0,0,0,645,646,5,34,0,0,646,172,1,0, + 0,0,647,649,7,3,0,0,648,647,1,0,0,0,649,653,1,0,0,0,650,652,7,4, + 0,0,651,650,1,0,0,0,652,655,1,0,0,0,653,651,1,0,0,0,653,654,1,0, + 0,0,654,174,1,0,0,0,655,653,1,0,0,0,656,658,7,5,0,0,657,656,1,0, + 0,0,658,659,1,0,0,0,659,657,1,0,0,0,659,660,1,0,0,0,660,176,1,0, + 0,0,661,664,3,179,89,0,662,664,3,181,90,0,663,661,1,0,0,0,663,662, + 1,0,0,0,664,178,1,0,0,0,665,667,3,175,87,0,666,665,1,0,0,0,666,667, + 1,0,0,0,667,668,1,0,0,0,668,669,5,46,0,0,669,674,3,175,87,0,670, + 671,3,175,87,0,671,672,5,46,0,0,672,674,1,0,0,0,673,666,1,0,0,0, + 673,670,1,0,0,0,674,180,1,0,0,0,675,678,3,175,87,0,676,678,3,179, + 89,0,677,675,1,0,0,0,677,676,1,0,0,0,678,679,1,0,0,0,679,680,7,6, + 0,0,680,681,3,183,91,0,681,182,1,0,0,0,682,685,3,99,49,0,683,685, + 3,147,73,0,684,682,1,0,0,0,684,683,1,0,0,0,684,685,1,0,0,0,685,686, + 1,0,0,0,686,687,3,175,87,0,687,184,1,0,0,0,22,0,190,207,214,222, + 230,621,628,631,634,637,640,642,648,651,653,659,663,666,673,677, + 684,2,0,1,0,0,2,0 + ] class PyNestMLLexer(Lexer): @@ -291,161 +264,169 @@ class PyNestMLLexer(Lexer): decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] COMMENT = 2 - NEW_LINE = 3 - SL_COMMENT = 1 - ML_COMMENT = 2 - NEWLINE = 3 - WS = 4 - LINE_ESCAPE = 5 - END_KEYWORD = 6 - INTEGER_KEYWORD = 7 - REAL_KEYWORD = 8 - STRING_KEYWORD = 9 - BOOLEAN_KEYWORD = 10 - VOID_KEYWORD = 11 - FUNCTION_KEYWORD = 12 - INLINE_KEYWORD = 13 - RETURN_KEYWORD = 14 - IF_KEYWORD = 15 - ELIF_KEYWORD = 16 - ELSE_KEYWORD = 17 - FOR_KEYWORD = 18 - WHILE_KEYWORD = 19 - IN_KEYWORD = 20 - STEP_KEYWORD = 21 - INF_KEYWORD = 22 - AND_KEYWORD = 23 - OR_KEYWORD = 24 - NOT_KEYWORD = 25 - RECORDABLE_KEYWORD = 26 - KERNEL_KEYWORD = 27 - NEURON_KEYWORD = 28 - STATE_KEYWORD = 29 - PARAMETERS_KEYWORD = 30 - INTERNALS_KEYWORD = 31 - INITIAL_VALUES_KEYWORD = 32 - UPDATE_KEYWORD = 33 - EQUATIONS_KEYWORD = 34 - INPUT_KEYWORD = 35 - OUTPUT_KEYWORD = 36 - CURRENT_KEYWORD = 37 - SPIKE_KEYWORD = 38 - INHIBITORY_KEYWORD = 39 - EXCITATORY_KEYWORD = 40 - ELLIPSIS = 41 - LEFT_PAREN = 42 - RIGHT_PAREN = 43 - PLUS = 44 - TILDE = 45 - PIPE = 46 - CARET = 47 - AMPERSAND = 48 - LEFT_SQUARE_BRACKET = 49 - LEFT_ANGLE_MINUS = 50 - RIGHT_SQUARE_BRACKET = 51 - LEFT_LEFT_SQUARE = 52 - RIGHT_RIGHT_SQUARE = 53 - LEFT_LEFT_ANGLE = 54 - RIGHT_RIGHT_ANGLE = 55 - LEFT_ANGLE = 56 - RIGHT_ANGLE = 57 - LEFT_ANGLE_EQUALS = 58 - PLUS_EQUALS = 59 - MINUS_EQUALS = 60 - STAR_EQUALS = 61 - FORWARD_SLASH_EQUALS = 62 - EQUALS_EQUALS = 63 - EXCLAMATION_EQUALS = 64 - LEFT_ANGLE_RIGHT_ANGLE = 65 - RIGHT_ANGLE_EQUALS = 66 - COMMA = 67 - MINUS = 68 - EQUALS = 69 - STAR = 70 - STAR_STAR = 71 - FORWARD_SLASH = 72 - PERCENT = 73 - QUESTION = 74 - COLON = 75 - SEMICOLON = 76 - DIFFERENTIAL_ORDER = 77 - BOOLEAN_LITERAL = 78 - STRING_LITERAL = 79 - NAME = 80 - UNSIGNED_INTEGER = 81 - FLOAT = 82 + DOCSTRING_TRIPLEQUOTE = 1 + WS = 2 + LINE_ESCAPE = 3 + DOCSTRING = 4 + SL_COMMENT = 5 + NEWLINE = 6 + END_KEYWORD = 7 + INTEGER_KEYWORD = 8 + REAL_KEYWORD = 9 + STRING_KEYWORD = 10 + BOOLEAN_KEYWORD = 11 + VOID_KEYWORD = 12 + FUNCTION_KEYWORD = 13 + INLINE_KEYWORD = 14 + RETURN_KEYWORD = 15 + IF_KEYWORD = 16 + ELIF_KEYWORD = 17 + ELSE_KEYWORD = 18 + FOR_KEYWORD = 19 + WHILE_KEYWORD = 20 + IN_KEYWORD = 21 + STEP_KEYWORD = 22 + INF_KEYWORD = 23 + AND_KEYWORD = 24 + OR_KEYWORD = 25 + NOT_KEYWORD = 26 + RECORDABLE_KEYWORD = 27 + KERNEL_KEYWORD = 28 + NEURON_KEYWORD = 29 + SYNAPSE_KEYWORD = 30 + STATE_KEYWORD = 31 + PARAMETERS_KEYWORD = 32 + INTERNALS_KEYWORD = 33 + UPDATE_KEYWORD = 34 + EQUATIONS_KEYWORD = 35 + INPUT_KEYWORD = 36 + OUTPUT_KEYWORD = 37 + CONTINUOUS_KEYWORD = 38 + ON_RECEIVE_KEYWORD = 39 + SPIKE_KEYWORD = 40 + INHIBITORY_KEYWORD = 41 + EXCITATORY_KEYWORD = 42 + DECORATOR_HOMOGENEOUS = 43 + DECORATOR_HETEROGENEOUS = 44 + AT = 45 + ELLIPSIS = 46 + LEFT_PAREN = 47 + RIGHT_PAREN = 48 + PLUS = 49 + TILDE = 50 + PIPE = 51 + CARET = 52 + AMPERSAND = 53 + LEFT_SQUARE_BRACKET = 54 + LEFT_ANGLE_MINUS = 55 + RIGHT_SQUARE_BRACKET = 56 + LEFT_LEFT_SQUARE = 57 + RIGHT_RIGHT_SQUARE = 58 + LEFT_LEFT_ANGLE = 59 + RIGHT_RIGHT_ANGLE = 60 + LEFT_ANGLE = 61 + RIGHT_ANGLE = 62 + LEFT_ANGLE_EQUALS = 63 + PLUS_EQUALS = 64 + MINUS_EQUALS = 65 + STAR_EQUALS = 66 + FORWARD_SLASH_EQUALS = 67 + EQUALS_EQUALS = 68 + EXCLAMATION_EQUALS = 69 + LEFT_ANGLE_RIGHT_ANGLE = 70 + RIGHT_ANGLE_EQUALS = 71 + COMMA = 72 + MINUS = 73 + EQUALS = 74 + STAR = 75 + STAR_STAR = 76 + FORWARD_SLASH = 77 + PERCENT = 78 + QUESTION = 79 + COLON = 80 + DOUBLE_COLON = 81 + SEMICOLON = 82 + DIFFERENTIAL_ORDER = 83 + BOOLEAN_LITERAL = 84 + STRING_LITERAL = 85 + NAME = 86 + UNSIGNED_INTEGER = 87 + FLOAT = 88 - channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN", u"COMMENT", u"NEW_LINE" ] + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN", u"COMMENT" ] - modeNames = [ u"DEFAULT_MODE" ] + modeNames = [ "DEFAULT_MODE" ] - literalNames = [ u"", - u"'end'", u"'integer'", u"'real'", u"'string'", u"'boolean'", - u"'void'", u"'function'", u"'inline'", u"'return'", u"'if'", - u"'elif'", u"'else'", u"'for'", u"'while'", u"'in'", u"'step'", - u"'inf'", u"'and'", u"'or'", u"'not'", u"'recordable'", u"'kernel'", - u"'neuron'", u"'state'", u"'parameters'", u"'internals'", u"'initial_values'", - u"'update'", u"'equations'", u"'input'", u"'output'", u"'current'", - u"'spike'", u"'inhibitory'", u"'excitatory'", u"'...'", u"'('", - u"')'", u"'+'", u"'~'", u"'|'", u"'^'", u"'&'", u"'['", u"'<-'", - u"']'", u"'[['", u"']]'", u"'<<'", u"'>>'", u"'<'", u"'>'", - u"'<='", u"'+='", u"'-='", u"'*='", u"'/='", u"'=='", u"'!='", - u"'<>'", u"'>='", u"','", u"'-'", u"'='", u"'*'", u"'**'", u"'/'", - u"'%'", u"'?'", u"':'", u"';'", u"'''" ] + literalNames = [ "", + "'\"\"\"'", "'end'", "'integer'", "'real'", "'string'", "'boolean'", + "'void'", "'function'", "'inline'", "'return'", "'if'", "'elif'", + "'else'", "'for'", "'while'", "'in'", "'step'", "'inf'", "'and'", + "'or'", "'not'", "'recordable'", "'kernel'", "'neuron'", "'synapse'", + "'state'", "'parameters'", "'internals'", "'update'", "'equations'", + "'input'", "'output'", "'continuous'", "'onReceive'", "'spike'", + "'inhibitory'", "'excitatory'", "'@homogeneous'", "'@heterogeneous'", + "'@'", "'...'", "'('", "')'", "'+'", "'~'", "'|'", "'^'", "'&'", + "'['", "'<-'", "']'", "'[['", "']]'", "'<<'", "'>>'", "'<'", + "'>'", "'<='", "'+='", "'-='", "'*='", "'/='", "'=='", "'!='", + "'<>'", "'>='", "','", "'-'", "'='", "'*'", "'**'", "'/'", "'%'", + "'?'", "':'", "'::'", "';'", "'''" ] - symbolicNames = [ u"", - u"SL_COMMENT", u"ML_COMMENT", u"NEWLINE", u"WS", u"LINE_ESCAPE", - u"END_KEYWORD", u"INTEGER_KEYWORD", u"REAL_KEYWORD", u"STRING_KEYWORD", - u"BOOLEAN_KEYWORD", u"VOID_KEYWORD", u"FUNCTION_KEYWORD", u"INLINE_KEYWORD", - u"RETURN_KEYWORD", u"IF_KEYWORD", u"ELIF_KEYWORD", u"ELSE_KEYWORD", - u"FOR_KEYWORD", u"WHILE_KEYWORD", u"IN_KEYWORD", u"STEP_KEYWORD", - u"INF_KEYWORD", u"AND_KEYWORD", u"OR_KEYWORD", u"NOT_KEYWORD", - u"RECORDABLE_KEYWORD", u"KERNEL_KEYWORD", u"NEURON_KEYWORD", - u"STATE_KEYWORD", u"PARAMETERS_KEYWORD", u"INTERNALS_KEYWORD", - u"INITIAL_VALUES_KEYWORD", u"UPDATE_KEYWORD", u"EQUATIONS_KEYWORD", - u"INPUT_KEYWORD", u"OUTPUT_KEYWORD", u"CURRENT_KEYWORD", u"SPIKE_KEYWORD", - u"INHIBITORY_KEYWORD", u"EXCITATORY_KEYWORD", u"ELLIPSIS", u"LEFT_PAREN", - u"RIGHT_PAREN", u"PLUS", u"TILDE", u"PIPE", u"CARET", u"AMPERSAND", - u"LEFT_SQUARE_BRACKET", u"LEFT_ANGLE_MINUS", u"RIGHT_SQUARE_BRACKET", - u"LEFT_LEFT_SQUARE", u"RIGHT_RIGHT_SQUARE", u"LEFT_LEFT_ANGLE", - u"RIGHT_RIGHT_ANGLE", u"LEFT_ANGLE", u"RIGHT_ANGLE", u"LEFT_ANGLE_EQUALS", - u"PLUS_EQUALS", u"MINUS_EQUALS", u"STAR_EQUALS", u"FORWARD_SLASH_EQUALS", - u"EQUALS_EQUALS", u"EXCLAMATION_EQUALS", u"LEFT_ANGLE_RIGHT_ANGLE", - u"RIGHT_ANGLE_EQUALS", u"COMMA", u"MINUS", u"EQUALS", u"STAR", - u"STAR_STAR", u"FORWARD_SLASH", u"PERCENT", u"QUESTION", u"COLON", - u"SEMICOLON", u"DIFFERENTIAL_ORDER", u"BOOLEAN_LITERAL", u"STRING_LITERAL", - u"NAME", u"UNSIGNED_INTEGER", u"FLOAT" ] + symbolicNames = [ "", + "DOCSTRING_TRIPLEQUOTE", "WS", "LINE_ESCAPE", "DOCSTRING", "SL_COMMENT", + "NEWLINE", "END_KEYWORD", "INTEGER_KEYWORD", "REAL_KEYWORD", + "STRING_KEYWORD", "BOOLEAN_KEYWORD", "VOID_KEYWORD", "FUNCTION_KEYWORD", + "INLINE_KEYWORD", "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", + "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", + "STEP_KEYWORD", "INF_KEYWORD", "AND_KEYWORD", "OR_KEYWORD", + "NOT_KEYWORD", "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", "NEURON_KEYWORD", + "SYNAPSE_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", + "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", "OUTPUT_KEYWORD", + "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", "SPIKE_KEYWORD", + "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", + "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", + "PLUS", "TILDE", "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", + "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", + "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", + "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", "PLUS_EQUALS", + "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", "EQUALS_EQUALS", + "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", "RIGHT_ANGLE_EQUALS", + "COMMA", "MINUS", "EQUALS", "STAR", "STAR_STAR", "FORWARD_SLASH", + "PERCENT", "QUESTION", "COLON", "DOUBLE_COLON", "SEMICOLON", + "DIFFERENTIAL_ORDER", "BOOLEAN_LITERAL", "STRING_LITERAL", "NAME", + "UNSIGNED_INTEGER", "FLOAT" ] - ruleNames = [ u"SL_COMMENT", u"ML_COMMENT", u"NEWLINE", u"WS", u"LINE_ESCAPE", - u"END_KEYWORD", u"INTEGER_KEYWORD", u"REAL_KEYWORD", u"STRING_KEYWORD", - u"BOOLEAN_KEYWORD", u"VOID_KEYWORD", u"FUNCTION_KEYWORD", - u"INLINE_KEYWORD", u"RETURN_KEYWORD", u"IF_KEYWORD", u"ELIF_KEYWORD", - u"ELSE_KEYWORD", u"FOR_KEYWORD", u"WHILE_KEYWORD", u"IN_KEYWORD", - u"STEP_KEYWORD", u"INF_KEYWORD", u"AND_KEYWORD", u"OR_KEYWORD", - u"NOT_KEYWORD", u"RECORDABLE_KEYWORD", u"KERNEL_KEYWORD", - u"NEURON_KEYWORD", u"STATE_KEYWORD", u"PARAMETERS_KEYWORD", - u"INTERNALS_KEYWORD", u"INITIAL_VALUES_KEYWORD", u"UPDATE_KEYWORD", - u"EQUATIONS_KEYWORD", u"INPUT_KEYWORD", u"OUTPUT_KEYWORD", - u"CURRENT_KEYWORD", u"SPIKE_KEYWORD", u"INHIBITORY_KEYWORD", - u"EXCITATORY_KEYWORD", u"ELLIPSIS", u"LEFT_PAREN", u"RIGHT_PAREN", - u"PLUS", u"TILDE", u"PIPE", u"CARET", u"AMPERSAND", u"LEFT_SQUARE_BRACKET", - u"LEFT_ANGLE_MINUS", u"RIGHT_SQUARE_BRACKET", u"LEFT_LEFT_SQUARE", - u"RIGHT_RIGHT_SQUARE", u"LEFT_LEFT_ANGLE", u"RIGHT_RIGHT_ANGLE", - u"LEFT_ANGLE", u"RIGHT_ANGLE", u"LEFT_ANGLE_EQUALS", u"PLUS_EQUALS", - u"MINUS_EQUALS", u"STAR_EQUALS", u"FORWARD_SLASH_EQUALS", - u"EQUALS_EQUALS", u"EXCLAMATION_EQUALS", u"LEFT_ANGLE_RIGHT_ANGLE", - u"RIGHT_ANGLE_EQUALS", u"COMMA", u"MINUS", u"EQUALS", - u"STAR", u"STAR_STAR", u"FORWARD_SLASH", u"PERCENT", u"QUESTION", - u"COLON", u"SEMICOLON", u"DIFFERENTIAL_ORDER", u"BOOLEAN_LITERAL", - u"STRING_LITERAL", u"NAME", u"UNSIGNED_INTEGER", u"FLOAT", - u"POINT_FLOAT", u"EXPONENT_FLOAT", u"EXPONENT" ] + ruleNames = [ "DOCSTRING_TRIPLEQUOTE", "NEWLINE_FRAG", "WS", "LINE_ESCAPE", + "DOCSTRING", "SL_COMMENT", "NEWLINE", "END_KEYWORD", "INTEGER_KEYWORD", + "REAL_KEYWORD", "STRING_KEYWORD", "BOOLEAN_KEYWORD", "VOID_KEYWORD", + "FUNCTION_KEYWORD", "INLINE_KEYWORD", "RETURN_KEYWORD", + "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", + "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", + "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", + "KERNEL_KEYWORD", "NEURON_KEYWORD", "SYNAPSE_KEYWORD", + "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", + "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", + "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", + "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", + "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", "AT", + "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", + "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", + "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", + "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", + "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", "PLUS_EQUALS", "MINUS_EQUALS", + "STAR_EQUALS", "FORWARD_SLASH_EQUALS", "EQUALS_EQUALS", + "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", "RIGHT_ANGLE_EQUALS", + "COMMA", "MINUS", "EQUALS", "STAR", "STAR_STAR", "FORWARD_SLASH", + "PERCENT", "QUESTION", "COLON", "DOUBLE_COLON", "SEMICOLON", + "DIFFERENTIAL_ORDER", "BOOLEAN_LITERAL", "STRING_LITERAL", + "NAME", "UNSIGNED_INTEGER", "FLOAT", "POINT_FLOAT", "EXPONENT_FLOAT", + "EXPONENT" ] - grammarFileName = u"PyNestMLLexer.g4" + grammarFileName = "PyNestMLLexer.g4" - def __init__(self, input=None, output=sys.stdout): - super(PyNestMLLexer, self).__init__(input, output=output) - self.checkVersion("4.7.1") + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.10") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/pynestml/generated/PyNestMLLexer.tokens b/pynestml/generated/PyNestMLLexer.tokens deleted file mode 100644 index a8c14cc33..000000000 --- a/pynestml/generated/PyNestMLLexer.tokens +++ /dev/null @@ -1,154 +0,0 @@ -SL_COMMENT=1 -ML_COMMENT=2 -NEWLINE=3 -WS=4 -LINE_ESCAPE=5 -END_KEYWORD=6 -INTEGER_KEYWORD=7 -REAL_KEYWORD=8 -STRING_KEYWORD=9 -BOOLEAN_KEYWORD=10 -VOID_KEYWORD=11 -FUNCTION_KEYWORD=12 -INLINE_KEYWORD=13 -RETURN_KEYWORD=14 -IF_KEYWORD=15 -ELIF_KEYWORD=16 -ELSE_KEYWORD=17 -FOR_KEYWORD=18 -WHILE_KEYWORD=19 -IN_KEYWORD=20 -STEP_KEYWORD=21 -INF_KEYWORD=22 -AND_KEYWORD=23 -OR_KEYWORD=24 -NOT_KEYWORD=25 -RECORDABLE_KEYWORD=26 -KERNEL_KEYWORD=27 -NEURON_KEYWORD=28 -STATE_KEYWORD=29 -PARAMETERS_KEYWORD=30 -INTERNALS_KEYWORD=31 -INITIAL_VALUES_KEYWORD=32 -UPDATE_KEYWORD=33 -EQUATIONS_KEYWORD=34 -INPUT_KEYWORD=35 -OUTPUT_KEYWORD=36 -CURRENT_KEYWORD=37 -SPIKE_KEYWORD=38 -INHIBITORY_KEYWORD=39 -EXCITATORY_KEYWORD=40 -ELLIPSIS=41 -LEFT_PAREN=42 -RIGHT_PAREN=43 -PLUS=44 -TILDE=45 -PIPE=46 -CARET=47 -AMPERSAND=48 -LEFT_SQUARE_BRACKET=49 -LEFT_ANGLE_MINUS=50 -RIGHT_SQUARE_BRACKET=51 -LEFT_LEFT_SQUARE=52 -RIGHT_RIGHT_SQUARE=53 -LEFT_LEFT_ANGLE=54 -RIGHT_RIGHT_ANGLE=55 -LEFT_ANGLE=56 -RIGHT_ANGLE=57 -LEFT_ANGLE_EQUALS=58 -PLUS_EQUALS=59 -MINUS_EQUALS=60 -STAR_EQUALS=61 -FORWARD_SLASH_EQUALS=62 -EQUALS_EQUALS=63 -EXCLAMATION_EQUALS=64 -LEFT_ANGLE_RIGHT_ANGLE=65 -RIGHT_ANGLE_EQUALS=66 -COMMA=67 -MINUS=68 -EQUALS=69 -STAR=70 -STAR_STAR=71 -FORWARD_SLASH=72 -PERCENT=73 -QUESTION=74 -COLON=75 -SEMICOLON=76 -DIFFERENTIAL_ORDER=77 -BOOLEAN_LITERAL=78 -STRING_LITERAL=79 -NAME=80 -UNSIGNED_INTEGER=81 -FLOAT=82 -'end'=6 -'integer'=7 -'real'=8 -'string'=9 -'boolean'=10 -'void'=11 -'function'=12 -'inline'=13 -'return'=14 -'if'=15 -'elif'=16 -'else'=17 -'for'=18 -'while'=19 -'in'=20 -'step'=21 -'inf'=22 -'and'=23 -'or'=24 -'not'=25 -'recordable'=26 -'kernel'=27 -'neuron'=28 -'state'=29 -'parameters'=30 -'internals'=31 -'initial_values'=32 -'update'=33 -'equations'=34 -'input'=35 -'output'=36 -'current'=37 -'spike'=38 -'inhibitory'=39 -'excitatory'=40 -'...'=41 -'('=42 -')'=43 -'+'=44 -'~'=45 -'|'=46 -'^'=47 -'&'=48 -'['=49 -'<-'=50 -']'=51 -'[['=52 -']]'=53 -'<<'=54 -'>>'=55 -'<'=56 -'>'=57 -'<='=58 -'+='=59 -'-='=60 -'*='=61 -'/='=62 -'=='=63 -'!='=64 -'<>'=65 -'>='=66 -','=67 -'-'=68 -'='=69 -'*'=70 -'**'=71 -'/'=72 -'%'=73 -'?'=74 -':'=75 -';'=76 -'\''=77 diff --git a/pynestml/generated/PyNestMLParser.interp b/pynestml/generated/PyNestMLParser.interp index 1b8516b27..b66002e41 100644 --- a/pynestml/generated/PyNestMLParser.interp +++ b/pynestml/generated/PyNestMLParser.interp @@ -1,5 +1,6 @@ token literal names: null +'"""' null null null @@ -28,18 +29,22 @@ null 'recordable' 'kernel' 'neuron' +'synapse' 'state' 'parameters' 'internals' -'initial_values' 'update' 'equations' 'input' 'output' -'current' +'continuous' +'onReceive' 'spike' 'inhibitory' 'excitatory' +'@homogeneous' +'@heterogeneous' +'@' '...' '(' ')' @@ -75,6 +80,7 @@ null '%' '?' ':' +'::' ';' '\'' null @@ -85,11 +91,12 @@ null token symbolic names: null -SL_COMMENT -ML_COMMENT -NEWLINE +DOCSTRING_TRIPLEQUOTE WS LINE_ESCAPE +DOCSTRING +SL_COMMENT +NEWLINE END_KEYWORD INTEGER_KEYWORD REAL_KEYWORD @@ -113,18 +120,22 @@ NOT_KEYWORD RECORDABLE_KEYWORD KERNEL_KEYWORD NEURON_KEYWORD +SYNAPSE_KEYWORD STATE_KEYWORD PARAMETERS_KEYWORD INTERNALS_KEYWORD -INITIAL_VALUES_KEYWORD UPDATE_KEYWORD EQUATIONS_KEYWORD INPUT_KEYWORD OUTPUT_KEYWORD -CURRENT_KEYWORD +CONTINUOUS_KEYWORD +ON_RECEIVE_KEYWORD SPIKE_KEYWORD INHIBITORY_KEYWORD EXCITATORY_KEYWORD +DECORATOR_HOMOGENEOUS +DECORATOR_HETEROGENEOUS +AT ELLIPSIS LEFT_PAREN RIGHT_PAREN @@ -160,6 +171,7 @@ FORWARD_SLASH PERCENT QUESTION COLON +DOUBLE_COLON SEMICOLON DIFFERENTIAL_ORDER BOOLEAN_LITERAL @@ -178,6 +190,7 @@ unaryOperator bitOperator comparisonOperator logicalOperator +indexParameter variable functionCall inlineExpression @@ -189,6 +202,9 @@ compoundStmt smallStmt assignment declaration +anyDecorator +namespaceDecoratorNamespace +namespaceDecoratorName returnStmt ifStmt ifClause @@ -198,7 +214,10 @@ forStmt whileStmt nestMLCompilationUnit neuron -body +neuronBody +synapse +synapseBody +onReceiveBlock blockWithVariables updateBlock equationsBlock @@ -208,7 +227,8 @@ inputQualifier outputBlock function parameter +constParameter atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 84, 497, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 87, 10, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 98, 10, 3, 3, 3, 3, 3, 3, 3, 5, 3, 103, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 109, 10, 3, 12, 3, 14, 3, 112, 11, 3, 3, 4, 5, 4, 115, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 130, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 139, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 145, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 7, 5, 166, 10, 5, 12, 5, 14, 5, 169, 11, 5, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 175, 10, 6, 3, 6, 3, 6, 3, 6, 5, 6, 180, 10, 6, 3, 7, 3, 7, 3, 7, 5, 7, 185, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 192, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 201, 10, 9, 3, 10, 3, 10, 5, 10, 205, 10, 10, 3, 11, 3, 11, 7, 11, 209, 10, 11, 12, 11, 14, 11, 212, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 219, 10, 12, 12, 12, 14, 12, 222, 11, 12, 5, 12, 224, 10, 12, 3, 12, 3, 12, 3, 13, 5, 13, 229, 10, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 237, 10, 13, 3, 14, 3, 14, 3, 14, 3, 14, 5, 14, 243, 10, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 7, 15, 254, 10, 15, 12, 15, 14, 15, 257, 11, 15, 3, 15, 5, 15, 260, 10, 15, 3, 16, 3, 16, 7, 16, 264, 10, 16, 12, 16, 14, 16, 267, 11, 16, 3, 17, 3, 17, 5, 17, 271, 10, 17, 3, 18, 3, 18, 3, 18, 5, 18, 276, 10, 18, 3, 19, 3, 19, 3, 19, 3, 19, 5, 19, 282, 10, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 290, 10, 20, 3, 20, 3, 20, 3, 21, 5, 21, 295, 10, 21, 3, 21, 5, 21, 298, 10, 21, 3, 21, 3, 21, 3, 21, 7, 21, 303, 10, 21, 12, 21, 14, 21, 306, 11, 21, 3, 21, 3, 21, 3, 21, 3, 21, 5, 21, 312, 10, 21, 3, 21, 3, 21, 5, 21, 316, 10, 21, 3, 21, 3, 21, 3, 21, 3, 21, 5, 21, 322, 10, 21, 3, 22, 3, 22, 5, 22, 326, 10, 22, 3, 23, 3, 23, 7, 23, 330, 10, 23, 12, 23, 14, 23, 333, 11, 23, 3, 23, 5, 23, 336, 10, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 362, 10, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 7, 29, 377, 10, 29, 12, 29, 14, 29, 380, 11, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 7, 31, 396, 10, 31, 12, 31, 14, 31, 399, 11, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 7, 32, 407, 10, 32, 12, 32, 14, 32, 410, 11, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 7, 34, 425, 10, 34, 12, 34, 14, 34, 428, 11, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 7, 35, 436, 10, 35, 12, 35, 14, 35, 439, 11, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 5, 36, 447, 10, 36, 3, 36, 5, 36, 450, 10, 36, 3, 36, 3, 36, 7, 36, 454, 10, 36, 12, 36, 14, 36, 457, 11, 36, 3, 36, 3, 36, 5, 36, 461, 10, 36, 3, 37, 3, 37, 5, 37, 465, 10, 37, 3, 38, 3, 38, 3, 38, 3, 38, 5, 38, 471, 10, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 7, 39, 479, 10, 39, 12, 39, 14, 39, 482, 11, 39, 5, 39, 484, 10, 39, 3, 39, 3, 39, 5, 39, 488, 10, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 2, 4, 4, 8, 41, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 2, 5, 4, 2, 46, 46, 70, 70, 3, 2, 83, 84, 3, 2, 31, 34, 2, 556, 2, 86, 3, 2, 2, 2, 4, 97, 3, 2, 2, 2, 6, 114, 3, 2, 2, 2, 8, 129, 3, 2, 2, 2, 10, 179, 3, 2, 2, 2, 12, 184, 3, 2, 2, 2, 14, 191, 3, 2, 2, 2, 16, 200, 3, 2, 2, 2, 18, 204, 3, 2, 2, 2, 20, 206, 3, 2, 2, 2, 22, 213, 3, 2, 2, 2, 24, 228, 3, 2, 2, 2, 26, 238, 3, 2, 2, 2, 28, 244, 3, 2, 2, 2, 30, 265, 3, 2, 2, 2, 32, 270, 3, 2, 2, 2, 34, 275, 3, 2, 2, 2, 36, 281, 3, 2, 2, 2, 38, 283, 3, 2, 2, 2, 40, 294, 3, 2, 2, 2, 42, 323, 3, 2, 2, 2, 44, 327, 3, 2, 2, 2, 46, 339, 3, 2, 2, 2, 48, 344, 3, 2, 2, 2, 50, 349, 3, 2, 2, 2, 52, 353, 3, 2, 2, 2, 54, 368, 3, 2, 2, 2, 56, 378, 3, 2, 2, 2, 58, 383, 3, 2, 2, 2, 60, 387, 3, 2, 2, 2, 62, 402, 3, 2, 2, 2, 64, 413, 3, 2, 2, 2, 66, 418, 3, 2, 2, 2, 68, 431, 3, 2, 2, 2, 70, 442, 3, 2, 2, 2, 72, 464, 3, 2, 2, 2, 74, 466, 3, 2, 2, 2, 76, 472, 3, 2, 2, 2, 78, 493, 3, 2, 2, 2, 80, 87, 7, 9, 2, 2, 81, 87, 7, 10, 2, 2, 82, 87, 7, 11, 2, 2, 83, 87, 7, 12, 2, 2, 84, 87, 7, 13, 2, 2, 85, 87, 5, 4, 3, 2, 86, 80, 3, 2, 2, 2, 86, 81, 3, 2, 2, 2, 86, 82, 3, 2, 2, 2, 86, 83, 3, 2, 2, 2, 86, 84, 3, 2, 2, 2, 86, 85, 3, 2, 2, 2, 87, 3, 3, 2, 2, 2, 88, 89, 8, 3, 1, 2, 89, 90, 7, 44, 2, 2, 90, 91, 5, 4, 3, 2, 91, 92, 7, 45, 2, 2, 92, 98, 3, 2, 2, 2, 93, 94, 7, 83, 2, 2, 94, 95, 7, 74, 2, 2, 95, 98, 5, 4, 3, 4, 96, 98, 7, 82, 2, 2, 97, 88, 3, 2, 2, 2, 97, 93, 3, 2, 2, 2, 97, 96, 3, 2, 2, 2, 98, 110, 3, 2, 2, 2, 99, 102, 12, 5, 2, 2, 100, 103, 7, 72, 2, 2, 101, 103, 7, 74, 2, 2, 102, 100, 3, 2, 2, 2, 102, 101, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 109, 5, 4, 3, 6, 105, 106, 12, 6, 2, 2, 106, 107, 7, 73, 2, 2, 107, 109, 5, 6, 4, 2, 108, 99, 3, 2, 2, 2, 108, 105, 3, 2, 2, 2, 109, 112, 3, 2, 2, 2, 110, 108, 3, 2, 2, 2, 110, 111, 3, 2, 2, 2, 111, 5, 3, 2, 2, 2, 112, 110, 3, 2, 2, 2, 113, 115, 9, 2, 2, 2, 114, 113, 3, 2, 2, 2, 114, 115, 3, 2, 2, 2, 115, 116, 3, 2, 2, 2, 116, 117, 7, 83, 2, 2, 117, 7, 3, 2, 2, 2, 118, 119, 8, 5, 1, 2, 119, 120, 7, 44, 2, 2, 120, 121, 5, 8, 5, 2, 121, 122, 7, 45, 2, 2, 122, 130, 3, 2, 2, 2, 123, 124, 5, 12, 7, 2, 124, 125, 5, 8, 5, 11, 125, 130, 3, 2, 2, 2, 126, 127, 7, 27, 2, 2, 127, 130, 5, 8, 5, 6, 128, 130, 5, 10, 6, 2, 129, 118, 3, 2, 2, 2, 129, 123, 3, 2, 2, 2, 129, 126, 3, 2, 2, 2, 129, 128, 3, 2, 2, 2, 130, 167, 3, 2, 2, 2, 131, 132, 12, 12, 2, 2, 132, 133, 7, 73, 2, 2, 133, 166, 5, 8, 5, 12, 134, 138, 12, 10, 2, 2, 135, 139, 7, 72, 2, 2, 136, 139, 7, 74, 2, 2, 137, 139, 7, 75, 2, 2, 138, 135, 3, 2, 2, 2, 138, 136, 3, 2, 2, 2, 138, 137, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 166, 5, 8, 5, 11, 141, 144, 12, 9, 2, 2, 142, 145, 7, 46, 2, 2, 143, 145, 7, 70, 2, 2, 144, 142, 3, 2, 2, 2, 144, 143, 3, 2, 2, 2, 145, 146, 3, 2, 2, 2, 146, 166, 5, 8, 5, 10, 147, 148, 12, 8, 2, 2, 148, 149, 5, 14, 8, 2, 149, 150, 5, 8, 5, 9, 150, 166, 3, 2, 2, 2, 151, 152, 12, 7, 2, 2, 152, 153, 5, 16, 9, 2, 153, 154, 5, 8, 5, 8, 154, 166, 3, 2, 2, 2, 155, 156, 12, 5, 2, 2, 156, 157, 5, 18, 10, 2, 157, 158, 5, 8, 5, 6, 158, 166, 3, 2, 2, 2, 159, 160, 12, 4, 2, 2, 160, 161, 7, 76, 2, 2, 161, 162, 5, 8, 5, 2, 162, 163, 7, 77, 2, 2, 163, 164, 5, 8, 5, 5, 164, 166, 3, 2, 2, 2, 165, 131, 3, 2, 2, 2, 165, 134, 3, 2, 2, 2, 165, 141, 3, 2, 2, 2, 165, 147, 3, 2, 2, 2, 165, 151, 3, 2, 2, 2, 165, 155, 3, 2, 2, 2, 165, 159, 3, 2, 2, 2, 166, 169, 3, 2, 2, 2, 167, 165, 3, 2, 2, 2, 167, 168, 3, 2, 2, 2, 168, 9, 3, 2, 2, 2, 169, 167, 3, 2, 2, 2, 170, 180, 5, 22, 12, 2, 171, 180, 7, 80, 2, 2, 172, 174, 9, 3, 2, 2, 173, 175, 5, 20, 11, 2, 174, 173, 3, 2, 2, 2, 174, 175, 3, 2, 2, 2, 175, 180, 3, 2, 2, 2, 176, 180, 7, 81, 2, 2, 177, 180, 7, 24, 2, 2, 178, 180, 5, 20, 11, 2, 179, 170, 3, 2, 2, 2, 179, 171, 3, 2, 2, 2, 179, 172, 3, 2, 2, 2, 179, 176, 3, 2, 2, 2, 179, 177, 3, 2, 2, 2, 179, 178, 3, 2, 2, 2, 180, 11, 3, 2, 2, 2, 181, 185, 7, 46, 2, 2, 182, 185, 7, 70, 2, 2, 183, 185, 7, 47, 2, 2, 184, 181, 3, 2, 2, 2, 184, 182, 3, 2, 2, 2, 184, 183, 3, 2, 2, 2, 185, 13, 3, 2, 2, 2, 186, 192, 7, 50, 2, 2, 187, 192, 7, 49, 2, 2, 188, 192, 7, 48, 2, 2, 189, 192, 7, 56, 2, 2, 190, 192, 7, 57, 2, 2, 191, 186, 3, 2, 2, 2, 191, 187, 3, 2, 2, 2, 191, 188, 3, 2, 2, 2, 191, 189, 3, 2, 2, 2, 191, 190, 3, 2, 2, 2, 192, 15, 3, 2, 2, 2, 193, 201, 7, 58, 2, 2, 194, 201, 7, 60, 2, 2, 195, 201, 7, 65, 2, 2, 196, 201, 7, 66, 2, 2, 197, 201, 7, 67, 2, 2, 198, 201, 7, 68, 2, 2, 199, 201, 7, 59, 2, 2, 200, 193, 3, 2, 2, 2, 200, 194, 3, 2, 2, 2, 200, 195, 3, 2, 2, 2, 200, 196, 3, 2, 2, 2, 200, 197, 3, 2, 2, 2, 200, 198, 3, 2, 2, 2, 200, 199, 3, 2, 2, 2, 201, 17, 3, 2, 2, 2, 202, 205, 7, 25, 2, 2, 203, 205, 7, 26, 2, 2, 204, 202, 3, 2, 2, 2, 204, 203, 3, 2, 2, 2, 205, 19, 3, 2, 2, 2, 206, 210, 7, 82, 2, 2, 207, 209, 7, 79, 2, 2, 208, 207, 3, 2, 2, 2, 209, 212, 3, 2, 2, 2, 210, 208, 3, 2, 2, 2, 210, 211, 3, 2, 2, 2, 211, 21, 3, 2, 2, 2, 212, 210, 3, 2, 2, 2, 213, 214, 7, 82, 2, 2, 214, 223, 7, 44, 2, 2, 215, 220, 5, 8, 5, 2, 216, 217, 7, 69, 2, 2, 217, 219, 5, 8, 5, 2, 218, 216, 3, 2, 2, 2, 219, 222, 3, 2, 2, 2, 220, 218, 3, 2, 2, 2, 220, 221, 3, 2, 2, 2, 221, 224, 3, 2, 2, 2, 222, 220, 3, 2, 2, 2, 223, 215, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 225, 3, 2, 2, 2, 225, 226, 7, 45, 2, 2, 226, 23, 3, 2, 2, 2, 227, 229, 7, 28, 2, 2, 228, 227, 3, 2, 2, 2, 228, 229, 3, 2, 2, 2, 229, 230, 3, 2, 2, 2, 230, 231, 7, 15, 2, 2, 231, 232, 7, 82, 2, 2, 232, 233, 5, 2, 2, 2, 233, 234, 7, 71, 2, 2, 234, 236, 5, 8, 5, 2, 235, 237, 7, 78, 2, 2, 236, 235, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 25, 3, 2, 2, 2, 238, 239, 5, 20, 11, 2, 239, 240, 7, 71, 2, 2, 240, 242, 5, 8, 5, 2, 241, 243, 7, 78, 2, 2, 242, 241, 3, 2, 2, 2, 242, 243, 3, 2, 2, 2, 243, 27, 3, 2, 2, 2, 244, 245, 7, 29, 2, 2, 245, 246, 5, 20, 11, 2, 246, 247, 7, 71, 2, 2, 247, 255, 5, 8, 5, 2, 248, 249, 7, 69, 2, 2, 249, 250, 5, 20, 11, 2, 250, 251, 7, 71, 2, 2, 251, 252, 5, 8, 5, 2, 252, 254, 3, 2, 2, 2, 253, 248, 3, 2, 2, 2, 254, 257, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, 2, 256, 259, 3, 2, 2, 2, 257, 255, 3, 2, 2, 2, 258, 260, 7, 78, 2, 2, 259, 258, 3, 2, 2, 2, 259, 260, 3, 2, 2, 2, 260, 29, 3, 2, 2, 2, 261, 264, 5, 32, 17, 2, 262, 264, 7, 5, 2, 2, 263, 261, 3, 2, 2, 2, 263, 262, 3, 2, 2, 2, 264, 267, 3, 2, 2, 2, 265, 263, 3, 2, 2, 2, 265, 266, 3, 2, 2, 2, 266, 31, 3, 2, 2, 2, 267, 265, 3, 2, 2, 2, 268, 271, 5, 36, 19, 2, 269, 271, 5, 34, 18, 2, 270, 268, 3, 2, 2, 2, 270, 269, 3, 2, 2, 2, 271, 33, 3, 2, 2, 2, 272, 276, 5, 44, 23, 2, 273, 276, 5, 52, 27, 2, 274, 276, 5, 54, 28, 2, 275, 272, 3, 2, 2, 2, 275, 273, 3, 2, 2, 2, 275, 274, 3, 2, 2, 2, 276, 35, 3, 2, 2, 2, 277, 282, 5, 38, 20, 2, 278, 282, 5, 22, 12, 2, 279, 282, 5, 40, 21, 2, 280, 282, 5, 42, 22, 2, 281, 277, 3, 2, 2, 2, 281, 278, 3, 2, 2, 2, 281, 279, 3, 2, 2, 2, 281, 280, 3, 2, 2, 2, 282, 37, 3, 2, 2, 2, 283, 289, 5, 20, 11, 2, 284, 290, 7, 71, 2, 2, 285, 290, 7, 61, 2, 2, 286, 290, 7, 62, 2, 2, 287, 290, 7, 63, 2, 2, 288, 290, 7, 64, 2, 2, 289, 284, 3, 2, 2, 2, 289, 285, 3, 2, 2, 2, 289, 286, 3, 2, 2, 2, 289, 287, 3, 2, 2, 2, 289, 288, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 292, 5, 8, 5, 2, 292, 39, 3, 2, 2, 2, 293, 295, 7, 28, 2, 2, 294, 293, 3, 2, 2, 2, 294, 295, 3, 2, 2, 2, 295, 297, 3, 2, 2, 2, 296, 298, 7, 14, 2, 2, 297, 296, 3, 2, 2, 2, 297, 298, 3, 2, 2, 2, 298, 299, 3, 2, 2, 2, 299, 304, 5, 20, 11, 2, 300, 301, 7, 69, 2, 2, 301, 303, 5, 20, 11, 2, 302, 300, 3, 2, 2, 2, 303, 306, 3, 2, 2, 2, 304, 302, 3, 2, 2, 2, 304, 305, 3, 2, 2, 2, 305, 307, 3, 2, 2, 2, 306, 304, 3, 2, 2, 2, 307, 311, 5, 2, 2, 2, 308, 309, 7, 51, 2, 2, 309, 310, 7, 82, 2, 2, 310, 312, 7, 53, 2, 2, 311, 308, 3, 2, 2, 2, 311, 312, 3, 2, 2, 2, 312, 315, 3, 2, 2, 2, 313, 314, 7, 71, 2, 2, 314, 316, 5, 8, 5, 2, 315, 313, 3, 2, 2, 2, 315, 316, 3, 2, 2, 2, 316, 321, 3, 2, 2, 2, 317, 318, 7, 54, 2, 2, 318, 319, 5, 8, 5, 2, 319, 320, 7, 55, 2, 2, 320, 322, 3, 2, 2, 2, 321, 317, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 41, 3, 2, 2, 2, 323, 325, 7, 16, 2, 2, 324, 326, 5, 8, 5, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 43, 3, 2, 2, 2, 327, 331, 5, 46, 24, 2, 328, 330, 5, 48, 25, 2, 329, 328, 3, 2, 2, 2, 330, 333, 3, 2, 2, 2, 331, 329, 3, 2, 2, 2, 331, 332, 3, 2, 2, 2, 332, 335, 3, 2, 2, 2, 333, 331, 3, 2, 2, 2, 334, 336, 5, 50, 26, 2, 335, 334, 3, 2, 2, 2, 335, 336, 3, 2, 2, 2, 336, 337, 3, 2, 2, 2, 337, 338, 7, 8, 2, 2, 338, 45, 3, 2, 2, 2, 339, 340, 7, 17, 2, 2, 340, 341, 5, 8, 5, 2, 341, 342, 7, 77, 2, 2, 342, 343, 5, 30, 16, 2, 343, 47, 3, 2, 2, 2, 344, 345, 7, 18, 2, 2, 345, 346, 5, 8, 5, 2, 346, 347, 7, 77, 2, 2, 347, 348, 5, 30, 16, 2, 348, 49, 3, 2, 2, 2, 349, 350, 7, 19, 2, 2, 350, 351, 7, 77, 2, 2, 351, 352, 5, 30, 16, 2, 352, 51, 3, 2, 2, 2, 353, 354, 7, 20, 2, 2, 354, 355, 7, 82, 2, 2, 355, 356, 7, 22, 2, 2, 356, 357, 5, 8, 5, 2, 357, 358, 7, 43, 2, 2, 358, 359, 5, 8, 5, 2, 359, 361, 7, 23, 2, 2, 360, 362, 7, 70, 2, 2, 361, 360, 3, 2, 2, 2, 361, 362, 3, 2, 2, 2, 362, 363, 3, 2, 2, 2, 363, 364, 9, 3, 2, 2, 364, 365, 7, 77, 2, 2, 365, 366, 5, 30, 16, 2, 366, 367, 7, 8, 2, 2, 367, 53, 3, 2, 2, 2, 368, 369, 7, 21, 2, 2, 369, 370, 5, 8, 5, 2, 370, 371, 7, 77, 2, 2, 371, 372, 5, 30, 16, 2, 372, 373, 7, 8, 2, 2, 373, 55, 3, 2, 2, 2, 374, 377, 5, 58, 30, 2, 375, 377, 7, 5, 2, 2, 376, 374, 3, 2, 2, 2, 376, 375, 3, 2, 2, 2, 377, 380, 3, 2, 2, 2, 378, 376, 3, 2, 2, 2, 378, 379, 3, 2, 2, 2, 379, 381, 3, 2, 2, 2, 380, 378, 3, 2, 2, 2, 381, 382, 7, 2, 2, 3, 382, 57, 3, 2, 2, 2, 383, 384, 7, 30, 2, 2, 384, 385, 7, 82, 2, 2, 385, 386, 5, 60, 31, 2, 386, 59, 3, 2, 2, 2, 387, 397, 7, 77, 2, 2, 388, 396, 7, 5, 2, 2, 389, 396, 5, 62, 32, 2, 390, 396, 5, 66, 34, 2, 391, 396, 5, 68, 35, 2, 392, 396, 5, 74, 38, 2, 393, 396, 5, 64, 33, 2, 394, 396, 5, 76, 39, 2, 395, 388, 3, 2, 2, 2, 395, 389, 3, 2, 2, 2, 395, 390, 3, 2, 2, 2, 395, 391, 3, 2, 2, 2, 395, 392, 3, 2, 2, 2, 395, 393, 3, 2, 2, 2, 395, 394, 3, 2, 2, 2, 396, 399, 3, 2, 2, 2, 397, 395, 3, 2, 2, 2, 397, 398, 3, 2, 2, 2, 398, 400, 3, 2, 2, 2, 399, 397, 3, 2, 2, 2, 400, 401, 7, 8, 2, 2, 401, 61, 3, 2, 2, 2, 402, 403, 9, 4, 2, 2, 403, 408, 7, 77, 2, 2, 404, 407, 5, 40, 21, 2, 405, 407, 7, 5, 2, 2, 406, 404, 3, 2, 2, 2, 406, 405, 3, 2, 2, 2, 407, 410, 3, 2, 2, 2, 408, 406, 3, 2, 2, 2, 408, 409, 3, 2, 2, 2, 409, 411, 3, 2, 2, 2, 410, 408, 3, 2, 2, 2, 411, 412, 7, 8, 2, 2, 412, 63, 3, 2, 2, 2, 413, 414, 7, 35, 2, 2, 414, 415, 7, 77, 2, 2, 415, 416, 5, 30, 16, 2, 416, 417, 7, 8, 2, 2, 417, 65, 3, 2, 2, 2, 418, 419, 7, 36, 2, 2, 419, 426, 7, 77, 2, 2, 420, 425, 5, 24, 13, 2, 421, 425, 5, 26, 14, 2, 422, 425, 5, 28, 15, 2, 423, 425, 7, 5, 2, 2, 424, 420, 3, 2, 2, 2, 424, 421, 3, 2, 2, 2, 424, 422, 3, 2, 2, 2, 424, 423, 3, 2, 2, 2, 425, 428, 3, 2, 2, 2, 426, 424, 3, 2, 2, 2, 426, 427, 3, 2, 2, 2, 427, 429, 3, 2, 2, 2, 428, 426, 3, 2, 2, 2, 429, 430, 7, 8, 2, 2, 430, 67, 3, 2, 2, 2, 431, 432, 7, 37, 2, 2, 432, 437, 7, 77, 2, 2, 433, 436, 5, 70, 36, 2, 434, 436, 7, 5, 2, 2, 435, 433, 3, 2, 2, 2, 435, 434, 3, 2, 2, 2, 436, 439, 3, 2, 2, 2, 437, 435, 3, 2, 2, 2, 437, 438, 3, 2, 2, 2, 438, 440, 3, 2, 2, 2, 439, 437, 3, 2, 2, 2, 440, 441, 7, 8, 2, 2, 441, 69, 3, 2, 2, 2, 442, 446, 7, 82, 2, 2, 443, 444, 7, 51, 2, 2, 444, 445, 7, 82, 2, 2, 445, 447, 7, 53, 2, 2, 446, 443, 3, 2, 2, 2, 446, 447, 3, 2, 2, 2, 447, 449, 3, 2, 2, 2, 448, 450, 5, 2, 2, 2, 449, 448, 3, 2, 2, 2, 449, 450, 3, 2, 2, 2, 450, 451, 3, 2, 2, 2, 451, 455, 7, 52, 2, 2, 452, 454, 5, 72, 37, 2, 453, 452, 3, 2, 2, 2, 454, 457, 3, 2, 2, 2, 455, 453, 3, 2, 2, 2, 455, 456, 3, 2, 2, 2, 456, 460, 3, 2, 2, 2, 457, 455, 3, 2, 2, 2, 458, 461, 7, 39, 2, 2, 459, 461, 7, 40, 2, 2, 460, 458, 3, 2, 2, 2, 460, 459, 3, 2, 2, 2, 461, 71, 3, 2, 2, 2, 462, 465, 7, 41, 2, 2, 463, 465, 7, 42, 2, 2, 464, 462, 3, 2, 2, 2, 464, 463, 3, 2, 2, 2, 465, 73, 3, 2, 2, 2, 466, 467, 7, 38, 2, 2, 467, 470, 7, 77, 2, 2, 468, 471, 7, 40, 2, 2, 469, 471, 7, 39, 2, 2, 470, 468, 3, 2, 2, 2, 470, 469, 3, 2, 2, 2, 471, 75, 3, 2, 2, 2, 472, 473, 7, 14, 2, 2, 473, 474, 7, 82, 2, 2, 474, 483, 7, 44, 2, 2, 475, 480, 5, 78, 40, 2, 476, 477, 7, 69, 2, 2, 477, 479, 5, 78, 40, 2, 478, 476, 3, 2, 2, 2, 479, 482, 3, 2, 2, 2, 480, 478, 3, 2, 2, 2, 480, 481, 3, 2, 2, 2, 481, 484, 3, 2, 2, 2, 482, 480, 3, 2, 2, 2, 483, 475, 3, 2, 2, 2, 483, 484, 3, 2, 2, 2, 484, 485, 3, 2, 2, 2, 485, 487, 7, 45, 2, 2, 486, 488, 5, 2, 2, 2, 487, 486, 3, 2, 2, 2, 487, 488, 3, 2, 2, 2, 488, 489, 3, 2, 2, 2, 489, 490, 7, 77, 2, 2, 490, 491, 5, 30, 16, 2, 491, 492, 7, 8, 2, 2, 492, 77, 3, 2, 2, 2, 493, 494, 7, 82, 2, 2, 494, 495, 5, 2, 2, 2, 495, 79, 3, 2, 2, 2, 62, 86, 97, 102, 108, 110, 114, 129, 138, 144, 165, 167, 174, 179, 184, 191, 200, 204, 210, 220, 223, 228, 236, 242, 255, 259, 263, 265, 270, 275, 281, 289, 294, 297, 304, 311, 315, 321, 325, 331, 335, 361, 376, 378, 395, 397, 406, 408, 424, 426, 435, 437, 446, 449, 455, 460, 464, 470, 480, 483, 487] \ No newline at end of file +[4, 1, 88, 605, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 101, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 112, 8, 1, 1, 1, 1, 1, 1, 1, 3, 1, 117, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 123, 8, 1, 10, 1, 12, 1, 126, 9, 1, 1, 2, 3, 2, 129, 8, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 144, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 153, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 159, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 176, 8, 3, 10, 3, 12, 3, 179, 9, 3, 1, 3, 1, 3, 5, 3, 183, 8, 3, 10, 3, 12, 3, 186, 9, 3, 1, 3, 1, 3, 5, 3, 190, 8, 3, 10, 3, 12, 3, 193, 9, 3, 1, 3, 1, 3, 5, 3, 197, 8, 3, 10, 3, 12, 3, 200, 9, 3, 1, 3, 1, 3, 5, 3, 204, 8, 3, 10, 3, 12, 3, 207, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 213, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 218, 8, 4, 1, 5, 1, 5, 1, 5, 3, 5, 223, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 230, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 239, 8, 7, 1, 8, 1, 8, 3, 8, 243, 8, 8, 1, 9, 1, 9, 3, 9, 247, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 254, 8, 10, 1, 10, 5, 10, 257, 8, 10, 10, 10, 12, 10, 260, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 267, 8, 11, 10, 11, 12, 11, 270, 9, 11, 3, 11, 272, 8, 11, 1, 11, 1, 11, 1, 12, 3, 12, 277, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 285, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 291, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 299, 8, 14, 10, 14, 12, 14, 302, 9, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 308, 8, 14, 10, 14, 12, 14, 311, 9, 14, 1, 14, 3, 14, 314, 8, 14, 1, 15, 1, 15, 5, 15, 318, 8, 15, 10, 15, 12, 15, 321, 9, 15, 1, 16, 1, 16, 3, 16, 325, 8, 16, 1, 17, 1, 17, 1, 17, 3, 17, 330, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 336, 8, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 344, 8, 19, 1, 19, 1, 19, 1, 20, 3, 20, 349, 8, 20, 1, 20, 3, 20, 352, 8, 20, 1, 20, 1, 20, 1, 20, 5, 20, 357, 8, 20, 10, 20, 12, 20, 360, 9, 20, 1, 20, 1, 20, 1, 20, 3, 20, 365, 8, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 371, 8, 20, 1, 20, 5, 20, 374, 8, 20, 10, 20, 12, 20, 377, 9, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 386, 8, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 3, 24, 394, 8, 24, 1, 25, 1, 25, 5, 25, 398, 8, 25, 10, 25, 12, 25, 401, 9, 25, 1, 25, 3, 25, 404, 8, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 430, 8, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 5, 31, 446, 8, 31, 10, 31, 12, 31, 449, 9, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 5, 33, 465, 8, 33, 10, 33, 12, 33, 468, 9, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 485, 8, 35, 10, 35, 12, 35, 488, 9, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 497, 8, 36, 10, 36, 12, 36, 500, 9, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 511, 8, 37, 10, 37, 12, 37, 514, 9, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 529, 8, 39, 10, 39, 12, 39, 532, 9, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 540, 8, 40, 10, 40, 12, 40, 543, 9, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 551, 8, 41, 1, 41, 3, 41, 554, 8, 41, 1, 41, 1, 41, 5, 41, 558, 8, 41, 10, 41, 12, 41, 561, 9, 41, 1, 41, 1, 41, 3, 41, 565, 8, 41, 1, 42, 1, 42, 3, 42, 569, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 575, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 583, 8, 44, 10, 44, 12, 44, 586, 9, 44, 3, 44, 588, 8, 44, 1, 44, 1, 44, 3, 44, 592, 8, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 0, 2, 2, 6, 47, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 0, 4, 2, 0, 49, 49, 73, 73, 1, 0, 87, 88, 1, 0, 31, 33, 3, 0, 23, 23, 84, 85, 87, 88, 675, 0, 100, 1, 0, 0, 0, 2, 111, 1, 0, 0, 0, 4, 128, 1, 0, 0, 0, 6, 143, 1, 0, 0, 0, 8, 217, 1, 0, 0, 0, 10, 222, 1, 0, 0, 0, 12, 229, 1, 0, 0, 0, 14, 238, 1, 0, 0, 0, 16, 242, 1, 0, 0, 0, 18, 246, 1, 0, 0, 0, 20, 248, 1, 0, 0, 0, 22, 261, 1, 0, 0, 0, 24, 276, 1, 0, 0, 0, 26, 286, 1, 0, 0, 0, 28, 292, 1, 0, 0, 0, 30, 319, 1, 0, 0, 0, 32, 324, 1, 0, 0, 0, 34, 329, 1, 0, 0, 0, 36, 335, 1, 0, 0, 0, 38, 337, 1, 0, 0, 0, 40, 348, 1, 0, 0, 0, 42, 385, 1, 0, 0, 0, 44, 387, 1, 0, 0, 0, 46, 389, 1, 0, 0, 0, 48, 391, 1, 0, 0, 0, 50, 395, 1, 0, 0, 0, 52, 407, 1, 0, 0, 0, 54, 412, 1, 0, 0, 0, 56, 417, 1, 0, 0, 0, 58, 421, 1, 0, 0, 0, 60, 436, 1, 0, 0, 0, 62, 447, 1, 0, 0, 0, 64, 452, 1, 0, 0, 0, 66, 456, 1, 0, 0, 0, 68, 471, 1, 0, 0, 0, 70, 486, 1, 0, 0, 0, 72, 491, 1, 0, 0, 0, 74, 506, 1, 0, 0, 0, 76, 517, 1, 0, 0, 0, 78, 522, 1, 0, 0, 0, 80, 535, 1, 0, 0, 0, 82, 546, 1, 0, 0, 0, 84, 568, 1, 0, 0, 0, 86, 570, 1, 0, 0, 0, 88, 576, 1, 0, 0, 0, 90, 597, 1, 0, 0, 0, 92, 600, 1, 0, 0, 0, 94, 101, 5, 8, 0, 0, 95, 101, 5, 9, 0, 0, 96, 101, 5, 10, 0, 0, 97, 101, 5, 11, 0, 0, 98, 101, 5, 12, 0, 0, 99, 101, 3, 2, 1, 0, 100, 94, 1, 0, 0, 0, 100, 95, 1, 0, 0, 0, 100, 96, 1, 0, 0, 0, 100, 97, 1, 0, 0, 0, 100, 98, 1, 0, 0, 0, 100, 99, 1, 0, 0, 0, 101, 1, 1, 0, 0, 0, 102, 103, 6, 1, -1, 0, 103, 104, 5, 47, 0, 0, 104, 105, 3, 2, 1, 0, 105, 106, 5, 48, 0, 0, 106, 112, 1, 0, 0, 0, 107, 108, 5, 87, 0, 0, 108, 109, 5, 77, 0, 0, 109, 112, 3, 2, 1, 2, 110, 112, 5, 86, 0, 0, 111, 102, 1, 0, 0, 0, 111, 107, 1, 0, 0, 0, 111, 110, 1, 0, 0, 0, 112, 124, 1, 0, 0, 0, 113, 116, 10, 3, 0, 0, 114, 117, 5, 75, 0, 0, 115, 117, 5, 77, 0, 0, 116, 114, 1, 0, 0, 0, 116, 115, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 123, 3, 2, 1, 4, 119, 120, 10, 4, 0, 0, 120, 121, 5, 76, 0, 0, 121, 123, 3, 4, 2, 0, 122, 113, 1, 0, 0, 0, 122, 119, 1, 0, 0, 0, 123, 126, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 124, 125, 1, 0, 0, 0, 125, 3, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 127, 129, 7, 0, 0, 0, 128, 127, 1, 0, 0, 0, 128, 129, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 131, 5, 87, 0, 0, 131, 5, 1, 0, 0, 0, 132, 133, 6, 3, -1, 0, 133, 134, 5, 47, 0, 0, 134, 135, 3, 6, 3, 0, 135, 136, 5, 48, 0, 0, 136, 144, 1, 0, 0, 0, 137, 138, 3, 10, 5, 0, 138, 139, 3, 6, 3, 9, 139, 144, 1, 0, 0, 0, 140, 141, 5, 26, 0, 0, 141, 144, 3, 6, 3, 4, 142, 144, 3, 8, 4, 0, 143, 132, 1, 0, 0, 0, 143, 137, 1, 0, 0, 0, 143, 140, 1, 0, 0, 0, 143, 142, 1, 0, 0, 0, 144, 205, 1, 0, 0, 0, 145, 146, 10, 10, 0, 0, 146, 147, 5, 76, 0, 0, 147, 204, 3, 6, 3, 10, 148, 152, 10, 8, 0, 0, 149, 153, 5, 75, 0, 0, 150, 153, 5, 77, 0, 0, 151, 153, 5, 78, 0, 0, 152, 149, 1, 0, 0, 0, 152, 150, 1, 0, 0, 0, 152, 151, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 204, 3, 6, 3, 9, 155, 158, 10, 7, 0, 0, 156, 159, 5, 49, 0, 0, 157, 159, 5, 73, 0, 0, 158, 156, 1, 0, 0, 0, 158, 157, 1, 0, 0, 0, 159, 160, 1, 0, 0, 0, 160, 204, 3, 6, 3, 8, 161, 162, 10, 6, 0, 0, 162, 163, 3, 12, 6, 0, 163, 164, 3, 6, 3, 7, 164, 204, 1, 0, 0, 0, 165, 166, 10, 5, 0, 0, 166, 167, 3, 14, 7, 0, 167, 168, 3, 6, 3, 6, 168, 204, 1, 0, 0, 0, 169, 170, 10, 3, 0, 0, 170, 171, 3, 16, 8, 0, 171, 172, 3, 6, 3, 4, 172, 204, 1, 0, 0, 0, 173, 177, 10, 2, 0, 0, 174, 176, 5, 6, 0, 0, 175, 174, 1, 0, 0, 0, 176, 179, 1, 0, 0, 0, 177, 175, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 180, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 180, 184, 5, 79, 0, 0, 181, 183, 5, 6, 0, 0, 182, 181, 1, 0, 0, 0, 183, 186, 1, 0, 0, 0, 184, 182, 1, 0, 0, 0, 184, 185, 1, 0, 0, 0, 185, 187, 1, 0, 0, 0, 186, 184, 1, 0, 0, 0, 187, 191, 3, 6, 3, 0, 188, 190, 5, 6, 0, 0, 189, 188, 1, 0, 0, 0, 190, 193, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 191, 192, 1, 0, 0, 0, 192, 194, 1, 0, 0, 0, 193, 191, 1, 0, 0, 0, 194, 198, 5, 80, 0, 0, 195, 197, 5, 6, 0, 0, 196, 195, 1, 0, 0, 0, 197, 200, 1, 0, 0, 0, 198, 196, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 201, 1, 0, 0, 0, 200, 198, 1, 0, 0, 0, 201, 202, 3, 6, 3, 3, 202, 204, 1, 0, 0, 0, 203, 145, 1, 0, 0, 0, 203, 148, 1, 0, 0, 0, 203, 155, 1, 0, 0, 0, 203, 161, 1, 0, 0, 0, 203, 165, 1, 0, 0, 0, 203, 169, 1, 0, 0, 0, 203, 173, 1, 0, 0, 0, 204, 207, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 7, 1, 0, 0, 0, 207, 205, 1, 0, 0, 0, 208, 218, 3, 22, 11, 0, 209, 218, 5, 84, 0, 0, 210, 212, 7, 1, 0, 0, 211, 213, 3, 20, 10, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 218, 1, 0, 0, 0, 214, 218, 5, 85, 0, 0, 215, 218, 5, 23, 0, 0, 216, 218, 3, 20, 10, 0, 217, 208, 1, 0, 0, 0, 217, 209, 1, 0, 0, 0, 217, 210, 1, 0, 0, 0, 217, 214, 1, 0, 0, 0, 217, 215, 1, 0, 0, 0, 217, 216, 1, 0, 0, 0, 218, 9, 1, 0, 0, 0, 219, 223, 5, 49, 0, 0, 220, 223, 5, 73, 0, 0, 221, 223, 5, 50, 0, 0, 222, 219, 1, 0, 0, 0, 222, 220, 1, 0, 0, 0, 222, 221, 1, 0, 0, 0, 223, 11, 1, 0, 0, 0, 224, 230, 5, 53, 0, 0, 225, 230, 5, 52, 0, 0, 226, 230, 5, 51, 0, 0, 227, 230, 5, 59, 0, 0, 228, 230, 5, 60, 0, 0, 229, 224, 1, 0, 0, 0, 229, 225, 1, 0, 0, 0, 229, 226, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 228, 1, 0, 0, 0, 230, 13, 1, 0, 0, 0, 231, 239, 5, 61, 0, 0, 232, 239, 5, 63, 0, 0, 233, 239, 5, 68, 0, 0, 234, 239, 5, 69, 0, 0, 235, 239, 5, 70, 0, 0, 236, 239, 5, 71, 0, 0, 237, 239, 5, 62, 0, 0, 238, 231, 1, 0, 0, 0, 238, 232, 1, 0, 0, 0, 238, 233, 1, 0, 0, 0, 238, 234, 1, 0, 0, 0, 238, 235, 1, 0, 0, 0, 238, 236, 1, 0, 0, 0, 238, 237, 1, 0, 0, 0, 239, 15, 1, 0, 0, 0, 240, 243, 5, 24, 0, 0, 241, 243, 5, 25, 0, 0, 242, 240, 1, 0, 0, 0, 242, 241, 1, 0, 0, 0, 243, 17, 1, 0, 0, 0, 244, 247, 5, 86, 0, 0, 245, 247, 5, 87, 0, 0, 246, 244, 1, 0, 0, 0, 246, 245, 1, 0, 0, 0, 247, 19, 1, 0, 0, 0, 248, 253, 5, 86, 0, 0, 249, 250, 5, 54, 0, 0, 250, 251, 3, 18, 9, 0, 251, 252, 5, 56, 0, 0, 252, 254, 1, 0, 0, 0, 253, 249, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 258, 1, 0, 0, 0, 255, 257, 5, 83, 0, 0, 256, 255, 1, 0, 0, 0, 257, 260, 1, 0, 0, 0, 258, 256, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 21, 1, 0, 0, 0, 260, 258, 1, 0, 0, 0, 261, 262, 5, 86, 0, 0, 262, 271, 5, 47, 0, 0, 263, 268, 3, 6, 3, 0, 264, 265, 5, 72, 0, 0, 265, 267, 3, 6, 3, 0, 266, 264, 1, 0, 0, 0, 267, 270, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 272, 1, 0, 0, 0, 270, 268, 1, 0, 0, 0, 271, 263, 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 274, 5, 48, 0, 0, 274, 23, 1, 0, 0, 0, 275, 277, 5, 27, 0, 0, 276, 275, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 279, 5, 14, 0, 0, 279, 280, 5, 86, 0, 0, 280, 281, 3, 0, 0, 0, 281, 282, 5, 74, 0, 0, 282, 284, 3, 6, 3, 0, 283, 285, 5, 82, 0, 0, 284, 283, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 25, 1, 0, 0, 0, 286, 287, 3, 20, 10, 0, 287, 288, 5, 74, 0, 0, 288, 290, 3, 6, 3, 0, 289, 291, 5, 82, 0, 0, 290, 289, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 27, 1, 0, 0, 0, 292, 293, 5, 28, 0, 0, 293, 294, 3, 20, 10, 0, 294, 295, 5, 74, 0, 0, 295, 309, 3, 6, 3, 0, 296, 300, 5, 72, 0, 0, 297, 299, 5, 6, 0, 0, 298, 297, 1, 0, 0, 0, 299, 302, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 300, 301, 1, 0, 0, 0, 301, 303, 1, 0, 0, 0, 302, 300, 1, 0, 0, 0, 303, 304, 3, 20, 10, 0, 304, 305, 5, 74, 0, 0, 305, 306, 3, 6, 3, 0, 306, 308, 1, 0, 0, 0, 307, 296, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 309, 310, 1, 0, 0, 0, 310, 313, 1, 0, 0, 0, 311, 309, 1, 0, 0, 0, 312, 314, 5, 82, 0, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 29, 1, 0, 0, 0, 315, 318, 3, 32, 16, 0, 316, 318, 5, 6, 0, 0, 317, 315, 1, 0, 0, 0, 317, 316, 1, 0, 0, 0, 318, 321, 1, 0, 0, 0, 319, 317, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 31, 1, 0, 0, 0, 321, 319, 1, 0, 0, 0, 322, 325, 3, 36, 18, 0, 323, 325, 3, 34, 17, 0, 324, 322, 1, 0, 0, 0, 324, 323, 1, 0, 0, 0, 325, 33, 1, 0, 0, 0, 326, 330, 3, 50, 25, 0, 327, 330, 3, 58, 29, 0, 328, 330, 3, 60, 30, 0, 329, 326, 1, 0, 0, 0, 329, 327, 1, 0, 0, 0, 329, 328, 1, 0, 0, 0, 330, 35, 1, 0, 0, 0, 331, 336, 3, 38, 19, 0, 332, 336, 3, 22, 11, 0, 333, 336, 3, 40, 20, 0, 334, 336, 3, 48, 24, 0, 335, 331, 1, 0, 0, 0, 335, 332, 1, 0, 0, 0, 335, 333, 1, 0, 0, 0, 335, 334, 1, 0, 0, 0, 336, 37, 1, 0, 0, 0, 337, 343, 3, 20, 10, 0, 338, 344, 5, 74, 0, 0, 339, 344, 5, 64, 0, 0, 340, 344, 5, 65, 0, 0, 341, 344, 5, 66, 0, 0, 342, 344, 5, 67, 0, 0, 343, 338, 1, 0, 0, 0, 343, 339, 1, 0, 0, 0, 343, 340, 1, 0, 0, 0, 343, 341, 1, 0, 0, 0, 343, 342, 1, 0, 0, 0, 344, 345, 1, 0, 0, 0, 345, 346, 3, 6, 3, 0, 346, 39, 1, 0, 0, 0, 347, 349, 5, 27, 0, 0, 348, 347, 1, 0, 0, 0, 348, 349, 1, 0, 0, 0, 349, 351, 1, 0, 0, 0, 350, 352, 5, 14, 0, 0, 351, 350, 1, 0, 0, 0, 351, 352, 1, 0, 0, 0, 352, 353, 1, 0, 0, 0, 353, 358, 3, 20, 10, 0, 354, 355, 5, 72, 0, 0, 355, 357, 3, 20, 10, 0, 356, 354, 1, 0, 0, 0, 357, 360, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 358, 359, 1, 0, 0, 0, 359, 361, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 361, 364, 3, 0, 0, 0, 362, 363, 5, 74, 0, 0, 363, 365, 3, 6, 3, 0, 364, 362, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 370, 1, 0, 0, 0, 366, 367, 5, 57, 0, 0, 367, 368, 3, 6, 3, 0, 368, 369, 5, 58, 0, 0, 369, 371, 1, 0, 0, 0, 370, 366, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 375, 1, 0, 0, 0, 372, 374, 3, 42, 21, 0, 373, 372, 1, 0, 0, 0, 374, 377, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 375, 376, 1, 0, 0, 0, 376, 41, 1, 0, 0, 0, 377, 375, 1, 0, 0, 0, 378, 386, 5, 43, 0, 0, 379, 386, 5, 44, 0, 0, 380, 381, 5, 45, 0, 0, 381, 382, 3, 44, 22, 0, 382, 383, 5, 81, 0, 0, 383, 384, 3, 46, 23, 0, 384, 386, 1, 0, 0, 0, 385, 378, 1, 0, 0, 0, 385, 379, 1, 0, 0, 0, 385, 380, 1, 0, 0, 0, 386, 43, 1, 0, 0, 0, 387, 388, 5, 86, 0, 0, 388, 45, 1, 0, 0, 0, 389, 390, 5, 86, 0, 0, 390, 47, 1, 0, 0, 0, 391, 393, 5, 15, 0, 0, 392, 394, 3, 6, 3, 0, 393, 392, 1, 0, 0, 0, 393, 394, 1, 0, 0, 0, 394, 49, 1, 0, 0, 0, 395, 399, 3, 52, 26, 0, 396, 398, 3, 54, 27, 0, 397, 396, 1, 0, 0, 0, 398, 401, 1, 0, 0, 0, 399, 397, 1, 0, 0, 0, 399, 400, 1, 0, 0, 0, 400, 403, 1, 0, 0, 0, 401, 399, 1, 0, 0, 0, 402, 404, 3, 56, 28, 0, 403, 402, 1, 0, 0, 0, 403, 404, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 406, 5, 7, 0, 0, 406, 51, 1, 0, 0, 0, 407, 408, 5, 16, 0, 0, 408, 409, 3, 6, 3, 0, 409, 410, 5, 80, 0, 0, 410, 411, 3, 30, 15, 0, 411, 53, 1, 0, 0, 0, 412, 413, 5, 17, 0, 0, 413, 414, 3, 6, 3, 0, 414, 415, 5, 80, 0, 0, 415, 416, 3, 30, 15, 0, 416, 55, 1, 0, 0, 0, 417, 418, 5, 18, 0, 0, 418, 419, 5, 80, 0, 0, 419, 420, 3, 30, 15, 0, 420, 57, 1, 0, 0, 0, 421, 422, 5, 19, 0, 0, 422, 423, 5, 86, 0, 0, 423, 424, 5, 21, 0, 0, 424, 425, 3, 6, 3, 0, 425, 426, 5, 46, 0, 0, 426, 427, 3, 6, 3, 0, 427, 429, 5, 22, 0, 0, 428, 430, 5, 73, 0, 0, 429, 428, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 432, 7, 1, 0, 0, 432, 433, 5, 80, 0, 0, 433, 434, 3, 30, 15, 0, 434, 435, 5, 7, 0, 0, 435, 59, 1, 0, 0, 0, 436, 437, 5, 20, 0, 0, 437, 438, 3, 6, 3, 0, 438, 439, 5, 80, 0, 0, 439, 440, 3, 30, 15, 0, 440, 441, 5, 7, 0, 0, 441, 61, 1, 0, 0, 0, 442, 446, 3, 64, 32, 0, 443, 446, 3, 68, 34, 0, 444, 446, 5, 6, 0, 0, 445, 442, 1, 0, 0, 0, 445, 443, 1, 0, 0, 0, 445, 444, 1, 0, 0, 0, 446, 449, 1, 0, 0, 0, 447, 445, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 448, 450, 1, 0, 0, 0, 449, 447, 1, 0, 0, 0, 450, 451, 5, 0, 0, 1, 451, 63, 1, 0, 0, 0, 452, 453, 5, 29, 0, 0, 453, 454, 5, 86, 0, 0, 454, 455, 3, 66, 33, 0, 455, 65, 1, 0, 0, 0, 456, 466, 5, 80, 0, 0, 457, 465, 5, 6, 0, 0, 458, 465, 3, 74, 37, 0, 459, 465, 3, 78, 39, 0, 460, 465, 3, 80, 40, 0, 461, 465, 3, 86, 43, 0, 462, 465, 3, 76, 38, 0, 463, 465, 3, 88, 44, 0, 464, 457, 1, 0, 0, 0, 464, 458, 1, 0, 0, 0, 464, 459, 1, 0, 0, 0, 464, 460, 1, 0, 0, 0, 464, 461, 1, 0, 0, 0, 464, 462, 1, 0, 0, 0, 464, 463, 1, 0, 0, 0, 465, 468, 1, 0, 0, 0, 466, 464, 1, 0, 0, 0, 466, 467, 1, 0, 0, 0, 467, 469, 1, 0, 0, 0, 468, 466, 1, 0, 0, 0, 469, 470, 5, 7, 0, 0, 470, 67, 1, 0, 0, 0, 471, 472, 5, 30, 0, 0, 472, 473, 5, 86, 0, 0, 473, 474, 5, 80, 0, 0, 474, 475, 3, 70, 35, 0, 475, 69, 1, 0, 0, 0, 476, 485, 5, 6, 0, 0, 477, 485, 3, 74, 37, 0, 478, 485, 3, 78, 39, 0, 479, 485, 3, 80, 40, 0, 480, 485, 3, 86, 43, 0, 481, 485, 3, 88, 44, 0, 482, 485, 3, 72, 36, 0, 483, 485, 3, 76, 38, 0, 484, 476, 1, 0, 0, 0, 484, 477, 1, 0, 0, 0, 484, 478, 1, 0, 0, 0, 484, 479, 1, 0, 0, 0, 484, 480, 1, 0, 0, 0, 484, 481, 1, 0, 0, 0, 484, 482, 1, 0, 0, 0, 484, 483, 1, 0, 0, 0, 485, 488, 1, 0, 0, 0, 486, 484, 1, 0, 0, 0, 486, 487, 1, 0, 0, 0, 487, 489, 1, 0, 0, 0, 488, 486, 1, 0, 0, 0, 489, 490, 5, 7, 0, 0, 490, 71, 1, 0, 0, 0, 491, 492, 5, 39, 0, 0, 492, 493, 5, 47, 0, 0, 493, 498, 5, 86, 0, 0, 494, 495, 5, 72, 0, 0, 495, 497, 3, 92, 46, 0, 496, 494, 1, 0, 0, 0, 497, 500, 1, 0, 0, 0, 498, 496, 1, 0, 0, 0, 498, 499, 1, 0, 0, 0, 499, 501, 1, 0, 0, 0, 500, 498, 1, 0, 0, 0, 501, 502, 5, 48, 0, 0, 502, 503, 5, 80, 0, 0, 503, 504, 3, 30, 15, 0, 504, 505, 5, 7, 0, 0, 505, 73, 1, 0, 0, 0, 506, 507, 7, 2, 0, 0, 507, 512, 5, 80, 0, 0, 508, 511, 3, 40, 20, 0, 509, 511, 5, 6, 0, 0, 510, 508, 1, 0, 0, 0, 510, 509, 1, 0, 0, 0, 511, 514, 1, 0, 0, 0, 512, 510, 1, 0, 0, 0, 512, 513, 1, 0, 0, 0, 513, 515, 1, 0, 0, 0, 514, 512, 1, 0, 0, 0, 515, 516, 5, 7, 0, 0, 516, 75, 1, 0, 0, 0, 517, 518, 5, 34, 0, 0, 518, 519, 5, 80, 0, 0, 519, 520, 3, 30, 15, 0, 520, 521, 5, 7, 0, 0, 521, 77, 1, 0, 0, 0, 522, 523, 5, 35, 0, 0, 523, 530, 5, 80, 0, 0, 524, 529, 3, 24, 12, 0, 525, 529, 3, 26, 13, 0, 526, 529, 3, 28, 14, 0, 527, 529, 5, 6, 0, 0, 528, 524, 1, 0, 0, 0, 528, 525, 1, 0, 0, 0, 528, 526, 1, 0, 0, 0, 528, 527, 1, 0, 0, 0, 529, 532, 1, 0, 0, 0, 530, 528, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 533, 1, 0, 0, 0, 532, 530, 1, 0, 0, 0, 533, 534, 5, 7, 0, 0, 534, 79, 1, 0, 0, 0, 535, 536, 5, 36, 0, 0, 536, 541, 5, 80, 0, 0, 537, 540, 3, 82, 41, 0, 538, 540, 5, 6, 0, 0, 539, 537, 1, 0, 0, 0, 539, 538, 1, 0, 0, 0, 540, 543, 1, 0, 0, 0, 541, 539, 1, 0, 0, 0, 541, 542, 1, 0, 0, 0, 542, 544, 1, 0, 0, 0, 543, 541, 1, 0, 0, 0, 544, 545, 5, 7, 0, 0, 545, 81, 1, 0, 0, 0, 546, 550, 5, 86, 0, 0, 547, 548, 5, 54, 0, 0, 548, 549, 5, 86, 0, 0, 549, 551, 5, 56, 0, 0, 550, 547, 1, 0, 0, 0, 550, 551, 1, 0, 0, 0, 551, 553, 1, 0, 0, 0, 552, 554, 3, 0, 0, 0, 553, 552, 1, 0, 0, 0, 553, 554, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 559, 5, 55, 0, 0, 556, 558, 3, 84, 42, 0, 557, 556, 1, 0, 0, 0, 558, 561, 1, 0, 0, 0, 559, 557, 1, 0, 0, 0, 559, 560, 1, 0, 0, 0, 560, 564, 1, 0, 0, 0, 561, 559, 1, 0, 0, 0, 562, 565, 5, 38, 0, 0, 563, 565, 5, 40, 0, 0, 564, 562, 1, 0, 0, 0, 564, 563, 1, 0, 0, 0, 565, 83, 1, 0, 0, 0, 566, 569, 5, 41, 0, 0, 567, 569, 5, 42, 0, 0, 568, 566, 1, 0, 0, 0, 568, 567, 1, 0, 0, 0, 569, 85, 1, 0, 0, 0, 570, 571, 5, 37, 0, 0, 571, 574, 5, 80, 0, 0, 572, 575, 5, 40, 0, 0, 573, 575, 5, 38, 0, 0, 574, 572, 1, 0, 0, 0, 574, 573, 1, 0, 0, 0, 575, 87, 1, 0, 0, 0, 576, 577, 5, 13, 0, 0, 577, 578, 5, 86, 0, 0, 578, 587, 5, 47, 0, 0, 579, 584, 3, 90, 45, 0, 580, 581, 5, 72, 0, 0, 581, 583, 3, 90, 45, 0, 582, 580, 1, 0, 0, 0, 583, 586, 1, 0, 0, 0, 584, 582, 1, 0, 0, 0, 584, 585, 1, 0, 0, 0, 585, 588, 1, 0, 0, 0, 586, 584, 1, 0, 0, 0, 587, 579, 1, 0, 0, 0, 587, 588, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 5, 48, 0, 0, 590, 592, 3, 0, 0, 0, 591, 590, 1, 0, 0, 0, 591, 592, 1, 0, 0, 0, 592, 593, 1, 0, 0, 0, 593, 594, 5, 80, 0, 0, 594, 595, 3, 30, 15, 0, 595, 596, 5, 7, 0, 0, 596, 89, 1, 0, 0, 0, 597, 598, 5, 86, 0, 0, 598, 599, 3, 0, 0, 0, 599, 91, 1, 0, 0, 0, 600, 601, 5, 86, 0, 0, 601, 602, 5, 74, 0, 0, 602, 603, 7, 3, 0, 0, 603, 93, 1, 0, 0, 0, 71, 100, 111, 116, 122, 124, 128, 143, 152, 158, 177, 184, 191, 198, 203, 205, 212, 217, 222, 229, 238, 242, 246, 253, 258, 268, 271, 276, 284, 290, 300, 309, 313, 317, 319, 324, 329, 335, 343, 348, 351, 358, 364, 370, 375, 385, 393, 399, 403, 429, 445, 447, 464, 466, 484, 486, 498, 510, 512, 528, 530, 539, 541, 550, 553, 559, 564, 568, 574, 584, 587, 591] \ No newline at end of file diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index 832016ba2..6887dcf6b 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -1,260 +1,243 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.7.1 +# Generated from PyNestMLParser.g4 by ANTLR 4.10 # encoding: utf-8 -from __future__ import print_function from antlr4 import * from io import StringIO import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO def serializedATN(): - with StringIO() as buf: - buf.write(u"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3") - buf.write(u"T\u01f1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t") - buf.write(u"\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r") - buf.write(u"\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4") - buf.write(u"\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30") - buf.write(u"\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t") - buf.write(u"\35\4\36\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$") - buf.write(u"\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\3\2\3\2\3\2\3\2\3\2\3\2") - buf.write(u"\5\2W\n\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3b\n") - buf.write(u"\3\3\3\3\3\3\3\5\3g\n\3\3\3\3\3\3\3\3\3\7\3m\n\3\f\3") - buf.write(u"\16\3p\13\3\3\4\5\4s\n\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5") - buf.write(u"\3\5\3\5\3\5\3\5\3\5\3\5\5\5\u0082\n\5\3\5\3\5\3\5\3") - buf.write(u"\5\3\5\3\5\3\5\5\5\u008b\n\5\3\5\3\5\3\5\3\5\5\5\u0091") - buf.write(u"\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5") - buf.write(u"\3\5\3\5\3\5\3\5\3\5\3\5\3\5\7\5\u00a6\n\5\f\5\16\5\u00a9") - buf.write(u"\13\5\3\6\3\6\3\6\3\6\5\6\u00af\n\6\3\6\3\6\3\6\5\6\u00b4") - buf.write(u"\n\6\3\7\3\7\3\7\5\7\u00b9\n\7\3\b\3\b\3\b\3\b\3\b\5") - buf.write(u"\b\u00c0\n\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\5\t\u00c9\n") - buf.write(u"\t\3\n\3\n\5\n\u00cd\n\n\3\13\3\13\7\13\u00d1\n\13\f") - buf.write(u"\13\16\13\u00d4\13\13\3\f\3\f\3\f\3\f\3\f\7\f\u00db\n") - buf.write(u"\f\f\f\16\f\u00de\13\f\5\f\u00e0\n\f\3\f\3\f\3\r\5\r") - buf.write(u"\u00e5\n\r\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u00ed\n\r\3\16") - buf.write(u"\3\16\3\16\3\16\5\16\u00f3\n\16\3\17\3\17\3\17\3\17\3") - buf.write(u"\17\3\17\3\17\3\17\3\17\7\17\u00fe\n\17\f\17\16\17\u0101") - buf.write(u"\13\17\3\17\5\17\u0104\n\17\3\20\3\20\7\20\u0108\n\20") - buf.write(u"\f\20\16\20\u010b\13\20\3\21\3\21\5\21\u010f\n\21\3\22") - buf.write(u"\3\22\3\22\5\22\u0114\n\22\3\23\3\23\3\23\3\23\5\23\u011a") - buf.write(u"\n\23\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u0122\n\24\3") - buf.write(u"\24\3\24\3\25\5\25\u0127\n\25\3\25\5\25\u012a\n\25\3") - buf.write(u"\25\3\25\3\25\7\25\u012f\n\25\f\25\16\25\u0132\13\25") - buf.write(u"\3\25\3\25\3\25\3\25\5\25\u0138\n\25\3\25\3\25\5\25\u013c") - buf.write(u"\n\25\3\25\3\25\3\25\3\25\5\25\u0142\n\25\3\26\3\26\5") - buf.write(u"\26\u0146\n\26\3\27\3\27\7\27\u014a\n\27\f\27\16\27\u014d") - buf.write(u"\13\27\3\27\5\27\u0150\n\27\3\27\3\27\3\30\3\30\3\30") - buf.write(u"\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3") - buf.write(u"\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u016a") - buf.write(u"\n\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3") - buf.write(u"\34\3\34\3\35\3\35\7\35\u0179\n\35\f\35\16\35\u017c\13") - buf.write(u"\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37") - buf.write(u"\3\37\3\37\3\37\3\37\7\37\u018c\n\37\f\37\16\37\u018f") - buf.write(u"\13\37\3\37\3\37\3 \3 \3 \3 \7 \u0197\n \f \16 \u019a") - buf.write(u"\13 \3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\7\"") - buf.write(u"\u01a9\n\"\f\"\16\"\u01ac\13\"\3\"\3\"\3#\3#\3#\3#\7") - buf.write(u"#\u01b4\n#\f#\16#\u01b7\13#\3#\3#\3$\3$\3$\3$\5$\u01bf") - buf.write(u"\n$\3$\5$\u01c2\n$\3$\3$\7$\u01c6\n$\f$\16$\u01c9\13") - buf.write(u"$\3$\3$\5$\u01cd\n$\3%\3%\5%\u01d1\n%\3&\3&\3&\3&\5&") - buf.write(u"\u01d7\n&\3\'\3\'\3\'\3\'\3\'\3\'\7\'\u01df\n\'\f\'\16") - buf.write(u"\'\u01e2\13\'\5\'\u01e4\n\'\3\'\3\'\5\'\u01e8\n\'\3\'") - buf.write(u"\3\'\3\'\3\'\3(\3(\3(\3(\2\4\4\b)\2\4\6\b\n\f\16\20\22") - buf.write(u"\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLN\2") - buf.write(u"\5\4\2..FF\3\2ST\3\2\37\"\2\u022c\2V\3\2\2\2\4a\3\2\2") - buf.write(u"\2\6r\3\2\2\2\b\u0081\3\2\2\2\n\u00b3\3\2\2\2\f\u00b8") - buf.write(u"\3\2\2\2\16\u00bf\3\2\2\2\20\u00c8\3\2\2\2\22\u00cc\3") - buf.write(u"\2\2\2\24\u00ce\3\2\2\2\26\u00d5\3\2\2\2\30\u00e4\3\2") - buf.write(u"\2\2\32\u00ee\3\2\2\2\34\u00f4\3\2\2\2\36\u0109\3\2\2") - buf.write(u"\2 \u010e\3\2\2\2\"\u0113\3\2\2\2$\u0119\3\2\2\2&\u011b") - buf.write(u"\3\2\2\2(\u0126\3\2\2\2*\u0143\3\2\2\2,\u0147\3\2\2\2") - buf.write(u".\u0153\3\2\2\2\60\u0158\3\2\2\2\62\u015d\3\2\2\2\64") - buf.write(u"\u0161\3\2\2\2\66\u0170\3\2\2\28\u017a\3\2\2\2:\u017f") - buf.write(u"\3\2\2\2<\u0183\3\2\2\2>\u0192\3\2\2\2@\u019d\3\2\2\2") - buf.write(u"B\u01a2\3\2\2\2D\u01af\3\2\2\2F\u01ba\3\2\2\2H\u01d0") - buf.write(u"\3\2\2\2J\u01d2\3\2\2\2L\u01d8\3\2\2\2N\u01ed\3\2\2\2") - buf.write(u"PW\7\t\2\2QW\7\n\2\2RW\7\13\2\2SW\7\f\2\2TW\7\r\2\2U") - buf.write(u"W\5\4\3\2VP\3\2\2\2VQ\3\2\2\2VR\3\2\2\2VS\3\2\2\2VT\3") - buf.write(u"\2\2\2VU\3\2\2\2W\3\3\2\2\2XY\b\3\1\2YZ\7,\2\2Z[\5\4") - buf.write(u"\3\2[\\\7-\2\2\\b\3\2\2\2]^\7S\2\2^_\7J\2\2_b\5\4\3\4") - buf.write(u"`b\7R\2\2aX\3\2\2\2a]\3\2\2\2a`\3\2\2\2bn\3\2\2\2cf\f") - buf.write(u"\5\2\2dg\7H\2\2eg\7J\2\2fd\3\2\2\2fe\3\2\2\2gh\3\2\2") - buf.write(u"\2hm\5\4\3\6ij\f\6\2\2jk\7I\2\2km\5\6\4\2lc\3\2\2\2l") - buf.write(u"i\3\2\2\2mp\3\2\2\2nl\3\2\2\2no\3\2\2\2o\5\3\2\2\2pn") - buf.write(u"\3\2\2\2qs\t\2\2\2rq\3\2\2\2rs\3\2\2\2st\3\2\2\2tu\7") - buf.write(u"S\2\2u\7\3\2\2\2vw\b\5\1\2wx\7,\2\2xy\5\b\5\2yz\7-\2") - buf.write(u"\2z\u0082\3\2\2\2{|\5\f\7\2|}\5\b\5\13}\u0082\3\2\2\2") - buf.write(u"~\177\7\33\2\2\177\u0082\5\b\5\6\u0080\u0082\5\n\6\2") - buf.write(u"\u0081v\3\2\2\2\u0081{\3\2\2\2\u0081~\3\2\2\2\u0081\u0080") - buf.write(u"\3\2\2\2\u0082\u00a7\3\2\2\2\u0083\u0084\f\f\2\2\u0084") - buf.write(u"\u0085\7I\2\2\u0085\u00a6\5\b\5\f\u0086\u008a\f\n\2\2") - buf.write(u"\u0087\u008b\7H\2\2\u0088\u008b\7J\2\2\u0089\u008b\7") - buf.write(u"K\2\2\u008a\u0087\3\2\2\2\u008a\u0088\3\2\2\2\u008a\u0089") - buf.write(u"\3\2\2\2\u008b\u008c\3\2\2\2\u008c\u00a6\5\b\5\13\u008d") - buf.write(u"\u0090\f\t\2\2\u008e\u0091\7.\2\2\u008f\u0091\7F\2\2") - buf.write(u"\u0090\u008e\3\2\2\2\u0090\u008f\3\2\2\2\u0091\u0092") - buf.write(u"\3\2\2\2\u0092\u00a6\5\b\5\n\u0093\u0094\f\b\2\2\u0094") - buf.write(u"\u0095\5\16\b\2\u0095\u0096\5\b\5\t\u0096\u00a6\3\2\2") - buf.write(u"\2\u0097\u0098\f\7\2\2\u0098\u0099\5\20\t\2\u0099\u009a") - buf.write(u"\5\b\5\b\u009a\u00a6\3\2\2\2\u009b\u009c\f\5\2\2\u009c") - buf.write(u"\u009d\5\22\n\2\u009d\u009e\5\b\5\6\u009e\u00a6\3\2\2") - buf.write(u"\2\u009f\u00a0\f\4\2\2\u00a0\u00a1\7L\2\2\u00a1\u00a2") - buf.write(u"\5\b\5\2\u00a2\u00a3\7M\2\2\u00a3\u00a4\5\b\5\5\u00a4") - buf.write(u"\u00a6\3\2\2\2\u00a5\u0083\3\2\2\2\u00a5\u0086\3\2\2") - buf.write(u"\2\u00a5\u008d\3\2\2\2\u00a5\u0093\3\2\2\2\u00a5\u0097") - buf.write(u"\3\2\2\2\u00a5\u009b\3\2\2\2\u00a5\u009f\3\2\2\2\u00a6") - buf.write(u"\u00a9\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a7\u00a8\3\2\2") - buf.write(u"\2\u00a8\t\3\2\2\2\u00a9\u00a7\3\2\2\2\u00aa\u00b4\5") - buf.write(u"\26\f\2\u00ab\u00b4\7P\2\2\u00ac\u00ae\t\3\2\2\u00ad") - buf.write(u"\u00af\5\24\13\2\u00ae\u00ad\3\2\2\2\u00ae\u00af\3\2") - buf.write(u"\2\2\u00af\u00b4\3\2\2\2\u00b0\u00b4\7Q\2\2\u00b1\u00b4") - buf.write(u"\7\30\2\2\u00b2\u00b4\5\24\13\2\u00b3\u00aa\3\2\2\2\u00b3") - buf.write(u"\u00ab\3\2\2\2\u00b3\u00ac\3\2\2\2\u00b3\u00b0\3\2\2") - buf.write(u"\2\u00b3\u00b1\3\2\2\2\u00b3\u00b2\3\2\2\2\u00b4\13\3") - buf.write(u"\2\2\2\u00b5\u00b9\7.\2\2\u00b6\u00b9\7F\2\2\u00b7\u00b9") - buf.write(u"\7/\2\2\u00b8\u00b5\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b8") - buf.write(u"\u00b7\3\2\2\2\u00b9\r\3\2\2\2\u00ba\u00c0\7\62\2\2\u00bb") - buf.write(u"\u00c0\7\61\2\2\u00bc\u00c0\7\60\2\2\u00bd\u00c0\78\2") - buf.write(u"\2\u00be\u00c0\79\2\2\u00bf\u00ba\3\2\2\2\u00bf\u00bb") - buf.write(u"\3\2\2\2\u00bf\u00bc\3\2\2\2\u00bf\u00bd\3\2\2\2\u00bf") - buf.write(u"\u00be\3\2\2\2\u00c0\17\3\2\2\2\u00c1\u00c9\7:\2\2\u00c2") - buf.write(u"\u00c9\7<\2\2\u00c3\u00c9\7A\2\2\u00c4\u00c9\7B\2\2\u00c5") - buf.write(u"\u00c9\7C\2\2\u00c6\u00c9\7D\2\2\u00c7\u00c9\7;\2\2\u00c8") - buf.write(u"\u00c1\3\2\2\2\u00c8\u00c2\3\2\2\2\u00c8\u00c3\3\2\2") - buf.write(u"\2\u00c8\u00c4\3\2\2\2\u00c8\u00c5\3\2\2\2\u00c8\u00c6") - buf.write(u"\3\2\2\2\u00c8\u00c7\3\2\2\2\u00c9\21\3\2\2\2\u00ca\u00cd") - buf.write(u"\7\31\2\2\u00cb\u00cd\7\32\2\2\u00cc\u00ca\3\2\2\2\u00cc") - buf.write(u"\u00cb\3\2\2\2\u00cd\23\3\2\2\2\u00ce\u00d2\7R\2\2\u00cf") - buf.write(u"\u00d1\7O\2\2\u00d0\u00cf\3\2\2\2\u00d1\u00d4\3\2\2\2") - buf.write(u"\u00d2\u00d0\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3\25\3\2") - buf.write(u"\2\2\u00d4\u00d2\3\2\2\2\u00d5\u00d6\7R\2\2\u00d6\u00df") - buf.write(u"\7,\2\2\u00d7\u00dc\5\b\5\2\u00d8\u00d9\7E\2\2\u00d9") - buf.write(u"\u00db\5\b\5\2\u00da\u00d8\3\2\2\2\u00db\u00de\3\2\2") - buf.write(u"\2\u00dc\u00da\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dd\u00e0") - buf.write(u"\3\2\2\2\u00de\u00dc\3\2\2\2\u00df\u00d7\3\2\2\2\u00df") - buf.write(u"\u00e0\3\2\2\2\u00e0\u00e1\3\2\2\2\u00e1\u00e2\7-\2\2") - buf.write(u"\u00e2\27\3\2\2\2\u00e3\u00e5\7\34\2\2\u00e4\u00e3\3") - buf.write(u"\2\2\2\u00e4\u00e5\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6") - buf.write(u"\u00e7\7\17\2\2\u00e7\u00e8\7R\2\2\u00e8\u00e9\5\2\2") - buf.write(u"\2\u00e9\u00ea\7G\2\2\u00ea\u00ec\5\b\5\2\u00eb\u00ed") - buf.write(u"\7N\2\2\u00ec\u00eb\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed") - buf.write(u"\31\3\2\2\2\u00ee\u00ef\5\24\13\2\u00ef\u00f0\7G\2\2") - buf.write(u"\u00f0\u00f2\5\b\5\2\u00f1\u00f3\7N\2\2\u00f2\u00f1\3") - buf.write(u"\2\2\2\u00f2\u00f3\3\2\2\2\u00f3\33\3\2\2\2\u00f4\u00f5") - buf.write(u"\7\35\2\2\u00f5\u00f6\5\24\13\2\u00f6\u00f7\7G\2\2\u00f7") - buf.write(u"\u00ff\5\b\5\2\u00f8\u00f9\7E\2\2\u00f9\u00fa\5\24\13") - buf.write(u"\2\u00fa\u00fb\7G\2\2\u00fb\u00fc\5\b\5\2\u00fc\u00fe") - buf.write(u"\3\2\2\2\u00fd\u00f8\3\2\2\2\u00fe\u0101\3\2\2\2\u00ff") - buf.write(u"\u00fd\3\2\2\2\u00ff\u0100\3\2\2\2\u0100\u0103\3\2\2") - buf.write(u"\2\u0101\u00ff\3\2\2\2\u0102\u0104\7N\2\2\u0103\u0102") - buf.write(u"\3\2\2\2\u0103\u0104\3\2\2\2\u0104\35\3\2\2\2\u0105\u0108") - buf.write(u"\5 \21\2\u0106\u0108\7\5\2\2\u0107\u0105\3\2\2\2\u0107") - buf.write(u"\u0106\3\2\2\2\u0108\u010b\3\2\2\2\u0109\u0107\3\2\2") - buf.write(u"\2\u0109\u010a\3\2\2\2\u010a\37\3\2\2\2\u010b\u0109\3") - buf.write(u"\2\2\2\u010c\u010f\5$\23\2\u010d\u010f\5\"\22\2\u010e") - buf.write(u"\u010c\3\2\2\2\u010e\u010d\3\2\2\2\u010f!\3\2\2\2\u0110") - buf.write(u"\u0114\5,\27\2\u0111\u0114\5\64\33\2\u0112\u0114\5\66") - buf.write(u"\34\2\u0113\u0110\3\2\2\2\u0113\u0111\3\2\2\2\u0113\u0112") - buf.write(u"\3\2\2\2\u0114#\3\2\2\2\u0115\u011a\5&\24\2\u0116\u011a") - buf.write(u"\5\26\f\2\u0117\u011a\5(\25\2\u0118\u011a\5*\26\2\u0119") - buf.write(u"\u0115\3\2\2\2\u0119\u0116\3\2\2\2\u0119\u0117\3\2\2") - buf.write(u"\2\u0119\u0118\3\2\2\2\u011a%\3\2\2\2\u011b\u0121\5\24") - buf.write(u"\13\2\u011c\u0122\7G\2\2\u011d\u0122\7=\2\2\u011e\u0122") - buf.write(u"\7>\2\2\u011f\u0122\7?\2\2\u0120\u0122\7@\2\2\u0121\u011c") - buf.write(u"\3\2\2\2\u0121\u011d\3\2\2\2\u0121\u011e\3\2\2\2\u0121") - buf.write(u"\u011f\3\2\2\2\u0121\u0120\3\2\2\2\u0122\u0123\3\2\2") - buf.write(u"\2\u0123\u0124\5\b\5\2\u0124\'\3\2\2\2\u0125\u0127\7") - buf.write(u"\34\2\2\u0126\u0125\3\2\2\2\u0126\u0127\3\2\2\2\u0127") - buf.write(u"\u0129\3\2\2\2\u0128\u012a\7\16\2\2\u0129\u0128\3\2\2") - buf.write(u"\2\u0129\u012a\3\2\2\2\u012a\u012b\3\2\2\2\u012b\u0130") - buf.write(u"\5\24\13\2\u012c\u012d\7E\2\2\u012d\u012f\5\24\13\2\u012e") - buf.write(u"\u012c\3\2\2\2\u012f\u0132\3\2\2\2\u0130\u012e\3\2\2") - buf.write(u"\2\u0130\u0131\3\2\2\2\u0131\u0133\3\2\2\2\u0132\u0130") - buf.write(u"\3\2\2\2\u0133\u0137\5\2\2\2\u0134\u0135\7\63\2\2\u0135") - buf.write(u"\u0136\7R\2\2\u0136\u0138\7\65\2\2\u0137\u0134\3\2\2") - buf.write(u"\2\u0137\u0138\3\2\2\2\u0138\u013b\3\2\2\2\u0139\u013a") - buf.write(u"\7G\2\2\u013a\u013c\5\b\5\2\u013b\u0139\3\2\2\2\u013b") - buf.write(u"\u013c\3\2\2\2\u013c\u0141\3\2\2\2\u013d\u013e\7\66\2") - buf.write(u"\2\u013e\u013f\5\b\5\2\u013f\u0140\7\67\2\2\u0140\u0142") - buf.write(u"\3\2\2\2\u0141\u013d\3\2\2\2\u0141\u0142\3\2\2\2\u0142") - buf.write(u")\3\2\2\2\u0143\u0145\7\20\2\2\u0144\u0146\5\b\5\2\u0145") - buf.write(u"\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146+\3\2\2\2\u0147") - buf.write(u"\u014b\5.\30\2\u0148\u014a\5\60\31\2\u0149\u0148\3\2") - buf.write(u"\2\2\u014a\u014d\3\2\2\2\u014b\u0149\3\2\2\2\u014b\u014c") - buf.write(u"\3\2\2\2\u014c\u014f\3\2\2\2\u014d\u014b\3\2\2\2\u014e") - buf.write(u"\u0150\5\62\32\2\u014f\u014e\3\2\2\2\u014f\u0150\3\2") - buf.write(u"\2\2\u0150\u0151\3\2\2\2\u0151\u0152\7\b\2\2\u0152-\3") - buf.write(u"\2\2\2\u0153\u0154\7\21\2\2\u0154\u0155\5\b\5\2\u0155") - buf.write(u"\u0156\7M\2\2\u0156\u0157\5\36\20\2\u0157/\3\2\2\2\u0158") - buf.write(u"\u0159\7\22\2\2\u0159\u015a\5\b\5\2\u015a\u015b\7M\2") - buf.write(u"\2\u015b\u015c\5\36\20\2\u015c\61\3\2\2\2\u015d\u015e") - buf.write(u"\7\23\2\2\u015e\u015f\7M\2\2\u015f\u0160\5\36\20\2\u0160") - buf.write(u"\63\3\2\2\2\u0161\u0162\7\24\2\2\u0162\u0163\7R\2\2\u0163") - buf.write(u"\u0164\7\26\2\2\u0164\u0165\5\b\5\2\u0165\u0166\7+\2") - buf.write(u"\2\u0166\u0167\5\b\5\2\u0167\u0169\7\27\2\2\u0168\u016a") - buf.write(u"\7F\2\2\u0169\u0168\3\2\2\2\u0169\u016a\3\2\2\2\u016a") - buf.write(u"\u016b\3\2\2\2\u016b\u016c\t\3\2\2\u016c\u016d\7M\2\2") - buf.write(u"\u016d\u016e\5\36\20\2\u016e\u016f\7\b\2\2\u016f\65\3") - buf.write(u"\2\2\2\u0170\u0171\7\25\2\2\u0171\u0172\5\b\5\2\u0172") - buf.write(u"\u0173\7M\2\2\u0173\u0174\5\36\20\2\u0174\u0175\7\b\2") - buf.write(u"\2\u0175\67\3\2\2\2\u0176\u0179\5:\36\2\u0177\u0179\7") - buf.write(u"\5\2\2\u0178\u0176\3\2\2\2\u0178\u0177\3\2\2\2\u0179") - buf.write(u"\u017c\3\2\2\2\u017a\u0178\3\2\2\2\u017a\u017b\3\2\2") - buf.write(u"\2\u017b\u017d\3\2\2\2\u017c\u017a\3\2\2\2\u017d\u017e") - buf.write(u"\7\2\2\3\u017e9\3\2\2\2\u017f\u0180\7\36\2\2\u0180\u0181") - buf.write(u"\7R\2\2\u0181\u0182\5<\37\2\u0182;\3\2\2\2\u0183\u018d") - buf.write(u"\7M\2\2\u0184\u018c\7\5\2\2\u0185\u018c\5> \2\u0186\u018c") - buf.write(u"\5B\"\2\u0187\u018c\5D#\2\u0188\u018c\5J&\2\u0189\u018c") - buf.write(u"\5@!\2\u018a\u018c\5L\'\2\u018b\u0184\3\2\2\2\u018b\u0185") - buf.write(u"\3\2\2\2\u018b\u0186\3\2\2\2\u018b\u0187\3\2\2\2\u018b") - buf.write(u"\u0188\3\2\2\2\u018b\u0189\3\2\2\2\u018b\u018a\3\2\2") - buf.write(u"\2\u018c\u018f\3\2\2\2\u018d\u018b\3\2\2\2\u018d\u018e") - buf.write(u"\3\2\2\2\u018e\u0190\3\2\2\2\u018f\u018d\3\2\2\2\u0190") - buf.write(u"\u0191\7\b\2\2\u0191=\3\2\2\2\u0192\u0193\t\4\2\2\u0193") - buf.write(u"\u0198\7M\2\2\u0194\u0197\5(\25\2\u0195\u0197\7\5\2\2") - buf.write(u"\u0196\u0194\3\2\2\2\u0196\u0195\3\2\2\2\u0197\u019a") - buf.write(u"\3\2\2\2\u0198\u0196\3\2\2\2\u0198\u0199\3\2\2\2\u0199") - buf.write(u"\u019b\3\2\2\2\u019a\u0198\3\2\2\2\u019b\u019c\7\b\2") - buf.write(u"\2\u019c?\3\2\2\2\u019d\u019e\7#\2\2\u019e\u019f\7M\2") - buf.write(u"\2\u019f\u01a0\5\36\20\2\u01a0\u01a1\7\b\2\2\u01a1A\3") - buf.write(u"\2\2\2\u01a2\u01a3\7$\2\2\u01a3\u01aa\7M\2\2\u01a4\u01a9") - buf.write(u"\5\30\r\2\u01a5\u01a9\5\32\16\2\u01a6\u01a9\5\34\17\2") - buf.write(u"\u01a7\u01a9\7\5\2\2\u01a8\u01a4\3\2\2\2\u01a8\u01a5") - buf.write(u"\3\2\2\2\u01a8\u01a6\3\2\2\2\u01a8\u01a7\3\2\2\2\u01a9") - buf.write(u"\u01ac\3\2\2\2\u01aa\u01a8\3\2\2\2\u01aa\u01ab\3\2\2") - buf.write(u"\2\u01ab\u01ad\3\2\2\2\u01ac\u01aa\3\2\2\2\u01ad\u01ae") - buf.write(u"\7\b\2\2\u01aeC\3\2\2\2\u01af\u01b0\7%\2\2\u01b0\u01b5") - buf.write(u"\7M\2\2\u01b1\u01b4\5F$\2\u01b2\u01b4\7\5\2\2\u01b3\u01b1") - buf.write(u"\3\2\2\2\u01b3\u01b2\3\2\2\2\u01b4\u01b7\3\2\2\2\u01b5") - buf.write(u"\u01b3\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6\u01b8\3\2\2") - buf.write(u"\2\u01b7\u01b5\3\2\2\2\u01b8\u01b9\7\b\2\2\u01b9E\3\2") - buf.write(u"\2\2\u01ba\u01be\7R\2\2\u01bb\u01bc\7\63\2\2\u01bc\u01bd") - buf.write(u"\7R\2\2\u01bd\u01bf\7\65\2\2\u01be\u01bb\3\2\2\2\u01be") - buf.write(u"\u01bf\3\2\2\2\u01bf\u01c1\3\2\2\2\u01c0\u01c2\5\2\2") - buf.write(u"\2\u01c1\u01c0\3\2\2\2\u01c1\u01c2\3\2\2\2\u01c2\u01c3") - buf.write(u"\3\2\2\2\u01c3\u01c7\7\64\2\2\u01c4\u01c6\5H%\2\u01c5") - buf.write(u"\u01c4\3\2\2\2\u01c6\u01c9\3\2\2\2\u01c7\u01c5\3\2\2") - buf.write(u"\2\u01c7\u01c8\3\2\2\2\u01c8\u01cc\3\2\2\2\u01c9\u01c7") - buf.write(u"\3\2\2\2\u01ca\u01cd\7\'\2\2\u01cb\u01cd\7(\2\2\u01cc") - buf.write(u"\u01ca\3\2\2\2\u01cc\u01cb\3\2\2\2\u01cdG\3\2\2\2\u01ce") - buf.write(u"\u01d1\7)\2\2\u01cf\u01d1\7*\2\2\u01d0\u01ce\3\2\2\2") - buf.write(u"\u01d0\u01cf\3\2\2\2\u01d1I\3\2\2\2\u01d2\u01d3\7&\2") - buf.write(u"\2\u01d3\u01d6\7M\2\2\u01d4\u01d7\7(\2\2\u01d5\u01d7") - buf.write(u"\7\'\2\2\u01d6\u01d4\3\2\2\2\u01d6\u01d5\3\2\2\2\u01d7") - buf.write(u"K\3\2\2\2\u01d8\u01d9\7\16\2\2\u01d9\u01da\7R\2\2\u01da") - buf.write(u"\u01e3\7,\2\2\u01db\u01e0\5N(\2\u01dc\u01dd\7E\2\2\u01dd") - buf.write(u"\u01df\5N(\2\u01de\u01dc\3\2\2\2\u01df\u01e2\3\2\2\2") - buf.write(u"\u01e0\u01de\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1\u01e4") - buf.write(u"\3\2\2\2\u01e2\u01e0\3\2\2\2\u01e3\u01db\3\2\2\2\u01e3") - buf.write(u"\u01e4\3\2\2\2\u01e4\u01e5\3\2\2\2\u01e5\u01e7\7-\2\2") - buf.write(u"\u01e6\u01e8\5\2\2\2\u01e7\u01e6\3\2\2\2\u01e7\u01e8") - buf.write(u"\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01ea\7M\2\2\u01ea") - buf.write(u"\u01eb\5\36\20\2\u01eb\u01ec\7\b\2\2\u01ecM\3\2\2\2\u01ed") - buf.write(u"\u01ee\7R\2\2\u01ee\u01ef\5\2\2\2\u01efO\3\2\2\2>Vaf") - buf.write(u"lnr\u0081\u008a\u0090\u00a5\u00a7\u00ae\u00b3\u00b8\u00bf") - buf.write(u"\u00c8\u00cc\u00d2\u00dc\u00df\u00e4\u00ec\u00f2\u00ff") - buf.write(u"\u0103\u0107\u0109\u010e\u0113\u0119\u0121\u0126\u0129") - buf.write(u"\u0130\u0137\u013b\u0141\u0145\u014b\u014f\u0169\u0178") - buf.write(u"\u017a\u018b\u018d\u0196\u0198\u01a8\u01aa\u01b3\u01b5") - buf.write(u"\u01be\u01c1\u01c7\u01cc\u01d0\u01d6\u01e0\u01e3\u01e7") - return buf.getvalue() - + return [ + 4,1,88,605,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, + 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, + 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, + 2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7,32,2,33, + 7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2,39,7,39, + 2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,2,44,7,44,2,45,7,45,2,46, + 7,46,1,0,1,0,1,0,1,0,1,0,1,0,3,0,101,8,0,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,3,1,112,8,1,1,1,1,1,1,1,3,1,117,8,1,1,1,1,1,1,1,1,1, + 5,1,123,8,1,10,1,12,1,126,9,1,1,2,3,2,129,8,2,1,2,1,2,1,3,1,3,1, + 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,3,3,144,8,3,1,3,1,3,1,3,1,3,1, + 3,1,3,1,3,3,3,153,8,3,1,3,1,3,1,3,1,3,3,3,159,8,3,1,3,1,3,1,3,1, + 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,5,3,176,8,3,10,3,12, + 3,179,9,3,1,3,1,3,5,3,183,8,3,10,3,12,3,186,9,3,1,3,1,3,5,3,190, + 8,3,10,3,12,3,193,9,3,1,3,1,3,5,3,197,8,3,10,3,12,3,200,9,3,1,3, + 1,3,5,3,204,8,3,10,3,12,3,207,9,3,1,4,1,4,1,4,1,4,3,4,213,8,4,1, + 4,1,4,1,4,3,4,218,8,4,1,5,1,5,1,5,3,5,223,8,5,1,6,1,6,1,6,1,6,1, + 6,3,6,230,8,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,3,7,239,8,7,1,8,1,8,3, + 8,243,8,8,1,9,1,9,3,9,247,8,9,1,10,1,10,1,10,1,10,1,10,3,10,254, + 8,10,1,10,5,10,257,8,10,10,10,12,10,260,9,10,1,11,1,11,1,11,1,11, + 1,11,5,11,267,8,11,10,11,12,11,270,9,11,3,11,272,8,11,1,11,1,11, + 1,12,3,12,277,8,12,1,12,1,12,1,12,1,12,1,12,1,12,3,12,285,8,12,1, + 13,1,13,1,13,1,13,3,13,291,8,13,1,14,1,14,1,14,1,14,1,14,1,14,5, + 14,299,8,14,10,14,12,14,302,9,14,1,14,1,14,1,14,1,14,5,14,308,8, + 14,10,14,12,14,311,9,14,1,14,3,14,314,8,14,1,15,1,15,5,15,318,8, + 15,10,15,12,15,321,9,15,1,16,1,16,3,16,325,8,16,1,17,1,17,1,17,3, + 17,330,8,17,1,18,1,18,1,18,1,18,3,18,336,8,18,1,19,1,19,1,19,1,19, + 1,19,1,19,3,19,344,8,19,1,19,1,19,1,20,3,20,349,8,20,1,20,3,20,352, + 8,20,1,20,1,20,1,20,5,20,357,8,20,10,20,12,20,360,9,20,1,20,1,20, + 1,20,3,20,365,8,20,1,20,1,20,1,20,1,20,3,20,371,8,20,1,20,5,20,374, + 8,20,10,20,12,20,377,9,20,1,21,1,21,1,21,1,21,1,21,1,21,1,21,3,21, + 386,8,21,1,22,1,22,1,23,1,23,1,24,1,24,3,24,394,8,24,1,25,1,25,5, + 25,398,8,25,10,25,12,25,401,9,25,1,25,3,25,404,8,25,1,25,1,25,1, + 26,1,26,1,26,1,26,1,26,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1, + 28,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,3,29,430,8,29,1,29,1, + 29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,5, + 31,446,8,31,10,31,12,31,449,9,31,1,31,1,31,1,32,1,32,1,32,1,32,1, + 33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,5,33,465,8,33,10,33,12,33, + 468,9,33,1,33,1,33,1,34,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35, + 1,35,1,35,1,35,1,35,5,35,485,8,35,10,35,12,35,488,9,35,1,35,1,35, + 1,36,1,36,1,36,1,36,1,36,5,36,497,8,36,10,36,12,36,500,9,36,1,36, + 1,36,1,36,1,36,1,36,1,37,1,37,1,37,1,37,5,37,511,8,37,10,37,12,37, + 514,9,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39, + 1,39,1,39,5,39,529,8,39,10,39,12,39,532,9,39,1,39,1,39,1,40,1,40, + 1,40,1,40,5,40,540,8,40,10,40,12,40,543,9,40,1,40,1,40,1,41,1,41, + 1,41,1,41,3,41,551,8,41,1,41,3,41,554,8,41,1,41,1,41,5,41,558,8, + 41,10,41,12,41,561,9,41,1,41,1,41,3,41,565,8,41,1,42,1,42,3,42,569, + 8,42,1,43,1,43,1,43,1,43,3,43,575,8,43,1,44,1,44,1,44,1,44,1,44, + 1,44,5,44,583,8,44,10,44,12,44,586,9,44,3,44,588,8,44,1,44,1,44, + 3,44,592,8,44,1,44,1,44,1,44,1,44,1,45,1,45,1,45,1,46,1,46,1,46, + 1,46,1,46,0,2,2,6,47,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30, + 32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74, + 76,78,80,82,84,86,88,90,92,0,4,2,0,49,49,73,73,1,0,87,88,1,0,31, + 33,3,0,23,23,84,85,87,88,675,0,100,1,0,0,0,2,111,1,0,0,0,4,128,1, + 0,0,0,6,143,1,0,0,0,8,217,1,0,0,0,10,222,1,0,0,0,12,229,1,0,0,0, + 14,238,1,0,0,0,16,242,1,0,0,0,18,246,1,0,0,0,20,248,1,0,0,0,22,261, + 1,0,0,0,24,276,1,0,0,0,26,286,1,0,0,0,28,292,1,0,0,0,30,319,1,0, + 0,0,32,324,1,0,0,0,34,329,1,0,0,0,36,335,1,0,0,0,38,337,1,0,0,0, + 40,348,1,0,0,0,42,385,1,0,0,0,44,387,1,0,0,0,46,389,1,0,0,0,48,391, + 1,0,0,0,50,395,1,0,0,0,52,407,1,0,0,0,54,412,1,0,0,0,56,417,1,0, + 0,0,58,421,1,0,0,0,60,436,1,0,0,0,62,447,1,0,0,0,64,452,1,0,0,0, + 66,456,1,0,0,0,68,471,1,0,0,0,70,486,1,0,0,0,72,491,1,0,0,0,74,506, + 1,0,0,0,76,517,1,0,0,0,78,522,1,0,0,0,80,535,1,0,0,0,82,546,1,0, + 0,0,84,568,1,0,0,0,86,570,1,0,0,0,88,576,1,0,0,0,90,597,1,0,0,0, + 92,600,1,0,0,0,94,101,5,8,0,0,95,101,5,9,0,0,96,101,5,10,0,0,97, + 101,5,11,0,0,98,101,5,12,0,0,99,101,3,2,1,0,100,94,1,0,0,0,100,95, + 1,0,0,0,100,96,1,0,0,0,100,97,1,0,0,0,100,98,1,0,0,0,100,99,1,0, + 0,0,101,1,1,0,0,0,102,103,6,1,-1,0,103,104,5,47,0,0,104,105,3,2, + 1,0,105,106,5,48,0,0,106,112,1,0,0,0,107,108,5,87,0,0,108,109,5, + 77,0,0,109,112,3,2,1,2,110,112,5,86,0,0,111,102,1,0,0,0,111,107, + 1,0,0,0,111,110,1,0,0,0,112,124,1,0,0,0,113,116,10,3,0,0,114,117, + 5,75,0,0,115,117,5,77,0,0,116,114,1,0,0,0,116,115,1,0,0,0,117,118, + 1,0,0,0,118,123,3,2,1,4,119,120,10,4,0,0,120,121,5,76,0,0,121,123, + 3,4,2,0,122,113,1,0,0,0,122,119,1,0,0,0,123,126,1,0,0,0,124,122, + 1,0,0,0,124,125,1,0,0,0,125,3,1,0,0,0,126,124,1,0,0,0,127,129,7, + 0,0,0,128,127,1,0,0,0,128,129,1,0,0,0,129,130,1,0,0,0,130,131,5, + 87,0,0,131,5,1,0,0,0,132,133,6,3,-1,0,133,134,5,47,0,0,134,135,3, + 6,3,0,135,136,5,48,0,0,136,144,1,0,0,0,137,138,3,10,5,0,138,139, + 3,6,3,9,139,144,1,0,0,0,140,141,5,26,0,0,141,144,3,6,3,4,142,144, + 3,8,4,0,143,132,1,0,0,0,143,137,1,0,0,0,143,140,1,0,0,0,143,142, + 1,0,0,0,144,205,1,0,0,0,145,146,10,10,0,0,146,147,5,76,0,0,147,204, + 3,6,3,10,148,152,10,8,0,0,149,153,5,75,0,0,150,153,5,77,0,0,151, + 153,5,78,0,0,152,149,1,0,0,0,152,150,1,0,0,0,152,151,1,0,0,0,153, + 154,1,0,0,0,154,204,3,6,3,9,155,158,10,7,0,0,156,159,5,49,0,0,157, + 159,5,73,0,0,158,156,1,0,0,0,158,157,1,0,0,0,159,160,1,0,0,0,160, + 204,3,6,3,8,161,162,10,6,0,0,162,163,3,12,6,0,163,164,3,6,3,7,164, + 204,1,0,0,0,165,166,10,5,0,0,166,167,3,14,7,0,167,168,3,6,3,6,168, + 204,1,0,0,0,169,170,10,3,0,0,170,171,3,16,8,0,171,172,3,6,3,4,172, + 204,1,0,0,0,173,177,10,2,0,0,174,176,5,6,0,0,175,174,1,0,0,0,176, + 179,1,0,0,0,177,175,1,0,0,0,177,178,1,0,0,0,178,180,1,0,0,0,179, + 177,1,0,0,0,180,184,5,79,0,0,181,183,5,6,0,0,182,181,1,0,0,0,183, + 186,1,0,0,0,184,182,1,0,0,0,184,185,1,0,0,0,185,187,1,0,0,0,186, + 184,1,0,0,0,187,191,3,6,3,0,188,190,5,6,0,0,189,188,1,0,0,0,190, + 193,1,0,0,0,191,189,1,0,0,0,191,192,1,0,0,0,192,194,1,0,0,0,193, + 191,1,0,0,0,194,198,5,80,0,0,195,197,5,6,0,0,196,195,1,0,0,0,197, + 200,1,0,0,0,198,196,1,0,0,0,198,199,1,0,0,0,199,201,1,0,0,0,200, + 198,1,0,0,0,201,202,3,6,3,3,202,204,1,0,0,0,203,145,1,0,0,0,203, + 148,1,0,0,0,203,155,1,0,0,0,203,161,1,0,0,0,203,165,1,0,0,0,203, + 169,1,0,0,0,203,173,1,0,0,0,204,207,1,0,0,0,205,203,1,0,0,0,205, + 206,1,0,0,0,206,7,1,0,0,0,207,205,1,0,0,0,208,218,3,22,11,0,209, + 218,5,84,0,0,210,212,7,1,0,0,211,213,3,20,10,0,212,211,1,0,0,0,212, + 213,1,0,0,0,213,218,1,0,0,0,214,218,5,85,0,0,215,218,5,23,0,0,216, + 218,3,20,10,0,217,208,1,0,0,0,217,209,1,0,0,0,217,210,1,0,0,0,217, + 214,1,0,0,0,217,215,1,0,0,0,217,216,1,0,0,0,218,9,1,0,0,0,219,223, + 5,49,0,0,220,223,5,73,0,0,221,223,5,50,0,0,222,219,1,0,0,0,222,220, + 1,0,0,0,222,221,1,0,0,0,223,11,1,0,0,0,224,230,5,53,0,0,225,230, + 5,52,0,0,226,230,5,51,0,0,227,230,5,59,0,0,228,230,5,60,0,0,229, + 224,1,0,0,0,229,225,1,0,0,0,229,226,1,0,0,0,229,227,1,0,0,0,229, + 228,1,0,0,0,230,13,1,0,0,0,231,239,5,61,0,0,232,239,5,63,0,0,233, + 239,5,68,0,0,234,239,5,69,0,0,235,239,5,70,0,0,236,239,5,71,0,0, + 237,239,5,62,0,0,238,231,1,0,0,0,238,232,1,0,0,0,238,233,1,0,0,0, + 238,234,1,0,0,0,238,235,1,0,0,0,238,236,1,0,0,0,238,237,1,0,0,0, + 239,15,1,0,0,0,240,243,5,24,0,0,241,243,5,25,0,0,242,240,1,0,0,0, + 242,241,1,0,0,0,243,17,1,0,0,0,244,247,5,86,0,0,245,247,5,87,0,0, + 246,244,1,0,0,0,246,245,1,0,0,0,247,19,1,0,0,0,248,253,5,86,0,0, + 249,250,5,54,0,0,250,251,3,18,9,0,251,252,5,56,0,0,252,254,1,0,0, + 0,253,249,1,0,0,0,253,254,1,0,0,0,254,258,1,0,0,0,255,257,5,83,0, + 0,256,255,1,0,0,0,257,260,1,0,0,0,258,256,1,0,0,0,258,259,1,0,0, + 0,259,21,1,0,0,0,260,258,1,0,0,0,261,262,5,86,0,0,262,271,5,47,0, + 0,263,268,3,6,3,0,264,265,5,72,0,0,265,267,3,6,3,0,266,264,1,0,0, + 0,267,270,1,0,0,0,268,266,1,0,0,0,268,269,1,0,0,0,269,272,1,0,0, + 0,270,268,1,0,0,0,271,263,1,0,0,0,271,272,1,0,0,0,272,273,1,0,0, + 0,273,274,5,48,0,0,274,23,1,0,0,0,275,277,5,27,0,0,276,275,1,0,0, + 0,276,277,1,0,0,0,277,278,1,0,0,0,278,279,5,14,0,0,279,280,5,86, + 0,0,280,281,3,0,0,0,281,282,5,74,0,0,282,284,3,6,3,0,283,285,5,82, + 0,0,284,283,1,0,0,0,284,285,1,0,0,0,285,25,1,0,0,0,286,287,3,20, + 10,0,287,288,5,74,0,0,288,290,3,6,3,0,289,291,5,82,0,0,290,289,1, + 0,0,0,290,291,1,0,0,0,291,27,1,0,0,0,292,293,5,28,0,0,293,294,3, + 20,10,0,294,295,5,74,0,0,295,309,3,6,3,0,296,300,5,72,0,0,297,299, + 5,6,0,0,298,297,1,0,0,0,299,302,1,0,0,0,300,298,1,0,0,0,300,301, + 1,0,0,0,301,303,1,0,0,0,302,300,1,0,0,0,303,304,3,20,10,0,304,305, + 5,74,0,0,305,306,3,6,3,0,306,308,1,0,0,0,307,296,1,0,0,0,308,311, + 1,0,0,0,309,307,1,0,0,0,309,310,1,0,0,0,310,313,1,0,0,0,311,309, + 1,0,0,0,312,314,5,82,0,0,313,312,1,0,0,0,313,314,1,0,0,0,314,29, + 1,0,0,0,315,318,3,32,16,0,316,318,5,6,0,0,317,315,1,0,0,0,317,316, + 1,0,0,0,318,321,1,0,0,0,319,317,1,0,0,0,319,320,1,0,0,0,320,31,1, + 0,0,0,321,319,1,0,0,0,322,325,3,36,18,0,323,325,3,34,17,0,324,322, + 1,0,0,0,324,323,1,0,0,0,325,33,1,0,0,0,326,330,3,50,25,0,327,330, + 3,58,29,0,328,330,3,60,30,0,329,326,1,0,0,0,329,327,1,0,0,0,329, + 328,1,0,0,0,330,35,1,0,0,0,331,336,3,38,19,0,332,336,3,22,11,0,333, + 336,3,40,20,0,334,336,3,48,24,0,335,331,1,0,0,0,335,332,1,0,0,0, + 335,333,1,0,0,0,335,334,1,0,0,0,336,37,1,0,0,0,337,343,3,20,10,0, + 338,344,5,74,0,0,339,344,5,64,0,0,340,344,5,65,0,0,341,344,5,66, + 0,0,342,344,5,67,0,0,343,338,1,0,0,0,343,339,1,0,0,0,343,340,1,0, + 0,0,343,341,1,0,0,0,343,342,1,0,0,0,344,345,1,0,0,0,345,346,3,6, + 3,0,346,39,1,0,0,0,347,349,5,27,0,0,348,347,1,0,0,0,348,349,1,0, + 0,0,349,351,1,0,0,0,350,352,5,14,0,0,351,350,1,0,0,0,351,352,1,0, + 0,0,352,353,1,0,0,0,353,358,3,20,10,0,354,355,5,72,0,0,355,357,3, + 20,10,0,356,354,1,0,0,0,357,360,1,0,0,0,358,356,1,0,0,0,358,359, + 1,0,0,0,359,361,1,0,0,0,360,358,1,0,0,0,361,364,3,0,0,0,362,363, + 5,74,0,0,363,365,3,6,3,0,364,362,1,0,0,0,364,365,1,0,0,0,365,370, + 1,0,0,0,366,367,5,57,0,0,367,368,3,6,3,0,368,369,5,58,0,0,369,371, + 1,0,0,0,370,366,1,0,0,0,370,371,1,0,0,0,371,375,1,0,0,0,372,374, + 3,42,21,0,373,372,1,0,0,0,374,377,1,0,0,0,375,373,1,0,0,0,375,376, + 1,0,0,0,376,41,1,0,0,0,377,375,1,0,0,0,378,386,5,43,0,0,379,386, + 5,44,0,0,380,381,5,45,0,0,381,382,3,44,22,0,382,383,5,81,0,0,383, + 384,3,46,23,0,384,386,1,0,0,0,385,378,1,0,0,0,385,379,1,0,0,0,385, + 380,1,0,0,0,386,43,1,0,0,0,387,388,5,86,0,0,388,45,1,0,0,0,389,390, + 5,86,0,0,390,47,1,0,0,0,391,393,5,15,0,0,392,394,3,6,3,0,393,392, + 1,0,0,0,393,394,1,0,0,0,394,49,1,0,0,0,395,399,3,52,26,0,396,398, + 3,54,27,0,397,396,1,0,0,0,398,401,1,0,0,0,399,397,1,0,0,0,399,400, + 1,0,0,0,400,403,1,0,0,0,401,399,1,0,0,0,402,404,3,56,28,0,403,402, + 1,0,0,0,403,404,1,0,0,0,404,405,1,0,0,0,405,406,5,7,0,0,406,51,1, + 0,0,0,407,408,5,16,0,0,408,409,3,6,3,0,409,410,5,80,0,0,410,411, + 3,30,15,0,411,53,1,0,0,0,412,413,5,17,0,0,413,414,3,6,3,0,414,415, + 5,80,0,0,415,416,3,30,15,0,416,55,1,0,0,0,417,418,5,18,0,0,418,419, + 5,80,0,0,419,420,3,30,15,0,420,57,1,0,0,0,421,422,5,19,0,0,422,423, + 5,86,0,0,423,424,5,21,0,0,424,425,3,6,3,0,425,426,5,46,0,0,426,427, + 3,6,3,0,427,429,5,22,0,0,428,430,5,73,0,0,429,428,1,0,0,0,429,430, + 1,0,0,0,430,431,1,0,0,0,431,432,7,1,0,0,432,433,5,80,0,0,433,434, + 3,30,15,0,434,435,5,7,0,0,435,59,1,0,0,0,436,437,5,20,0,0,437,438, + 3,6,3,0,438,439,5,80,0,0,439,440,3,30,15,0,440,441,5,7,0,0,441,61, + 1,0,0,0,442,446,3,64,32,0,443,446,3,68,34,0,444,446,5,6,0,0,445, + 442,1,0,0,0,445,443,1,0,0,0,445,444,1,0,0,0,446,449,1,0,0,0,447, + 445,1,0,0,0,447,448,1,0,0,0,448,450,1,0,0,0,449,447,1,0,0,0,450, + 451,5,0,0,1,451,63,1,0,0,0,452,453,5,29,0,0,453,454,5,86,0,0,454, + 455,3,66,33,0,455,65,1,0,0,0,456,466,5,80,0,0,457,465,5,6,0,0,458, + 465,3,74,37,0,459,465,3,78,39,0,460,465,3,80,40,0,461,465,3,86,43, + 0,462,465,3,76,38,0,463,465,3,88,44,0,464,457,1,0,0,0,464,458,1, + 0,0,0,464,459,1,0,0,0,464,460,1,0,0,0,464,461,1,0,0,0,464,462,1, + 0,0,0,464,463,1,0,0,0,465,468,1,0,0,0,466,464,1,0,0,0,466,467,1, + 0,0,0,467,469,1,0,0,0,468,466,1,0,0,0,469,470,5,7,0,0,470,67,1,0, + 0,0,471,472,5,30,0,0,472,473,5,86,0,0,473,474,5,80,0,0,474,475,3, + 70,35,0,475,69,1,0,0,0,476,485,5,6,0,0,477,485,3,74,37,0,478,485, + 3,78,39,0,479,485,3,80,40,0,480,485,3,86,43,0,481,485,3,88,44,0, + 482,485,3,72,36,0,483,485,3,76,38,0,484,476,1,0,0,0,484,477,1,0, + 0,0,484,478,1,0,0,0,484,479,1,0,0,0,484,480,1,0,0,0,484,481,1,0, + 0,0,484,482,1,0,0,0,484,483,1,0,0,0,485,488,1,0,0,0,486,484,1,0, + 0,0,486,487,1,0,0,0,487,489,1,0,0,0,488,486,1,0,0,0,489,490,5,7, + 0,0,490,71,1,0,0,0,491,492,5,39,0,0,492,493,5,47,0,0,493,498,5,86, + 0,0,494,495,5,72,0,0,495,497,3,92,46,0,496,494,1,0,0,0,497,500,1, + 0,0,0,498,496,1,0,0,0,498,499,1,0,0,0,499,501,1,0,0,0,500,498,1, + 0,0,0,501,502,5,48,0,0,502,503,5,80,0,0,503,504,3,30,15,0,504,505, + 5,7,0,0,505,73,1,0,0,0,506,507,7,2,0,0,507,512,5,80,0,0,508,511, + 3,40,20,0,509,511,5,6,0,0,510,508,1,0,0,0,510,509,1,0,0,0,511,514, + 1,0,0,0,512,510,1,0,0,0,512,513,1,0,0,0,513,515,1,0,0,0,514,512, + 1,0,0,0,515,516,5,7,0,0,516,75,1,0,0,0,517,518,5,34,0,0,518,519, + 5,80,0,0,519,520,3,30,15,0,520,521,5,7,0,0,521,77,1,0,0,0,522,523, + 5,35,0,0,523,530,5,80,0,0,524,529,3,24,12,0,525,529,3,26,13,0,526, + 529,3,28,14,0,527,529,5,6,0,0,528,524,1,0,0,0,528,525,1,0,0,0,528, + 526,1,0,0,0,528,527,1,0,0,0,529,532,1,0,0,0,530,528,1,0,0,0,530, + 531,1,0,0,0,531,533,1,0,0,0,532,530,1,0,0,0,533,534,5,7,0,0,534, + 79,1,0,0,0,535,536,5,36,0,0,536,541,5,80,0,0,537,540,3,82,41,0,538, + 540,5,6,0,0,539,537,1,0,0,0,539,538,1,0,0,0,540,543,1,0,0,0,541, + 539,1,0,0,0,541,542,1,0,0,0,542,544,1,0,0,0,543,541,1,0,0,0,544, + 545,5,7,0,0,545,81,1,0,0,0,546,550,5,86,0,0,547,548,5,54,0,0,548, + 549,5,86,0,0,549,551,5,56,0,0,550,547,1,0,0,0,550,551,1,0,0,0,551, + 553,1,0,0,0,552,554,3,0,0,0,553,552,1,0,0,0,553,554,1,0,0,0,554, + 555,1,0,0,0,555,559,5,55,0,0,556,558,3,84,42,0,557,556,1,0,0,0,558, + 561,1,0,0,0,559,557,1,0,0,0,559,560,1,0,0,0,560,564,1,0,0,0,561, + 559,1,0,0,0,562,565,5,38,0,0,563,565,5,40,0,0,564,562,1,0,0,0,564, + 563,1,0,0,0,565,83,1,0,0,0,566,569,5,41,0,0,567,569,5,42,0,0,568, + 566,1,0,0,0,568,567,1,0,0,0,569,85,1,0,0,0,570,571,5,37,0,0,571, + 574,5,80,0,0,572,575,5,40,0,0,573,575,5,38,0,0,574,572,1,0,0,0,574, + 573,1,0,0,0,575,87,1,0,0,0,576,577,5,13,0,0,577,578,5,86,0,0,578, + 587,5,47,0,0,579,584,3,90,45,0,580,581,5,72,0,0,581,583,3,90,45, + 0,582,580,1,0,0,0,583,586,1,0,0,0,584,582,1,0,0,0,584,585,1,0,0, + 0,585,588,1,0,0,0,586,584,1,0,0,0,587,579,1,0,0,0,587,588,1,0,0, + 0,588,589,1,0,0,0,589,591,5,48,0,0,590,592,3,0,0,0,591,590,1,0,0, + 0,591,592,1,0,0,0,592,593,1,0,0,0,593,594,5,80,0,0,594,595,3,30, + 15,0,595,596,5,7,0,0,596,89,1,0,0,0,597,598,5,86,0,0,598,599,3,0, + 0,0,599,91,1,0,0,0,600,601,5,86,0,0,601,602,5,74,0,0,602,603,7,3, + 0,0,603,93,1,0,0,0,71,100,111,116,122,124,128,143,152,158,177,184, + 191,198,203,205,212,217,222,229,238,242,246,253,258,268,271,276, + 284,290,300,309,313,317,319,324,329,335,343,348,351,358,364,370, + 375,385,393,399,403,429,445,447,464,466,484,486,498,510,512,528, + 530,539,541,550,553,559,564,568,574,584,587,591 + ] class PyNestMLParser ( Parser ): @@ -266,48 +249,49 @@ class PyNestMLParser ( Parser ): sharedContextCache = PredictionContextCache() - literalNames = [ u"", u"", u"", u"", - u"", u"", u"'end'", u"'integer'", - u"'real'", u"'string'", u"'boolean'", u"'void'", u"'function'", - u"'inline'", u"'return'", u"'if'", u"'elif'", u"'else'", - u"'for'", u"'while'", u"'in'", u"'step'", u"'inf'", - u"'and'", u"'or'", u"'not'", u"'recordable'", u"'kernel'", - u"'neuron'", u"'state'", u"'parameters'", u"'internals'", - u"'initial_values'", u"'update'", u"'equations'", u"'input'", - u"'output'", u"'current'", u"'spike'", u"'inhibitory'", - u"'excitatory'", u"'...'", u"'('", u"')'", u"'+'", - u"'~'", u"'|'", u"'^'", u"'&'", u"'['", u"'<-'", u"']'", - u"'[['", u"']]'", u"'<<'", u"'>>'", u"'<'", u"'>'", - u"'<='", u"'+='", u"'-='", u"'*='", u"'/='", u"'=='", - u"'!='", u"'<>'", u"'>='", u"','", u"'-'", u"'='", - u"'*'", u"'**'", u"'/'", u"'%'", u"'?'", u"':'", u"';'", - u"'''" ] - - symbolicNames = [ u"", u"SL_COMMENT", u"ML_COMMENT", u"NEWLINE", - u"WS", u"LINE_ESCAPE", u"END_KEYWORD", u"INTEGER_KEYWORD", - u"REAL_KEYWORD", u"STRING_KEYWORD", u"BOOLEAN_KEYWORD", - u"VOID_KEYWORD", u"FUNCTION_KEYWORD", u"INLINE_KEYWORD", - u"RETURN_KEYWORD", u"IF_KEYWORD", u"ELIF_KEYWORD", - u"ELSE_KEYWORD", u"FOR_KEYWORD", u"WHILE_KEYWORD", - u"IN_KEYWORD", u"STEP_KEYWORD", u"INF_KEYWORD", u"AND_KEYWORD", - u"OR_KEYWORD", u"NOT_KEYWORD", u"RECORDABLE_KEYWORD", - u"KERNEL_KEYWORD", u"NEURON_KEYWORD", u"STATE_KEYWORD", - u"PARAMETERS_KEYWORD", u"INTERNALS_KEYWORD", u"INITIAL_VALUES_KEYWORD", - u"UPDATE_KEYWORD", u"EQUATIONS_KEYWORD", u"INPUT_KEYWORD", - u"OUTPUT_KEYWORD", u"CURRENT_KEYWORD", u"SPIKE_KEYWORD", - u"INHIBITORY_KEYWORD", u"EXCITATORY_KEYWORD", u"ELLIPSIS", - u"LEFT_PAREN", u"RIGHT_PAREN", u"PLUS", u"TILDE", - u"PIPE", u"CARET", u"AMPERSAND", u"LEFT_SQUARE_BRACKET", - u"LEFT_ANGLE_MINUS", u"RIGHT_SQUARE_BRACKET", u"LEFT_LEFT_SQUARE", - u"RIGHT_RIGHT_SQUARE", u"LEFT_LEFT_ANGLE", u"RIGHT_RIGHT_ANGLE", - u"LEFT_ANGLE", u"RIGHT_ANGLE", u"LEFT_ANGLE_EQUALS", - u"PLUS_EQUALS", u"MINUS_EQUALS", u"STAR_EQUALS", u"FORWARD_SLASH_EQUALS", - u"EQUALS_EQUALS", u"EXCLAMATION_EQUALS", u"LEFT_ANGLE_RIGHT_ANGLE", - u"RIGHT_ANGLE_EQUALS", u"COMMA", u"MINUS", u"EQUALS", - u"STAR", u"STAR_STAR", u"FORWARD_SLASH", u"PERCENT", - u"QUESTION", u"COLON", u"SEMICOLON", u"DIFFERENTIAL_ORDER", - u"BOOLEAN_LITERAL", u"STRING_LITERAL", u"NAME", u"UNSIGNED_INTEGER", - u"FLOAT" ] + literalNames = [ "", "'\"\"\"'", "", "", + "", "", "", "'end'", "'integer'", + "'real'", "'string'", "'boolean'", "'void'", "'function'", + "'inline'", "'return'", "'if'", "'elif'", "'else'", + "'for'", "'while'", "'in'", "'step'", "'inf'", "'and'", + "'or'", "'not'", "'recordable'", "'kernel'", "'neuron'", + "'synapse'", "'state'", "'parameters'", "'internals'", + "'update'", "'equations'", "'input'", "'output'", "'continuous'", + "'onReceive'", "'spike'", "'inhibitory'", "'excitatory'", + "'@homogeneous'", "'@heterogeneous'", "'@'", "'...'", + "'('", "')'", "'+'", "'~'", "'|'", "'^'", "'&'", "'['", + "'<-'", "']'", "'[['", "']]'", "'<<'", "'>>'", "'<'", + "'>'", "'<='", "'+='", "'-='", "'*='", "'/='", "'=='", + "'!='", "'<>'", "'>='", "','", "'-'", "'='", "'*'", + "'**'", "'/'", "'%'", "'?'", "':'", "'::'", "';'", + "'''" ] + + symbolicNames = [ "", "DOCSTRING_TRIPLEQUOTE", "WS", "LINE_ESCAPE", + "DOCSTRING", "SL_COMMENT", "NEWLINE", "END_KEYWORD", + "INTEGER_KEYWORD", "REAL_KEYWORD", "STRING_KEYWORD", + "BOOLEAN_KEYWORD", "VOID_KEYWORD", "FUNCTION_KEYWORD", + "INLINE_KEYWORD", "RETURN_KEYWORD", "IF_KEYWORD", + "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", + "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", "AND_KEYWORD", + "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", + "KERNEL_KEYWORD", "NEURON_KEYWORD", "SYNAPSE_KEYWORD", + "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", + "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", + "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", + "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", + "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", + "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", + "TILDE", "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", + "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", + "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", + "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", + "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", + "EQUALS_EQUALS", "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", + "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", "EQUALS", + "STAR", "STAR_STAR", "FORWARD_SLASH", "PERCENT", "QUESTION", + "COLON", "DOUBLE_COLON", "SEMICOLON", "DIFFERENTIAL_ORDER", + "BOOLEAN_LITERAL", "STRING_LITERAL", "NAME", "UNSIGNED_INTEGER", + "FLOAT" ] RULE_dataType = 0 RULE_unitType = 1 @@ -318,145 +302,162 @@ class PyNestMLParser ( Parser ): RULE_bitOperator = 6 RULE_comparisonOperator = 7 RULE_logicalOperator = 8 - RULE_variable = 9 - RULE_functionCall = 10 - RULE_inlineExpression = 11 - RULE_odeEquation = 12 - RULE_kernel = 13 - RULE_block = 14 - RULE_stmt = 15 - RULE_compoundStmt = 16 - RULE_smallStmt = 17 - RULE_assignment = 18 - RULE_declaration = 19 - RULE_returnStmt = 20 - RULE_ifStmt = 21 - RULE_ifClause = 22 - RULE_elifClause = 23 - RULE_elseClause = 24 - RULE_forStmt = 25 - RULE_whileStmt = 26 - RULE_nestMLCompilationUnit = 27 - RULE_neuron = 28 - RULE_body = 29 - RULE_blockWithVariables = 30 - RULE_updateBlock = 31 - RULE_equationsBlock = 32 - RULE_inputBlock = 33 - RULE_inputPort = 34 - RULE_inputQualifier = 35 - RULE_outputBlock = 36 - RULE_function = 37 - RULE_parameter = 38 - - ruleNames = [ u"dataType", u"unitType", u"unitTypeExponent", u"expression", - u"simpleExpression", u"unaryOperator", u"bitOperator", - u"comparisonOperator", u"logicalOperator", u"variable", - u"functionCall", u"inlineExpression", u"odeEquation", - u"kernel", u"block", u"stmt", u"compoundStmt", u"smallStmt", - u"assignment", u"declaration", u"returnStmt", u"ifStmt", - u"ifClause", u"elifClause", u"elseClause", u"forStmt", - u"whileStmt", u"nestMLCompilationUnit", u"neuron", u"body", - u"blockWithVariables", u"updateBlock", u"equationsBlock", - u"inputBlock", u"inputPort", u"inputQualifier", u"outputBlock", - u"function", u"parameter" ] + RULE_indexParameter = 9 + RULE_variable = 10 + RULE_functionCall = 11 + RULE_inlineExpression = 12 + RULE_odeEquation = 13 + RULE_kernel = 14 + RULE_block = 15 + RULE_stmt = 16 + RULE_compoundStmt = 17 + RULE_smallStmt = 18 + RULE_assignment = 19 + RULE_declaration = 20 + RULE_anyDecorator = 21 + RULE_namespaceDecoratorNamespace = 22 + RULE_namespaceDecoratorName = 23 + RULE_returnStmt = 24 + RULE_ifStmt = 25 + RULE_ifClause = 26 + RULE_elifClause = 27 + RULE_elseClause = 28 + RULE_forStmt = 29 + RULE_whileStmt = 30 + RULE_nestMLCompilationUnit = 31 + RULE_neuron = 32 + RULE_neuronBody = 33 + RULE_synapse = 34 + RULE_synapseBody = 35 + RULE_onReceiveBlock = 36 + RULE_blockWithVariables = 37 + RULE_updateBlock = 38 + RULE_equationsBlock = 39 + RULE_inputBlock = 40 + RULE_inputPort = 41 + RULE_inputQualifier = 42 + RULE_outputBlock = 43 + RULE_function = 44 + RULE_parameter = 45 + RULE_constParameter = 46 + + ruleNames = [ "dataType", "unitType", "unitTypeExponent", "expression", + "simpleExpression", "unaryOperator", "bitOperator", "comparisonOperator", + "logicalOperator", "indexParameter", "variable", "functionCall", + "inlineExpression", "odeEquation", "kernel", "block", + "stmt", "compoundStmt", "smallStmt", "assignment", "declaration", + "anyDecorator", "namespaceDecoratorNamespace", "namespaceDecoratorName", + "returnStmt", "ifStmt", "ifClause", "elifClause", "elseClause", + "forStmt", "whileStmt", "nestMLCompilationUnit", "neuron", + "neuronBody", "synapse", "synapseBody", "onReceiveBlock", + "blockWithVariables", "updateBlock", "equationsBlock", + "inputBlock", "inputPort", "inputQualifier", "outputBlock", + "function", "parameter", "constParameter" ] EOF = Token.EOF - SL_COMMENT=1 - ML_COMMENT=2 - NEWLINE=3 - WS=4 - LINE_ESCAPE=5 - END_KEYWORD=6 - INTEGER_KEYWORD=7 - REAL_KEYWORD=8 - STRING_KEYWORD=9 - BOOLEAN_KEYWORD=10 - VOID_KEYWORD=11 - FUNCTION_KEYWORD=12 - INLINE_KEYWORD=13 - RETURN_KEYWORD=14 - IF_KEYWORD=15 - ELIF_KEYWORD=16 - ELSE_KEYWORD=17 - FOR_KEYWORD=18 - WHILE_KEYWORD=19 - IN_KEYWORD=20 - STEP_KEYWORD=21 - INF_KEYWORD=22 - AND_KEYWORD=23 - OR_KEYWORD=24 - NOT_KEYWORD=25 - RECORDABLE_KEYWORD=26 - KERNEL_KEYWORD=27 - NEURON_KEYWORD=28 - STATE_KEYWORD=29 - PARAMETERS_KEYWORD=30 - INTERNALS_KEYWORD=31 - INITIAL_VALUES_KEYWORD=32 - UPDATE_KEYWORD=33 - EQUATIONS_KEYWORD=34 - INPUT_KEYWORD=35 - OUTPUT_KEYWORD=36 - CURRENT_KEYWORD=37 - SPIKE_KEYWORD=38 - INHIBITORY_KEYWORD=39 - EXCITATORY_KEYWORD=40 - ELLIPSIS=41 - LEFT_PAREN=42 - RIGHT_PAREN=43 - PLUS=44 - TILDE=45 - PIPE=46 - CARET=47 - AMPERSAND=48 - LEFT_SQUARE_BRACKET=49 - LEFT_ANGLE_MINUS=50 - RIGHT_SQUARE_BRACKET=51 - LEFT_LEFT_SQUARE=52 - RIGHT_RIGHT_SQUARE=53 - LEFT_LEFT_ANGLE=54 - RIGHT_RIGHT_ANGLE=55 - LEFT_ANGLE=56 - RIGHT_ANGLE=57 - LEFT_ANGLE_EQUALS=58 - PLUS_EQUALS=59 - MINUS_EQUALS=60 - STAR_EQUALS=61 - FORWARD_SLASH_EQUALS=62 - EQUALS_EQUALS=63 - EXCLAMATION_EQUALS=64 - LEFT_ANGLE_RIGHT_ANGLE=65 - RIGHT_ANGLE_EQUALS=66 - COMMA=67 - MINUS=68 - EQUALS=69 - STAR=70 - STAR_STAR=71 - FORWARD_SLASH=72 - PERCENT=73 - QUESTION=74 - COLON=75 - SEMICOLON=76 - DIFFERENTIAL_ORDER=77 - BOOLEAN_LITERAL=78 - STRING_LITERAL=79 - NAME=80 - UNSIGNED_INTEGER=81 - FLOAT=82 - - def __init__(self, input, output=sys.stdout): - super(PyNestMLParser, self).__init__(input, output=output) - self.checkVersion("4.7.1") + DOCSTRING_TRIPLEQUOTE=1 + WS=2 + LINE_ESCAPE=3 + DOCSTRING=4 + SL_COMMENT=5 + NEWLINE=6 + END_KEYWORD=7 + INTEGER_KEYWORD=8 + REAL_KEYWORD=9 + STRING_KEYWORD=10 + BOOLEAN_KEYWORD=11 + VOID_KEYWORD=12 + FUNCTION_KEYWORD=13 + INLINE_KEYWORD=14 + RETURN_KEYWORD=15 + IF_KEYWORD=16 + ELIF_KEYWORD=17 + ELSE_KEYWORD=18 + FOR_KEYWORD=19 + WHILE_KEYWORD=20 + IN_KEYWORD=21 + STEP_KEYWORD=22 + INF_KEYWORD=23 + AND_KEYWORD=24 + OR_KEYWORD=25 + NOT_KEYWORD=26 + RECORDABLE_KEYWORD=27 + KERNEL_KEYWORD=28 + NEURON_KEYWORD=29 + SYNAPSE_KEYWORD=30 + STATE_KEYWORD=31 + PARAMETERS_KEYWORD=32 + INTERNALS_KEYWORD=33 + UPDATE_KEYWORD=34 + EQUATIONS_KEYWORD=35 + INPUT_KEYWORD=36 + OUTPUT_KEYWORD=37 + CONTINUOUS_KEYWORD=38 + ON_RECEIVE_KEYWORD=39 + SPIKE_KEYWORD=40 + INHIBITORY_KEYWORD=41 + EXCITATORY_KEYWORD=42 + DECORATOR_HOMOGENEOUS=43 + DECORATOR_HETEROGENEOUS=44 + AT=45 + ELLIPSIS=46 + LEFT_PAREN=47 + RIGHT_PAREN=48 + PLUS=49 + TILDE=50 + PIPE=51 + CARET=52 + AMPERSAND=53 + LEFT_SQUARE_BRACKET=54 + LEFT_ANGLE_MINUS=55 + RIGHT_SQUARE_BRACKET=56 + LEFT_LEFT_SQUARE=57 + RIGHT_RIGHT_SQUARE=58 + LEFT_LEFT_ANGLE=59 + RIGHT_RIGHT_ANGLE=60 + LEFT_ANGLE=61 + RIGHT_ANGLE=62 + LEFT_ANGLE_EQUALS=63 + PLUS_EQUALS=64 + MINUS_EQUALS=65 + STAR_EQUALS=66 + FORWARD_SLASH_EQUALS=67 + EQUALS_EQUALS=68 + EXCLAMATION_EQUALS=69 + LEFT_ANGLE_RIGHT_ANGLE=70 + RIGHT_ANGLE_EQUALS=71 + COMMA=72 + MINUS=73 + EQUALS=74 + STAR=75 + STAR_STAR=76 + FORWARD_SLASH=77 + PERCENT=78 + QUESTION=79 + COLON=80 + DOUBLE_COLON=81 + SEMICOLON=82 + DIFFERENTIAL_ORDER=83 + BOOLEAN_LITERAL=84 + STRING_LITERAL=85 + NAME=86 + UNSIGNED_INTEGER=87 + FLOAT=88 + + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.10") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None + class DataTypeContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.DataTypeContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.isInt = None # Token self.isReal = None # Token @@ -487,8 +488,8 @@ def unitType(self): def getRuleIndex(self): return PyNestMLParser.RULE_dataType - def accept(self, visitor): - if hasattr(visitor, "visitDataType"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitDataType" ): return visitor.visitDataType(self) else: return visitor.visitChildren(self) @@ -501,37 +502,37 @@ def dataType(self): localctx = PyNestMLParser.DataTypeContext(self, self._ctx, self.state) self.enterRule(localctx, 0, self.RULE_dataType) try: - self.state = 84 + self.state = 100 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.INTEGER_KEYWORD]: self.enterOuterAlt(localctx, 1) - self.state = 78 + self.state = 94 localctx.isInt = self.match(PyNestMLParser.INTEGER_KEYWORD) pass elif token in [PyNestMLParser.REAL_KEYWORD]: self.enterOuterAlt(localctx, 2) - self.state = 79 + self.state = 95 localctx.isReal = self.match(PyNestMLParser.REAL_KEYWORD) pass elif token in [PyNestMLParser.STRING_KEYWORD]: self.enterOuterAlt(localctx, 3) - self.state = 80 + self.state = 96 localctx.isString = self.match(PyNestMLParser.STRING_KEYWORD) pass elif token in [PyNestMLParser.BOOLEAN_KEYWORD]: self.enterOuterAlt(localctx, 4) - self.state = 81 + self.state = 97 localctx.isBool = self.match(PyNestMLParser.BOOLEAN_KEYWORD) pass elif token in [PyNestMLParser.VOID_KEYWORD]: self.enterOuterAlt(localctx, 5) - self.state = 82 + self.state = 98 localctx.isVoid = self.match(PyNestMLParser.VOID_KEYWORD) pass elif token in [PyNestMLParser.LEFT_PAREN, PyNestMLParser.NAME, PyNestMLParser.UNSIGNED_INTEGER]: self.enterOuterAlt(localctx, 6) - self.state = 83 + self.state = 99 localctx.unit = self.unitType(0) pass else: @@ -545,10 +546,12 @@ def dataType(self): self.exitRule() return localctx + class UnitTypeContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.UnitTypeContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.base = None # UnitTypeContext self.left = None # UnitTypeContext @@ -566,7 +569,7 @@ def __init__(self, parser, parent=None, invokingState=-1): def LEFT_PAREN(self): return self.getToken(PyNestMLParser.LEFT_PAREN, 0) - def unitType(self, i=None): + def unitType(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.UnitTypeContext) else: @@ -598,15 +601,15 @@ def unitTypeExponent(self): def getRuleIndex(self): return PyNestMLParser.RULE_unitType - def accept(self, visitor): - if hasattr(visitor, "visitUnitType"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitUnitType" ): return visitor.visitUnitType(self) else: return visitor.visitChildren(self) - def unitType(self, _p=0): + def unitType(self, _p:int=0): _parentctx = self._ctx _parentState = self.state localctx = PyNestMLParser.UnitTypeContext(self, self._ctx, _parentState) @@ -615,34 +618,34 @@ def unitType(self, _p=0): self.enterRecursionRule(localctx, 2, self.RULE_unitType, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 95 + self.state = 111 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.LEFT_PAREN]: - self.state = 87 + self.state = 103 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) - self.state = 88 + self.state = 104 localctx.compoundUnit = self.unitType(0) - self.state = 89 + self.state = 105 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [PyNestMLParser.UNSIGNED_INTEGER]: - self.state = 91 + self.state = 107 localctx.unitlessLiteral = self.match(PyNestMLParser.UNSIGNED_INTEGER) - self.state = 92 + self.state = 108 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) - self.state = 93 + self.state = 109 localctx.right = self.unitType(2) pass elif token in [PyNestMLParser.NAME]: - self.state = 94 + self.state = 110 localctx.unit = self.match(PyNestMLParser.NAME) pass else: raise NoViableAltException(self) self._ctx.stop = self._input.LT(-1) - self.state = 108 + self.state = 124 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -650,32 +653,32 @@ def unitType(self, _p=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 106 + self.state = 122 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,3,self._ctx) if la_ == 1: localctx = PyNestMLParser.UnitTypeContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_unitType) - self.state = 97 + self.state = 113 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 100 + self.state = 116 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.STAR]: - self.state = 98 + self.state = 114 localctx.timesOp = self.match(PyNestMLParser.STAR) pass elif token in [PyNestMLParser.FORWARD_SLASH]: - self.state = 99 + self.state = 115 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass else: raise NoViableAltException(self) - self.state = 102 + self.state = 118 localctx.right = self.unitType(4) pass @@ -683,18 +686,18 @@ def unitType(self, _p=0): localctx = PyNestMLParser.UnitTypeContext(self, _parentctx, _parentState) localctx.base = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_unitType) - self.state = 103 + self.state = 119 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 104 + self.state = 120 localctx.powOp = self.match(PyNestMLParser.STAR_STAR) - self.state = 105 + self.state = 121 localctx.exponent = self.unitTypeExponent() pass - self.state = 110 + self.state = 126 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) @@ -706,10 +709,12 @@ def unitType(self, _p=0): self.unrollRecursionContexts(_parentctx) return localctx + class UnitTypeExponentContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.UnitTypeExponentContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def UNSIGNED_INTEGER(self): @@ -724,8 +729,8 @@ def MINUS(self): def getRuleIndex(self): return PyNestMLParser.RULE_unitTypeExponent - def accept(self, visitor): - if hasattr(visitor, "visitUnitTypeExponent"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitUnitTypeExponent" ): return visitor.visitUnitTypeExponent(self) else: return visitor.visitChildren(self) @@ -740,11 +745,11 @@ def unitTypeExponent(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 112 + self.state = 128 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.PLUS or _la==PyNestMLParser.MINUS: - self.state = 111 + self.state = 127 _la = self._input.LA(1) if not(_la==PyNestMLParser.PLUS or _la==PyNestMLParser.MINUS): self._errHandler.recoverInline(self) @@ -753,7 +758,7 @@ def unitTypeExponent(self): self.consume() - self.state = 114 + self.state = 130 self.match(PyNestMLParser.UNSIGNED_INTEGER) except RecognitionException as re: localctx.exception = re @@ -763,10 +768,12 @@ def unitTypeExponent(self): self.exitRule() return localctx + class ExpressionContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ExpressionContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.left = None # ExpressionContext self.condition = None # ExpressionContext @@ -787,7 +794,7 @@ def __init__(self, parser, parent=None, invokingState=-1): def LEFT_PAREN(self): return self.getToken(PyNestMLParser.LEFT_PAREN, 0) - def expression(self, i=None): + def expression(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.ExpressionContext) else: @@ -844,79 +851,86 @@ def QUESTION(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) + def NEWLINE(self, i:int=None): + if i is None: + return self.getTokens(PyNestMLParser.NEWLINE) + else: + return self.getToken(PyNestMLParser.NEWLINE, i) + def getRuleIndex(self): return PyNestMLParser.RULE_expression - def accept(self, visitor): - if hasattr(visitor, "visitExpression"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitExpression" ): return visitor.visitExpression(self) else: return visitor.visitChildren(self) - def expression(self, _p=0): + def expression(self, _p:int=0): _parentctx = self._ctx _parentState = self.state localctx = PyNestMLParser.ExpressionContext(self, self._ctx, _parentState) _prevctx = localctx _startState = 6 self.enterRecursionRule(localctx, 6, self.RULE_expression, _p) + self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 127 + self.state = 143 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.LEFT_PAREN]: - self.state = 117 + self.state = 133 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) - self.state = 118 + self.state = 134 localctx.term = self.expression(0) - self.state = 119 + self.state = 135 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [PyNestMLParser.PLUS, PyNestMLParser.TILDE, PyNestMLParser.MINUS]: - self.state = 121 + self.state = 137 self.unaryOperator() - self.state = 122 + self.state = 138 localctx.term = self.expression(9) pass elif token in [PyNestMLParser.NOT_KEYWORD]: - self.state = 124 + self.state = 140 localctx.logicalNot = self.match(PyNestMLParser.NOT_KEYWORD) - self.state = 125 + self.state = 141 localctx.term = self.expression(4) pass elif token in [PyNestMLParser.INF_KEYWORD, PyNestMLParser.BOOLEAN_LITERAL, PyNestMLParser.STRING_LITERAL, PyNestMLParser.NAME, PyNestMLParser.UNSIGNED_INTEGER, PyNestMLParser.FLOAT]: - self.state = 126 + self.state = 142 self.simpleExpression() pass else: raise NoViableAltException(self) self._ctx.stop = self._input.LT(-1) - self.state = 165 + self.state = 205 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,10,self._ctx) + _alt = self._interp.adaptivePredict(self._input,14,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 163 + self.state = 203 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,9,self._ctx) + la_ = self._interp.adaptivePredict(self._input,13,self._ctx) if la_ == 1: localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 129 + self.state = 145 if not self.precpred(self._ctx, 10): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 10)") - self.state = 130 + self.state = 146 localctx.powOp = self.match(PyNestMLParser.STAR_STAR) - self.state = 131 + self.state = 147 localctx.right = self.expression(10) pass @@ -924,29 +938,29 @@ def expression(self, _p=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 132 + self.state = 148 if not self.precpred(self._ctx, 8): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 8)") - self.state = 136 + self.state = 152 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.STAR]: - self.state = 133 + self.state = 149 localctx.timesOp = self.match(PyNestMLParser.STAR) pass elif token in [PyNestMLParser.FORWARD_SLASH]: - self.state = 134 + self.state = 150 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass elif token in [PyNestMLParser.PERCENT]: - self.state = 135 + self.state = 151 localctx.moduloOp = self.match(PyNestMLParser.PERCENT) pass else: raise NoViableAltException(self) - self.state = 138 + self.state = 154 localctx.right = self.expression(9) pass @@ -954,25 +968,25 @@ def expression(self, _p=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 139 + self.state = 155 if not self.precpred(self._ctx, 7): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 7)") - self.state = 142 + self.state = 158 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.PLUS]: - self.state = 140 + self.state = 156 localctx.plusOp = self.match(PyNestMLParser.PLUS) pass elif token in [PyNestMLParser.MINUS]: - self.state = 141 + self.state = 157 localctx.minusOp = self.match(PyNestMLParser.MINUS) pass else: raise NoViableAltException(self) - self.state = 144 + self.state = 160 localctx.right = self.expression(8) pass @@ -980,13 +994,13 @@ def expression(self, _p=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 145 + self.state = 161 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 146 + self.state = 162 self.bitOperator() - self.state = 147 + self.state = 163 localctx.right = self.expression(7) pass @@ -994,13 +1008,13 @@ def expression(self, _p=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 149 + self.state = 165 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 150 + self.state = 166 self.comparisonOperator() - self.state = 151 + self.state = 167 localctx.right = self.expression(6) pass @@ -1008,13 +1022,13 @@ def expression(self, _p=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 153 + self.state = 169 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 154 + self.state = 170 self.logicalOperator() - self.state = 155 + self.state = 171 localctx.right = self.expression(4) pass @@ -1022,24 +1036,64 @@ def expression(self, _p=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.condition = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 157 + self.state = 173 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 158 + self.state = 177 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==PyNestMLParser.NEWLINE: + self.state = 174 + self.match(PyNestMLParser.NEWLINE) + self.state = 179 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 180 self.match(PyNestMLParser.QUESTION) - self.state = 159 + self.state = 184 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==PyNestMLParser.NEWLINE: + self.state = 181 + self.match(PyNestMLParser.NEWLINE) + self.state = 186 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 187 localctx.ifTrue = self.expression(0) - self.state = 160 + self.state = 191 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==PyNestMLParser.NEWLINE: + self.state = 188 + self.match(PyNestMLParser.NEWLINE) + self.state = 193 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 194 self.match(PyNestMLParser.COLON) - self.state = 161 + self.state = 198 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==PyNestMLParser.NEWLINE: + self.state = 195 + self.match(PyNestMLParser.NEWLINE) + self.state = 200 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 201 localctx.ifNot = self.expression(3) pass - self.state = 167 + self.state = 207 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,10,self._ctx) + _alt = self._interp.adaptivePredict(self._input,14,self._ctx) except RecognitionException as re: localctx.exception = re @@ -1049,10 +1103,12 @@ def expression(self, _p=0): self.unrollRecursionContexts(_parentctx) return localctx + class SimpleExpressionContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.SimpleExpressionContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.string = None # Token self.isInf = None # Token @@ -1083,8 +1139,8 @@ def INF_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_simpleExpression - def accept(self, visitor): - if hasattr(visitor, "visitSimpleExpression"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitSimpleExpression" ): return visitor.visitSimpleExpression(self) else: return visitor.visitChildren(self) @@ -1098,35 +1154,35 @@ def simpleExpression(self): self.enterRule(localctx, 8, self.RULE_simpleExpression) self._la = 0 # Token type try: - self.state = 177 + self.state = 217 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,12,self._ctx) + la_ = self._interp.adaptivePredict(self._input,16,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 168 + self.state = 208 self.functionCall() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 169 + self.state = 209 self.match(PyNestMLParser.BOOLEAN_LITERAL) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 170 + self.state = 210 _la = self._input.LA(1) if not(_la==PyNestMLParser.UNSIGNED_INTEGER or _la==PyNestMLParser.FLOAT): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 172 + self.state = 212 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,11,self._ctx) + la_ = self._interp.adaptivePredict(self._input,15,self._ctx) if la_ == 1: - self.state = 171 + self.state = 211 self.variable() @@ -1134,19 +1190,19 @@ def simpleExpression(self): elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 174 + self.state = 214 localctx.string = self.match(PyNestMLParser.STRING_LITERAL) pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 175 + self.state = 215 localctx.isInf = self.match(PyNestMLParser.INF_KEYWORD) pass elif la_ == 6: self.enterOuterAlt(localctx, 6) - self.state = 176 + self.state = 216 self.variable() pass @@ -1159,10 +1215,12 @@ def simpleExpression(self): self.exitRule() return localctx + class UnaryOperatorContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.UnaryOperatorContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.unaryPlus = None # Token self.unaryMinus = None # Token @@ -1180,8 +1238,8 @@ def TILDE(self): def getRuleIndex(self): return PyNestMLParser.RULE_unaryOperator - def accept(self, visitor): - if hasattr(visitor, "visitUnaryOperator"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitUnaryOperator" ): return visitor.visitUnaryOperator(self) else: return visitor.visitChildren(self) @@ -1195,19 +1253,19 @@ def unaryOperator(self): self.enterRule(localctx, 10, self.RULE_unaryOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 182 + self.state = 222 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.PLUS]: - self.state = 179 + self.state = 219 localctx.unaryPlus = self.match(PyNestMLParser.PLUS) pass elif token in [PyNestMLParser.MINUS]: - self.state = 180 + self.state = 220 localctx.unaryMinus = self.match(PyNestMLParser.MINUS) pass elif token in [PyNestMLParser.TILDE]: - self.state = 181 + self.state = 221 localctx.unaryTilde = self.match(PyNestMLParser.TILDE) pass else: @@ -1221,10 +1279,12 @@ def unaryOperator(self): self.exitRule() return localctx + class BitOperatorContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.BitOperatorContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.bitAnd = None # Token self.bitXor = None # Token @@ -1250,8 +1310,8 @@ def RIGHT_RIGHT_ANGLE(self): def getRuleIndex(self): return PyNestMLParser.RULE_bitOperator - def accept(self, visitor): - if hasattr(visitor, "visitBitOperator"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitBitOperator" ): return visitor.visitBitOperator(self) else: return visitor.visitChildren(self) @@ -1265,27 +1325,27 @@ def bitOperator(self): self.enterRule(localctx, 12, self.RULE_bitOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 189 + self.state = 229 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.AMPERSAND]: - self.state = 184 + self.state = 224 localctx.bitAnd = self.match(PyNestMLParser.AMPERSAND) pass elif token in [PyNestMLParser.CARET]: - self.state = 185 + self.state = 225 localctx.bitXor = self.match(PyNestMLParser.CARET) pass elif token in [PyNestMLParser.PIPE]: - self.state = 186 + self.state = 226 localctx.bitOr = self.match(PyNestMLParser.PIPE) pass elif token in [PyNestMLParser.LEFT_LEFT_ANGLE]: - self.state = 187 + self.state = 227 localctx.bitShiftLeft = self.match(PyNestMLParser.LEFT_LEFT_ANGLE) pass elif token in [PyNestMLParser.RIGHT_RIGHT_ANGLE]: - self.state = 188 + self.state = 228 localctx.bitShiftRight = self.match(PyNestMLParser.RIGHT_RIGHT_ANGLE) pass else: @@ -1299,10 +1359,12 @@ def bitOperator(self): self.exitRule() return localctx + class ComparisonOperatorContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ComparisonOperatorContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.lt = None # Token self.le = None # Token @@ -1336,8 +1398,8 @@ def RIGHT_ANGLE(self): def getRuleIndex(self): return PyNestMLParser.RULE_comparisonOperator - def accept(self, visitor): - if hasattr(visitor, "visitComparisonOperator"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitComparisonOperator" ): return visitor.visitComparisonOperator(self) else: return visitor.visitChildren(self) @@ -1351,35 +1413,35 @@ def comparisonOperator(self): self.enterRule(localctx, 14, self.RULE_comparisonOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 198 + self.state = 238 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.LEFT_ANGLE]: - self.state = 191 + self.state = 231 localctx.lt = self.match(PyNestMLParser.LEFT_ANGLE) pass elif token in [PyNestMLParser.LEFT_ANGLE_EQUALS]: - self.state = 192 + self.state = 232 localctx.le = self.match(PyNestMLParser.LEFT_ANGLE_EQUALS) pass elif token in [PyNestMLParser.EQUALS_EQUALS]: - self.state = 193 + self.state = 233 localctx.eq = self.match(PyNestMLParser.EQUALS_EQUALS) pass elif token in [PyNestMLParser.EXCLAMATION_EQUALS]: - self.state = 194 + self.state = 234 localctx.ne = self.match(PyNestMLParser.EXCLAMATION_EQUALS) pass elif token in [PyNestMLParser.LEFT_ANGLE_RIGHT_ANGLE]: - self.state = 195 + self.state = 235 localctx.ne2 = self.match(PyNestMLParser.LEFT_ANGLE_RIGHT_ANGLE) pass elif token in [PyNestMLParser.RIGHT_ANGLE_EQUALS]: - self.state = 196 + self.state = 236 localctx.ge = self.match(PyNestMLParser.RIGHT_ANGLE_EQUALS) pass elif token in [PyNestMLParser.RIGHT_ANGLE]: - self.state = 197 + self.state = 237 localctx.gt = self.match(PyNestMLParser.RIGHT_ANGLE) pass else: @@ -1393,10 +1455,12 @@ def comparisonOperator(self): self.exitRule() return localctx + class LogicalOperatorContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.LogicalOperatorContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.logicalAnd = None # Token self.logicalOr = None # Token @@ -1410,8 +1474,8 @@ def OR_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_logicalOperator - def accept(self, visitor): - if hasattr(visitor, "visitLogicalOperator"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitLogicalOperator" ): return visitor.visitLogicalOperator(self) else: return visitor.visitChildren(self) @@ -1425,15 +1489,15 @@ def logicalOperator(self): self.enterRule(localctx, 16, self.RULE_logicalOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 202 + self.state = 242 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.AND_KEYWORD]: - self.state = 200 + self.state = 240 localctx.logicalAnd = self.match(PyNestMLParser.AND_KEYWORD) pass elif token in [PyNestMLParser.OR_KEYWORD]: - self.state = 201 + self.state = 241 localctx.logicalOr = self.match(PyNestMLParser.OR_KEYWORD) pass else: @@ -1447,27 +1511,96 @@ def logicalOperator(self): self.exitRule() return localctx + + class IndexParameterContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.sizeStr = None # Token + self.sizeInt = None # Token + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def UNSIGNED_INTEGER(self): + return self.getToken(PyNestMLParser.UNSIGNED_INTEGER, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_indexParameter + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIndexParameter" ): + return visitor.visitIndexParameter(self) + else: + return visitor.visitChildren(self) + + + + + def indexParameter(self): + + localctx = PyNestMLParser.IndexParameterContext(self, self._ctx, self.state) + self.enterRule(localctx, 18, self.RULE_indexParameter) + try: + self.enterOuterAlt(localctx, 1) + self.state = 246 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [PyNestMLParser.NAME]: + self.state = 244 + localctx.sizeStr = self.match(PyNestMLParser.NAME) + pass + elif token in [PyNestMLParser.UNSIGNED_INTEGER]: + self.state = 245 + localctx.sizeInt = self.match(PyNestMLParser.UNSIGNED_INTEGER) + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class VariableContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.VariableContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.name = None # Token + self.vectorParameter = None # IndexParameterContext def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) - def DIFFERENTIAL_ORDER(self, i=None): + def LEFT_SQUARE_BRACKET(self): + return self.getToken(PyNestMLParser.LEFT_SQUARE_BRACKET, 0) + + def RIGHT_SQUARE_BRACKET(self): + return self.getToken(PyNestMLParser.RIGHT_SQUARE_BRACKET, 0) + + def DIFFERENTIAL_ORDER(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.DIFFERENTIAL_ORDER) else: return self.getToken(PyNestMLParser.DIFFERENTIAL_ORDER, i) + def indexParameter(self): + return self.getTypedRuleContext(PyNestMLParser.IndexParameterContext,0) + + def getRuleIndex(self): return PyNestMLParser.RULE_variable - def accept(self, visitor): - if hasattr(visitor, "visitVariable"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVariable" ): return visitor.visitVariable(self) else: return visitor.visitChildren(self) @@ -1478,21 +1611,33 @@ def accept(self, visitor): def variable(self): localctx = PyNestMLParser.VariableContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_variable) + self.enterRule(localctx, 20, self.RULE_variable) try: self.enterOuterAlt(localctx, 1) - self.state = 204 + self.state = 248 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 208 + self.state = 253 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,22,self._ctx) + if la_ == 1: + self.state = 249 + self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) + self.state = 250 + localctx.vectorParameter = self.indexParameter() + self.state = 251 + self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) + + + self.state = 258 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,17,self._ctx) + _alt = self._interp.adaptivePredict(self._input,23,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 205 + self.state = 255 self.match(PyNestMLParser.DIFFERENTIAL_ORDER) - self.state = 210 + self.state = 260 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,17,self._ctx) + _alt = self._interp.adaptivePredict(self._input,23,self._ctx) except RecognitionException as re: localctx.exception = re @@ -1502,10 +1647,12 @@ def variable(self): self.exitRule() return localctx + class FunctionCallContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.FunctionCallContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.calleeName = None # Token @@ -1518,14 +1665,14 @@ def RIGHT_PAREN(self): def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) - def expression(self, i=None): + def expression(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.ExpressionContext) else: return self.getTypedRuleContext(PyNestMLParser.ExpressionContext,i) - def COMMA(self, i=None): + def COMMA(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.COMMA) else: @@ -1534,8 +1681,8 @@ def COMMA(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_functionCall - def accept(self, visitor): - if hasattr(visitor, "visitFunctionCall"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFunctionCall" ): return visitor.visitFunctionCall(self) else: return visitor.visitChildren(self) @@ -1546,35 +1693,35 @@ def accept(self, visitor): def functionCall(self): localctx = PyNestMLParser.FunctionCallContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_functionCall) + self.enterRule(localctx, 22, self.RULE_functionCall) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 211 + self.state = 261 localctx.calleeName = self.match(PyNestMLParser.NAME) - self.state = 212 + self.state = 262 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 221 + self.state = 271 self._errHandler.sync(self) _la = self._input.LA(1) - if ((((_la - 22)) & ~0x3f) == 0 and ((1 << (_la - 22)) & ((1 << (PyNestMLParser.INF_KEYWORD - 22)) | (1 << (PyNestMLParser.NOT_KEYWORD - 22)) | (1 << (PyNestMLParser.LEFT_PAREN - 22)) | (1 << (PyNestMLParser.PLUS - 22)) | (1 << (PyNestMLParser.TILDE - 22)) | (1 << (PyNestMLParser.MINUS - 22)) | (1 << (PyNestMLParser.BOOLEAN_LITERAL - 22)) | (1 << (PyNestMLParser.STRING_LITERAL - 22)) | (1 << (PyNestMLParser.NAME - 22)) | (1 << (PyNestMLParser.UNSIGNED_INTEGER - 22)) | (1 << (PyNestMLParser.FLOAT - 22)))) != 0): - self.state = 213 + if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.INF_KEYWORD) | (1 << PyNestMLParser.NOT_KEYWORD) | (1 << PyNestMLParser.LEFT_PAREN) | (1 << PyNestMLParser.PLUS) | (1 << PyNestMLParser.TILDE))) != 0) or ((((_la - 73)) & ~0x3f) == 0 and ((1 << (_la - 73)) & ((1 << (PyNestMLParser.MINUS - 73)) | (1 << (PyNestMLParser.BOOLEAN_LITERAL - 73)) | (1 << (PyNestMLParser.STRING_LITERAL - 73)) | (1 << (PyNestMLParser.NAME - 73)) | (1 << (PyNestMLParser.UNSIGNED_INTEGER - 73)) | (1 << (PyNestMLParser.FLOAT - 73)))) != 0): + self.state = 263 self.expression(0) - self.state = 218 + self.state = 268 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.COMMA: - self.state = 214 + self.state = 264 self.match(PyNestMLParser.COMMA) - self.state = 215 + self.state = 265 self.expression(0) - self.state = 220 + self.state = 270 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 223 + self.state = 273 self.match(PyNestMLParser.RIGHT_PAREN) except RecognitionException as re: localctx.exception = re @@ -1584,10 +1731,12 @@ def functionCall(self): self.exitRule() return localctx + class InlineExpressionContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.InlineExpressionContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.recordable = None # Token self.variableName = None # Token @@ -1618,8 +1767,8 @@ def RECORDABLE_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_inlineExpression - def accept(self, visitor): - if hasattr(visitor, "visitInlineExpression"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitInlineExpression" ): return visitor.visitInlineExpression(self) else: return visitor.visitChildren(self) @@ -1630,33 +1779,33 @@ def accept(self, visitor): def inlineExpression(self): localctx = PyNestMLParser.InlineExpressionContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_inlineExpression) + self.enterRule(localctx, 24, self.RULE_inlineExpression) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 226 + self.state = 276 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.RECORDABLE_KEYWORD: - self.state = 225 + self.state = 275 localctx.recordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) - self.state = 228 + self.state = 278 self.match(PyNestMLParser.INLINE_KEYWORD) - self.state = 229 + self.state = 279 localctx.variableName = self.match(PyNestMLParser.NAME) - self.state = 230 + self.state = 280 self.dataType() - self.state = 231 + self.state = 281 self.match(PyNestMLParser.EQUALS) - self.state = 232 + self.state = 282 self.expression(0) - self.state = 234 + self.state = 284 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.SEMICOLON: - self.state = 233 + self.state = 283 self.match(PyNestMLParser.SEMICOLON) @@ -1668,10 +1817,12 @@ def inlineExpression(self): self.exitRule() return localctx + class OdeEquationContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.OdeEquationContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.lhs = None # VariableContext self.rhs = None # ExpressionContext @@ -1693,8 +1844,8 @@ def SEMICOLON(self): def getRuleIndex(self): return PyNestMLParser.RULE_odeEquation - def accept(self, visitor): - if hasattr(visitor, "visitOdeEquation"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitOdeEquation" ): return visitor.visitOdeEquation(self) else: return visitor.visitChildren(self) @@ -1705,21 +1856,21 @@ def accept(self, visitor): def odeEquation(self): localctx = PyNestMLParser.OdeEquationContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_odeEquation) + self.enterRule(localctx, 26, self.RULE_odeEquation) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 236 + self.state = 286 localctx.lhs = self.variable() - self.state = 237 + self.state = 287 self.match(PyNestMLParser.EQUALS) - self.state = 238 + self.state = 288 localctx.rhs = self.expression(0) - self.state = 240 + self.state = 290 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.SEMICOLON: - self.state = 239 + self.state = 289 self.match(PyNestMLParser.SEMICOLON) @@ -1731,36 +1882,38 @@ def odeEquation(self): self.exitRule() return localctx + class KernelContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.KernelContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def KERNEL_KEYWORD(self): return self.getToken(PyNestMLParser.KERNEL_KEYWORD, 0) - def variable(self, i=None): + def variable(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.VariableContext) else: return self.getTypedRuleContext(PyNestMLParser.VariableContext,i) - def EQUALS(self, i=None): + def EQUALS(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.EQUALS) else: return self.getToken(PyNestMLParser.EQUALS, i) - def expression(self, i=None): + def expression(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.ExpressionContext) else: return self.getTypedRuleContext(PyNestMLParser.ExpressionContext,i) - def COMMA(self, i=None): + def COMMA(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.COMMA) else: @@ -1769,11 +1922,17 @@ def COMMA(self, i=None): def SEMICOLON(self): return self.getToken(PyNestMLParser.SEMICOLON, 0) + def NEWLINE(self, i:int=None): + if i is None: + return self.getTokens(PyNestMLParser.NEWLINE) + else: + return self.getToken(PyNestMLParser.NEWLINE, i) + def getRuleIndex(self): return PyNestMLParser.RULE_kernel - def accept(self, visitor): - if hasattr(visitor, "visitKernel"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitKernel" ): return visitor.visitKernel(self) else: return visitor.visitChildren(self) @@ -1784,39 +1943,49 @@ def accept(self, visitor): def kernel(self): localctx = PyNestMLParser.KernelContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_kernel) + self.enterRule(localctx, 28, self.RULE_kernel) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 242 + self.state = 292 self.match(PyNestMLParser.KERNEL_KEYWORD) - self.state = 243 + self.state = 293 self.variable() - self.state = 244 + self.state = 294 self.match(PyNestMLParser.EQUALS) - self.state = 245 + self.state = 295 self.expression(0) - self.state = 253 + self.state = 309 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.COMMA: - self.state = 246 + self.state = 296 self.match(PyNestMLParser.COMMA) - self.state = 247 + self.state = 300 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==PyNestMLParser.NEWLINE: + self.state = 297 + self.match(PyNestMLParser.NEWLINE) + self.state = 302 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 303 self.variable() - self.state = 248 + self.state = 304 self.match(PyNestMLParser.EQUALS) - self.state = 249 + self.state = 305 self.expression(0) - self.state = 255 + self.state = 311 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 257 + self.state = 313 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.SEMICOLON: - self.state = 256 + self.state = 312 self.match(PyNestMLParser.SEMICOLON) @@ -1828,20 +1997,22 @@ def kernel(self): self.exitRule() return localctx + class BlockContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.BlockContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser - def stmt(self, i=None): + def stmt(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.StmtContext) else: return self.getTypedRuleContext(PyNestMLParser.StmtContext,i) - def NEWLINE(self, i=None): + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NEWLINE) else: @@ -1850,8 +2021,8 @@ def NEWLINE(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_block - def accept(self, visitor): - if hasattr(visitor, "visitBlock"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitBlock" ): return visitor.visitBlock(self) else: return visitor.visitChildren(self) @@ -1862,29 +2033,29 @@ def accept(self, visitor): def block(self): localctx = PyNestMLParser.BlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_block) + self.enterRule(localctx, 30, self.RULE_block) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 263 + self.state = 319 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.FUNCTION_KEYWORD) | (1 << PyNestMLParser.RETURN_KEYWORD) | (1 << PyNestMLParser.IF_KEYWORD) | (1 << PyNestMLParser.FOR_KEYWORD) | (1 << PyNestMLParser.WHILE_KEYWORD) | (1 << PyNestMLParser.RECORDABLE_KEYWORD))) != 0) or _la==PyNestMLParser.NAME: - self.state = 261 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.INLINE_KEYWORD) | (1 << PyNestMLParser.RETURN_KEYWORD) | (1 << PyNestMLParser.IF_KEYWORD) | (1 << PyNestMLParser.FOR_KEYWORD) | (1 << PyNestMLParser.WHILE_KEYWORD) | (1 << PyNestMLParser.RECORDABLE_KEYWORD))) != 0) or _la==PyNestMLParser.NAME: + self.state = 317 self._errHandler.sync(self) token = self._input.LA(1) - if token in [PyNestMLParser.FUNCTION_KEYWORD, PyNestMLParser.RETURN_KEYWORD, PyNestMLParser.IF_KEYWORD, PyNestMLParser.FOR_KEYWORD, PyNestMLParser.WHILE_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD, PyNestMLParser.NAME]: - self.state = 259 + if token in [PyNestMLParser.INLINE_KEYWORD, PyNestMLParser.RETURN_KEYWORD, PyNestMLParser.IF_KEYWORD, PyNestMLParser.FOR_KEYWORD, PyNestMLParser.WHILE_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD, PyNestMLParser.NAME]: + self.state = 315 self.stmt() pass elif token in [PyNestMLParser.NEWLINE]: - self.state = 260 + self.state = 316 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 265 + self.state = 321 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1896,10 +2067,12 @@ def block(self): self.exitRule() return localctx + class StmtContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.StmtContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def smallStmt(self): @@ -1913,8 +2086,8 @@ def compoundStmt(self): def getRuleIndex(self): return PyNestMLParser.RULE_stmt - def accept(self, visitor): - if hasattr(visitor, "visitStmt"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitStmt" ): return visitor.visitStmt(self) else: return visitor.visitChildren(self) @@ -1925,19 +2098,19 @@ def accept(self, visitor): def stmt(self): localctx = PyNestMLParser.StmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_stmt) + self.enterRule(localctx, 32, self.RULE_stmt) try: - self.state = 268 + self.state = 324 self._errHandler.sync(self) token = self._input.LA(1) - if token in [PyNestMLParser.FUNCTION_KEYWORD, PyNestMLParser.RETURN_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD, PyNestMLParser.NAME]: + if token in [PyNestMLParser.INLINE_KEYWORD, PyNestMLParser.RETURN_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD, PyNestMLParser.NAME]: self.enterOuterAlt(localctx, 1) - self.state = 266 + self.state = 322 self.smallStmt() pass elif token in [PyNestMLParser.IF_KEYWORD, PyNestMLParser.FOR_KEYWORD, PyNestMLParser.WHILE_KEYWORD]: self.enterOuterAlt(localctx, 2) - self.state = 267 + self.state = 323 self.compoundStmt() pass else: @@ -1951,10 +2124,12 @@ def stmt(self): self.exitRule() return localctx + class CompoundStmtContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.CompoundStmtContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def ifStmt(self): @@ -1972,8 +2147,8 @@ def whileStmt(self): def getRuleIndex(self): return PyNestMLParser.RULE_compoundStmt - def accept(self, visitor): - if hasattr(visitor, "visitCompoundStmt"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitCompoundStmt" ): return visitor.visitCompoundStmt(self) else: return visitor.visitChildren(self) @@ -1984,24 +2159,24 @@ def accept(self, visitor): def compoundStmt(self): localctx = PyNestMLParser.CompoundStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_compoundStmt) + self.enterRule(localctx, 34, self.RULE_compoundStmt) try: - self.state = 273 + self.state = 329 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.IF_KEYWORD]: self.enterOuterAlt(localctx, 1) - self.state = 270 + self.state = 326 self.ifStmt() pass elif token in [PyNestMLParser.FOR_KEYWORD]: self.enterOuterAlt(localctx, 2) - self.state = 271 + self.state = 327 self.forStmt() pass elif token in [PyNestMLParser.WHILE_KEYWORD]: self.enterOuterAlt(localctx, 3) - self.state = 272 + self.state = 328 self.whileStmt() pass else: @@ -2015,10 +2190,12 @@ def compoundStmt(self): self.exitRule() return localctx + class SmallStmtContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.SmallStmtContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def assignment(self): @@ -2040,8 +2217,8 @@ def returnStmt(self): def getRuleIndex(self): return PyNestMLParser.RULE_smallStmt - def accept(self, visitor): - if hasattr(visitor, "visitSmallStmt"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitSmallStmt" ): return visitor.visitSmallStmt(self) else: return visitor.visitChildren(self) @@ -2052,32 +2229,32 @@ def accept(self, visitor): def smallStmt(self): localctx = PyNestMLParser.SmallStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_smallStmt) + self.enterRule(localctx, 36, self.RULE_smallStmt) try: - self.state = 279 + self.state = 335 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,29,self._ctx) + la_ = self._interp.adaptivePredict(self._input,36,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 275 + self.state = 331 self.assignment() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 276 + self.state = 332 self.functionCall() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 277 + self.state = 333 self.declaration() pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 278 + self.state = 334 self.returnStmt() pass @@ -2090,10 +2267,12 @@ def smallStmt(self): self.exitRule() return localctx + class AssignmentContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.AssignmentContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.lhs_variable = None # VariableContext self.directAssignment = None # Token @@ -2128,8 +2307,8 @@ def FORWARD_SLASH_EQUALS(self): def getRuleIndex(self): return PyNestMLParser.RULE_assignment - def accept(self, visitor): - if hasattr(visitor, "visitAssignment"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAssignment" ): return visitor.visitAssignment(self) else: return visitor.visitChildren(self) @@ -2140,38 +2319,38 @@ def accept(self, visitor): def assignment(self): localctx = PyNestMLParser.AssignmentContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_assignment) + self.enterRule(localctx, 38, self.RULE_assignment) try: self.enterOuterAlt(localctx, 1) - self.state = 281 + self.state = 337 localctx.lhs_variable = self.variable() - self.state = 287 + self.state = 343 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.EQUALS]: - self.state = 282 + self.state = 338 localctx.directAssignment = self.match(PyNestMLParser.EQUALS) pass elif token in [PyNestMLParser.PLUS_EQUALS]: - self.state = 283 + self.state = 339 localctx.compoundSum = self.match(PyNestMLParser.PLUS_EQUALS) pass elif token in [PyNestMLParser.MINUS_EQUALS]: - self.state = 284 + self.state = 340 localctx.compoundMinus = self.match(PyNestMLParser.MINUS_EQUALS) pass elif token in [PyNestMLParser.STAR_EQUALS]: - self.state = 285 + self.state = 341 localctx.compoundProduct = self.match(PyNestMLParser.STAR_EQUALS) pass elif token in [PyNestMLParser.FORWARD_SLASH_EQUALS]: - self.state = 286 + self.state = 342 localctx.compoundQuotient = self.match(PyNestMLParser.FORWARD_SLASH_EQUALS) pass else: raise NoViableAltException(self) - self.state = 289 + self.state = 345 self.expression(0) except RecognitionException as re: localctx.exception = re @@ -2181,18 +2360,20 @@ def assignment(self): self.exitRule() return localctx + class DeclarationContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.DeclarationContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.isRecordable = None # Token - self.isFunction = None # Token - self.sizeParameter = None # Token + self.isInlineExpression = None # Token self.rhs = None # ExpressionContext self.invariant = None # ExpressionContext + self.decorator = None # AnyDecoratorContext - def variable(self, i=None): + def variable(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.VariableContext) else: @@ -2203,18 +2384,12 @@ def dataType(self): return self.getTypedRuleContext(PyNestMLParser.DataTypeContext,0) - def COMMA(self, i=None): + def COMMA(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.COMMA) else: return self.getToken(PyNestMLParser.COMMA, i) - def LEFT_SQUARE_BRACKET(self): - return self.getToken(PyNestMLParser.LEFT_SQUARE_BRACKET, 0) - - def RIGHT_SQUARE_BRACKET(self): - return self.getToken(PyNestMLParser.RIGHT_SQUARE_BRACKET, 0) - def EQUALS(self): return self.getToken(PyNestMLParser.EQUALS, 0) @@ -2227,24 +2402,28 @@ def RIGHT_RIGHT_SQUARE(self): def RECORDABLE_KEYWORD(self): return self.getToken(PyNestMLParser.RECORDABLE_KEYWORD, 0) - def FUNCTION_KEYWORD(self): - return self.getToken(PyNestMLParser.FUNCTION_KEYWORD, 0) - - def NAME(self): - return self.getToken(PyNestMLParser.NAME, 0) + def INLINE_KEYWORD(self): + return self.getToken(PyNestMLParser.INLINE_KEYWORD, 0) - def expression(self, i=None): + def expression(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.ExpressionContext) else: return self.getTypedRuleContext(PyNestMLParser.ExpressionContext,i) + def anyDecorator(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.AnyDecoratorContext) + else: + return self.getTypedRuleContext(PyNestMLParser.AnyDecoratorContext,i) + + def getRuleIndex(self): return PyNestMLParser.RULE_declaration - def accept(self, visitor): - if hasattr(visitor, "visitDeclaration"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitDeclaration" ): return visitor.visitDeclaration(self) else: return visitor.visitChildren(self) @@ -2255,76 +2434,74 @@ def accept(self, visitor): def declaration(self): localctx = PyNestMLParser.DeclarationContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_declaration) + self.enterRule(localctx, 40, self.RULE_declaration) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 292 + self.state = 348 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.RECORDABLE_KEYWORD: - self.state = 291 + self.state = 347 localctx.isRecordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) - self.state = 295 + self.state = 351 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==PyNestMLParser.FUNCTION_KEYWORD: - self.state = 294 - localctx.isFunction = self.match(PyNestMLParser.FUNCTION_KEYWORD) + if _la==PyNestMLParser.INLINE_KEYWORD: + self.state = 350 + localctx.isInlineExpression = self.match(PyNestMLParser.INLINE_KEYWORD) - self.state = 297 + self.state = 353 self.variable() - self.state = 302 + self.state = 358 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.COMMA: - self.state = 298 + self.state = 354 self.match(PyNestMLParser.COMMA) - self.state = 299 + self.state = 355 self.variable() - self.state = 304 + self.state = 360 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 305 + self.state = 361 self.dataType() - self.state = 309 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==PyNestMLParser.LEFT_SQUARE_BRACKET: - self.state = 306 - self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 307 - localctx.sizeParameter = self.match(PyNestMLParser.NAME) - self.state = 308 - self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - - - self.state = 313 + self.state = 364 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.EQUALS: - self.state = 311 + self.state = 362 self.match(PyNestMLParser.EQUALS) - self.state = 312 + self.state = 363 localctx.rhs = self.expression(0) - self.state = 319 + self.state = 370 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.LEFT_LEFT_SQUARE: - self.state = 315 + self.state = 366 self.match(PyNestMLParser.LEFT_LEFT_SQUARE) - self.state = 316 + self.state = 367 localctx.invariant = self.expression(0) - self.state = 317 + self.state = 368 self.match(PyNestMLParser.RIGHT_RIGHT_SQUARE) + self.state = 375 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.DECORATOR_HOMOGENEOUS) | (1 << PyNestMLParser.DECORATOR_HETEROGENEOUS) | (1 << PyNestMLParser.AT))) != 0): + self.state = 372 + localctx.decorator = self.anyDecorator() + self.state = 377 + self._errHandler.sync(self) + _la = self._input.LA(1) + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2333,46 +2510,77 @@ def declaration(self): self.exitRule() return localctx - class ReturnStmtContext(ParserRuleContext): - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ReturnStmtContext, self).__init__(parent, invokingState) + class AnyDecoratorContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser - def RETURN_KEYWORD(self): - return self.getToken(PyNestMLParser.RETURN_KEYWORD, 0) + def DECORATOR_HOMOGENEOUS(self): + return self.getToken(PyNestMLParser.DECORATOR_HOMOGENEOUS, 0) + + def DECORATOR_HETEROGENEOUS(self): + return self.getToken(PyNestMLParser.DECORATOR_HETEROGENEOUS, 0) + + def AT(self): + return self.getToken(PyNestMLParser.AT, 0) + + def namespaceDecoratorNamespace(self): + return self.getTypedRuleContext(PyNestMLParser.NamespaceDecoratorNamespaceContext,0) - def expression(self): - return self.getTypedRuleContext(PyNestMLParser.ExpressionContext,0) + + def DOUBLE_COLON(self): + return self.getToken(PyNestMLParser.DOUBLE_COLON, 0) + + def namespaceDecoratorName(self): + return self.getTypedRuleContext(PyNestMLParser.NamespaceDecoratorNameContext,0) def getRuleIndex(self): - return PyNestMLParser.RULE_returnStmt + return PyNestMLParser.RULE_anyDecorator - def accept(self, visitor): - if hasattr(visitor, "visitReturnStmt"): - return visitor.visitReturnStmt(self) + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAnyDecorator" ): + return visitor.visitAnyDecorator(self) else: return visitor.visitChildren(self) - def returnStmt(self): + def anyDecorator(self): - localctx = PyNestMLParser.ReturnStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_returnStmt) + localctx = PyNestMLParser.AnyDecoratorContext(self, self._ctx, self.state) + self.enterRule(localctx, 42, self.RULE_anyDecorator) try: - self.enterOuterAlt(localctx, 1) - self.state = 321 - self.match(PyNestMLParser.RETURN_KEYWORD) - self.state = 323 + self.state = 385 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,37,self._ctx) - if la_ == 1: - self.state = 322 - self.expression(0) - + token = self._input.LA(1) + if token in [PyNestMLParser.DECORATOR_HOMOGENEOUS]: + self.enterOuterAlt(localctx, 1) + self.state = 378 + self.match(PyNestMLParser.DECORATOR_HOMOGENEOUS) + pass + elif token in [PyNestMLParser.DECORATOR_HETEROGENEOUS]: + self.enterOuterAlt(localctx, 2) + self.state = 379 + self.match(PyNestMLParser.DECORATOR_HETEROGENEOUS) + pass + elif token in [PyNestMLParser.AT]: + self.enterOuterAlt(localctx, 3) + self.state = 380 + self.match(PyNestMLParser.AT) + self.state = 381 + self.namespaceDecoratorNamespace() + self.state = 382 + self.match(PyNestMLParser.DOUBLE_COLON) + self.state = 383 + self.namespaceDecoratorName() + pass + else: + raise NoViableAltException(self) except RecognitionException as re: localctx.exception = re @@ -2382,35 +2590,168 @@ def returnStmt(self): self.exitRule() return localctx - class IfStmtContext(ParserRuleContext): - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.IfStmtContext, self).__init__(parent, invokingState) - self.parser = parser + class NamespaceDecoratorNamespaceContext(ParserRuleContext): + __slots__ = 'parser' - def ifClause(self): - return self.getTypedRuleContext(PyNestMLParser.IfClauseContext,0) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.name = None # Token + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) - def END_KEYWORD(self): - return self.getToken(PyNestMLParser.END_KEYWORD, 0) + def getRuleIndex(self): + return PyNestMLParser.RULE_namespaceDecoratorNamespace - def elifClause(self, i=None): - if i is None: - return self.getTypedRuleContexts(PyNestMLParser.ElifClauseContext) + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNamespaceDecoratorNamespace" ): + return visitor.visitNamespaceDecoratorNamespace(self) else: - return self.getTypedRuleContext(PyNestMLParser.ElifClauseContext,i) + return visitor.visitChildren(self) - def elseClause(self): - return self.getTypedRuleContext(PyNestMLParser.ElseClauseContext,0) + + + def namespaceDecoratorNamespace(self): + + localctx = PyNestMLParser.NamespaceDecoratorNamespaceContext(self, self._ctx, self.state) + self.enterRule(localctx, 44, self.RULE_namespaceDecoratorNamespace) + try: + self.enterOuterAlt(localctx, 1) + self.state = 387 + localctx.name = self.match(PyNestMLParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class NamespaceDecoratorNameContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.name = None # Token + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_namespaceDecoratorName + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNamespaceDecoratorName" ): + return visitor.visitNamespaceDecoratorName(self) + else: + return visitor.visitChildren(self) + + + + + def namespaceDecoratorName(self): + + localctx = PyNestMLParser.NamespaceDecoratorNameContext(self, self._ctx, self.state) + self.enterRule(localctx, 46, self.RULE_namespaceDecoratorName) + try: + self.enterOuterAlt(localctx, 1) + self.state = 389 + localctx.name = self.match(PyNestMLParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class ReturnStmtContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def RETURN_KEYWORD(self): + return self.getToken(PyNestMLParser.RETURN_KEYWORD, 0) + + def expression(self): + return self.getTypedRuleContext(PyNestMLParser.ExpressionContext,0) + + + def getRuleIndex(self): + return PyNestMLParser.RULE_returnStmt + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitReturnStmt" ): + return visitor.visitReturnStmt(self) + else: + return visitor.visitChildren(self) + + + + + def returnStmt(self): + + localctx = PyNestMLParser.ReturnStmtContext(self, self._ctx, self.state) + self.enterRule(localctx, 48, self.RULE_returnStmt) + try: + self.enterOuterAlt(localctx, 1) + self.state = 391 + self.match(PyNestMLParser.RETURN_KEYWORD) + self.state = 393 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,45,self._ctx) + if la_ == 1: + self.state = 392 + self.expression(0) + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class IfStmtContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def ifClause(self): + return self.getTypedRuleContext(PyNestMLParser.IfClauseContext,0) + + + def END_KEYWORD(self): + return self.getToken(PyNestMLParser.END_KEYWORD, 0) + + def elifClause(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.ElifClauseContext) + else: + return self.getTypedRuleContext(PyNestMLParser.ElifClauseContext,i) + + + def elseClause(self): + return self.getTypedRuleContext(PyNestMLParser.ElseClauseContext,0) def getRuleIndex(self): return PyNestMLParser.RULE_ifStmt - def accept(self, visitor): - if hasattr(visitor, "visitIfStmt"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIfStmt" ): return visitor.visitIfStmt(self) else: return visitor.visitChildren(self) @@ -2421,31 +2762,31 @@ def accept(self, visitor): def ifStmt(self): localctx = PyNestMLParser.IfStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_ifStmt) + self.enterRule(localctx, 50, self.RULE_ifStmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 325 + self.state = 395 self.ifClause() - self.state = 329 + self.state = 399 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.ELIF_KEYWORD: - self.state = 326 + self.state = 396 self.elifClause() - self.state = 331 + self.state = 401 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 333 + self.state = 403 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.ELSE_KEYWORD: - self.state = 332 + self.state = 402 self.elseClause() - self.state = 335 + self.state = 405 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -2455,10 +2796,12 @@ def ifStmt(self): self.exitRule() return localctx + class IfClauseContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.IfClauseContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def IF_KEYWORD(self): @@ -2478,8 +2821,8 @@ def block(self): def getRuleIndex(self): return PyNestMLParser.RULE_ifClause - def accept(self, visitor): - if hasattr(visitor, "visitIfClause"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIfClause" ): return visitor.visitIfClause(self) else: return visitor.visitChildren(self) @@ -2490,16 +2833,16 @@ def accept(self, visitor): def ifClause(self): localctx = PyNestMLParser.IfClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_ifClause) + self.enterRule(localctx, 52, self.RULE_ifClause) try: self.enterOuterAlt(localctx, 1) - self.state = 337 + self.state = 407 self.match(PyNestMLParser.IF_KEYWORD) - self.state = 338 + self.state = 408 self.expression(0) - self.state = 339 + self.state = 409 self.match(PyNestMLParser.COLON) - self.state = 340 + self.state = 410 self.block() except RecognitionException as re: localctx.exception = re @@ -2509,10 +2852,12 @@ def ifClause(self): self.exitRule() return localctx + class ElifClauseContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ElifClauseContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def ELIF_KEYWORD(self): @@ -2532,8 +2877,8 @@ def block(self): def getRuleIndex(self): return PyNestMLParser.RULE_elifClause - def accept(self, visitor): - if hasattr(visitor, "visitElifClause"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitElifClause" ): return visitor.visitElifClause(self) else: return visitor.visitChildren(self) @@ -2544,16 +2889,16 @@ def accept(self, visitor): def elifClause(self): localctx = PyNestMLParser.ElifClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_elifClause) + self.enterRule(localctx, 54, self.RULE_elifClause) try: self.enterOuterAlt(localctx, 1) - self.state = 342 + self.state = 412 self.match(PyNestMLParser.ELIF_KEYWORD) - self.state = 343 + self.state = 413 self.expression(0) - self.state = 344 + self.state = 414 self.match(PyNestMLParser.COLON) - self.state = 345 + self.state = 415 self.block() except RecognitionException as re: localctx.exception = re @@ -2563,10 +2908,12 @@ def elifClause(self): self.exitRule() return localctx + class ElseClauseContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ElseClauseContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def ELSE_KEYWORD(self): @@ -2582,8 +2929,8 @@ def block(self): def getRuleIndex(self): return PyNestMLParser.RULE_elseClause - def accept(self, visitor): - if hasattr(visitor, "visitElseClause"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitElseClause" ): return visitor.visitElseClause(self) else: return visitor.visitChildren(self) @@ -2594,14 +2941,14 @@ def accept(self, visitor): def elseClause(self): localctx = PyNestMLParser.ElseClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 48, self.RULE_elseClause) + self.enterRule(localctx, 56, self.RULE_elseClause) try: self.enterOuterAlt(localctx, 1) - self.state = 347 + self.state = 417 self.match(PyNestMLParser.ELSE_KEYWORD) - self.state = 348 + self.state = 418 self.match(PyNestMLParser.COLON) - self.state = 349 + self.state = 419 self.block() except RecognitionException as re: localctx.exception = re @@ -2611,10 +2958,12 @@ def elseClause(self): self.exitRule() return localctx + class ForStmtContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ForStmtContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.var = None # Token self.start_from = None # ExpressionContext @@ -2646,7 +2995,7 @@ def END_KEYWORD(self): def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) - def expression(self, i=None): + def expression(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.ExpressionContext) else: @@ -2665,8 +3014,8 @@ def MINUS(self): def getRuleIndex(self): return PyNestMLParser.RULE_forStmt - def accept(self, visitor): - if hasattr(visitor, "visitForStmt"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitForStmt" ): return visitor.visitForStmt(self) else: return visitor.visitChildren(self) @@ -2677,45 +3026,45 @@ def accept(self, visitor): def forStmt(self): localctx = PyNestMLParser.ForStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 50, self.RULE_forStmt) + self.enterRule(localctx, 58, self.RULE_forStmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 351 + self.state = 421 self.match(PyNestMLParser.FOR_KEYWORD) - self.state = 352 + self.state = 422 localctx.var = self.match(PyNestMLParser.NAME) - self.state = 353 + self.state = 423 self.match(PyNestMLParser.IN_KEYWORD) - self.state = 354 + self.state = 424 localctx.start_from = self.expression(0) - self.state = 355 + self.state = 425 self.match(PyNestMLParser.ELLIPSIS) - self.state = 356 + self.state = 426 localctx.end_at = self.expression(0) - self.state = 357 + self.state = 427 self.match(PyNestMLParser.STEP_KEYWORD) - self.state = 359 + self.state = 429 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.MINUS: - self.state = 358 + self.state = 428 localctx.negative = self.match(PyNestMLParser.MINUS) - self.state = 361 + self.state = 431 _la = self._input.LA(1) if not(_la==PyNestMLParser.UNSIGNED_INTEGER or _la==PyNestMLParser.FLOAT): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 362 + self.state = 432 self.match(PyNestMLParser.COLON) - self.state = 363 + self.state = 433 self.block() - self.state = 364 + self.state = 434 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -2725,10 +3074,12 @@ def forStmt(self): self.exitRule() return localctx + class WhileStmtContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.WhileStmtContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def WHILE_KEYWORD(self): @@ -2751,8 +3102,8 @@ def END_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_whileStmt - def accept(self, visitor): - if hasattr(visitor, "visitWhileStmt"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitWhileStmt" ): return visitor.visitWhileStmt(self) else: return visitor.visitChildren(self) @@ -2763,18 +3114,18 @@ def accept(self, visitor): def whileStmt(self): localctx = PyNestMLParser.WhileStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 52, self.RULE_whileStmt) + self.enterRule(localctx, 60, self.RULE_whileStmt) try: self.enterOuterAlt(localctx, 1) - self.state = 366 + self.state = 436 self.match(PyNestMLParser.WHILE_KEYWORD) - self.state = 367 + self.state = 437 self.expression(0) - self.state = 368 + self.state = 438 self.match(PyNestMLParser.COLON) - self.state = 369 + self.state = 439 self.block() - self.state = 370 + self.state = 440 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -2784,23 +3135,32 @@ def whileStmt(self): self.exitRule() return localctx + class NestMLCompilationUnitContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.NestMLCompilationUnitContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def EOF(self): return self.getToken(PyNestMLParser.EOF, 0) - def neuron(self, i=None): + def neuron(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.NeuronContext) else: return self.getTypedRuleContext(PyNestMLParser.NeuronContext,i) - def NEWLINE(self, i=None): + def synapse(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.SynapseContext) + else: + return self.getTypedRuleContext(PyNestMLParser.SynapseContext,i) + + + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NEWLINE) else: @@ -2809,8 +3169,8 @@ def NEWLINE(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_nestMLCompilationUnit - def accept(self, visitor): - if hasattr(visitor, "visitNestMLCompilationUnit"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNestMLCompilationUnit" ): return visitor.visitNestMLCompilationUnit(self) else: return visitor.visitChildren(self) @@ -2821,33 +3181,37 @@ def accept(self, visitor): def nestMLCompilationUnit(self): localctx = PyNestMLParser.NestMLCompilationUnitContext(self, self._ctx, self.state) - self.enterRule(localctx, 54, self.RULE_nestMLCompilationUnit) + self.enterRule(localctx, 62, self.RULE_nestMLCompilationUnit) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 376 + self.state = 447 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==PyNestMLParser.NEWLINE or _la==PyNestMLParser.NEURON_KEYWORD: - self.state = 374 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.NEURON_KEYWORD) | (1 << PyNestMLParser.SYNAPSE_KEYWORD))) != 0): + self.state = 445 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.NEURON_KEYWORD]: - self.state = 372 + self.state = 442 self.neuron() pass + elif token in [PyNestMLParser.SYNAPSE_KEYWORD]: + self.state = 443 + self.synapse() + pass elif token in [PyNestMLParser.NEWLINE]: - self.state = 373 + self.state = 444 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 378 + self.state = 449 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 379 + self.state = 450 self.match(PyNestMLParser.EOF) except RecognitionException as re: localctx.exception = re @@ -2857,10 +3221,12 @@ def nestMLCompilationUnit(self): self.exitRule() return localctx + class NeuronContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.NeuronContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def NEURON_KEYWORD(self): @@ -2869,15 +3235,15 @@ def NEURON_KEYWORD(self): def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) - def body(self): - return self.getTypedRuleContext(PyNestMLParser.BodyContext,0) + def neuronBody(self): + return self.getTypedRuleContext(PyNestMLParser.NeuronBodyContext,0) def getRuleIndex(self): return PyNestMLParser.RULE_neuron - def accept(self, visitor): - if hasattr(visitor, "visitNeuron"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNeuron" ): return visitor.visitNeuron(self) else: return visitor.visitChildren(self) @@ -2888,15 +3254,15 @@ def accept(self, visitor): def neuron(self): localctx = PyNestMLParser.NeuronContext(self, self._ctx, self.state) - self.enterRule(localctx, 56, self.RULE_neuron) + self.enterRule(localctx, 64, self.RULE_neuron) try: self.enterOuterAlt(localctx, 1) - self.state = 381 + self.state = 452 self.match(PyNestMLParser.NEURON_KEYWORD) - self.state = 382 + self.state = 453 self.match(PyNestMLParser.NAME) - self.state = 383 - self.body() + self.state = 454 + self.neuronBody() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2905,10 +3271,12 @@ def neuron(self): self.exitRule() return localctx - class BodyContext(ParserRuleContext): - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.BodyContext, self).__init__(parent, invokingState) + class NeuronBodyContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def COLON(self): @@ -2917,48 +3285,48 @@ def COLON(self): def END_KEYWORD(self): return self.getToken(PyNestMLParser.END_KEYWORD, 0) - def NEWLINE(self, i=None): + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NEWLINE) else: return self.getToken(PyNestMLParser.NEWLINE, i) - def blockWithVariables(self, i=None): + def blockWithVariables(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.BlockWithVariablesContext) else: return self.getTypedRuleContext(PyNestMLParser.BlockWithVariablesContext,i) - def equationsBlock(self, i=None): + def equationsBlock(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.EquationsBlockContext) else: return self.getTypedRuleContext(PyNestMLParser.EquationsBlockContext,i) - def inputBlock(self, i=None): + def inputBlock(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.InputBlockContext) else: return self.getTypedRuleContext(PyNestMLParser.InputBlockContext,i) - def outputBlock(self, i=None): + def outputBlock(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.OutputBlockContext) else: return self.getTypedRuleContext(PyNestMLParser.OutputBlockContext,i) - def updateBlock(self, i=None): + def updateBlock(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.UpdateBlockContext) else: return self.getTypedRuleContext(PyNestMLParser.UpdateBlockContext,i) - def function(self, i=None): + def function(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.FunctionContext) else: @@ -2966,69 +3334,69 @@ def function(self, i=None): def getRuleIndex(self): - return PyNestMLParser.RULE_body + return PyNestMLParser.RULE_neuronBody - def accept(self, visitor): - if hasattr(visitor, "visitBody"): - return visitor.visitBody(self) + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNeuronBody" ): + return visitor.visitNeuronBody(self) else: return visitor.visitChildren(self) - def body(self): + def neuronBody(self): - localctx = PyNestMLParser.BodyContext(self, self._ctx, self.state) - self.enterRule(localctx, 58, self.RULE_body) + localctx = PyNestMLParser.NeuronBodyContext(self, self._ctx, self.state) + self.enterRule(localctx, 66, self.RULE_neuronBody) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 385 + self.state = 456 self.match(PyNestMLParser.COLON) - self.state = 395 + self.state = 466 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.FUNCTION_KEYWORD) | (1 << PyNestMLParser.STATE_KEYWORD) | (1 << PyNestMLParser.PARAMETERS_KEYWORD) | (1 << PyNestMLParser.INTERNALS_KEYWORD) | (1 << PyNestMLParser.INITIAL_VALUES_KEYWORD) | (1 << PyNestMLParser.UPDATE_KEYWORD) | (1 << PyNestMLParser.EQUATIONS_KEYWORD) | (1 << PyNestMLParser.INPUT_KEYWORD) | (1 << PyNestMLParser.OUTPUT_KEYWORD))) != 0): - self.state = 393 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.FUNCTION_KEYWORD) | (1 << PyNestMLParser.STATE_KEYWORD) | (1 << PyNestMLParser.PARAMETERS_KEYWORD) | (1 << PyNestMLParser.INTERNALS_KEYWORD) | (1 << PyNestMLParser.UPDATE_KEYWORD) | (1 << PyNestMLParser.EQUATIONS_KEYWORD) | (1 << PyNestMLParser.INPUT_KEYWORD) | (1 << PyNestMLParser.OUTPUT_KEYWORD))) != 0): + self.state = 464 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.NEWLINE]: - self.state = 386 + self.state = 457 self.match(PyNestMLParser.NEWLINE) pass - elif token in [PyNestMLParser.STATE_KEYWORD, PyNestMLParser.PARAMETERS_KEYWORD, PyNestMLParser.INTERNALS_KEYWORD, PyNestMLParser.INITIAL_VALUES_KEYWORD]: - self.state = 387 + elif token in [PyNestMLParser.STATE_KEYWORD, PyNestMLParser.PARAMETERS_KEYWORD, PyNestMLParser.INTERNALS_KEYWORD]: + self.state = 458 self.blockWithVariables() pass elif token in [PyNestMLParser.EQUATIONS_KEYWORD]: - self.state = 388 + self.state = 459 self.equationsBlock() pass elif token in [PyNestMLParser.INPUT_KEYWORD]: - self.state = 389 + self.state = 460 self.inputBlock() pass elif token in [PyNestMLParser.OUTPUT_KEYWORD]: - self.state = 390 + self.state = 461 self.outputBlock() pass elif token in [PyNestMLParser.UPDATE_KEYWORD]: - self.state = 391 + self.state = 462 self.updateBlock() pass elif token in [PyNestMLParser.FUNCTION_KEYWORD]: - self.state = 392 + self.state = 463 self.function() pass else: raise NoViableAltException(self) - self.state = 397 + self.state = 468 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 398 + self.state = 469 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -3038,10 +3406,305 @@ def body(self): self.exitRule() return localctx + + class SynapseContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def SYNAPSE_KEYWORD(self): + return self.getToken(PyNestMLParser.SYNAPSE_KEYWORD, 0) + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def COLON(self): + return self.getToken(PyNestMLParser.COLON, 0) + + def synapseBody(self): + return self.getTypedRuleContext(PyNestMLParser.SynapseBodyContext,0) + + + def getRuleIndex(self): + return PyNestMLParser.RULE_synapse + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitSynapse" ): + return visitor.visitSynapse(self) + else: + return visitor.visitChildren(self) + + + + + def synapse(self): + + localctx = PyNestMLParser.SynapseContext(self, self._ctx, self.state) + self.enterRule(localctx, 68, self.RULE_synapse) + try: + self.enterOuterAlt(localctx, 1) + self.state = 471 + self.match(PyNestMLParser.SYNAPSE_KEYWORD) + self.state = 472 + self.match(PyNestMLParser.NAME) + self.state = 473 + self.match(PyNestMLParser.COLON) + self.state = 474 + self.synapseBody() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class SynapseBodyContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def END_KEYWORD(self): + return self.getToken(PyNestMLParser.END_KEYWORD, 0) + + def NEWLINE(self, i:int=None): + if i is None: + return self.getTokens(PyNestMLParser.NEWLINE) + else: + return self.getToken(PyNestMLParser.NEWLINE, i) + + def blockWithVariables(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.BlockWithVariablesContext) + else: + return self.getTypedRuleContext(PyNestMLParser.BlockWithVariablesContext,i) + + + def equationsBlock(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.EquationsBlockContext) + else: + return self.getTypedRuleContext(PyNestMLParser.EquationsBlockContext,i) + + + def inputBlock(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.InputBlockContext) + else: + return self.getTypedRuleContext(PyNestMLParser.InputBlockContext,i) + + + def outputBlock(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.OutputBlockContext) + else: + return self.getTypedRuleContext(PyNestMLParser.OutputBlockContext,i) + + + def function(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.FunctionContext) + else: + return self.getTypedRuleContext(PyNestMLParser.FunctionContext,i) + + + def onReceiveBlock(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.OnReceiveBlockContext) + else: + return self.getTypedRuleContext(PyNestMLParser.OnReceiveBlockContext,i) + + + def updateBlock(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.UpdateBlockContext) + else: + return self.getTypedRuleContext(PyNestMLParser.UpdateBlockContext,i) + + + def getRuleIndex(self): + return PyNestMLParser.RULE_synapseBody + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitSynapseBody" ): + return visitor.visitSynapseBody(self) + else: + return visitor.visitChildren(self) + + + + + def synapseBody(self): + + localctx = PyNestMLParser.SynapseBodyContext(self, self._ctx, self.state) + self.enterRule(localctx, 70, self.RULE_synapseBody) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 486 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.FUNCTION_KEYWORD) | (1 << PyNestMLParser.STATE_KEYWORD) | (1 << PyNestMLParser.PARAMETERS_KEYWORD) | (1 << PyNestMLParser.INTERNALS_KEYWORD) | (1 << PyNestMLParser.UPDATE_KEYWORD) | (1 << PyNestMLParser.EQUATIONS_KEYWORD) | (1 << PyNestMLParser.INPUT_KEYWORD) | (1 << PyNestMLParser.OUTPUT_KEYWORD) | (1 << PyNestMLParser.ON_RECEIVE_KEYWORD))) != 0): + self.state = 484 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [PyNestMLParser.NEWLINE]: + self.state = 476 + self.match(PyNestMLParser.NEWLINE) + pass + elif token in [PyNestMLParser.STATE_KEYWORD, PyNestMLParser.PARAMETERS_KEYWORD, PyNestMLParser.INTERNALS_KEYWORD]: + self.state = 477 + self.blockWithVariables() + pass + elif token in [PyNestMLParser.EQUATIONS_KEYWORD]: + self.state = 478 + self.equationsBlock() + pass + elif token in [PyNestMLParser.INPUT_KEYWORD]: + self.state = 479 + self.inputBlock() + pass + elif token in [PyNestMLParser.OUTPUT_KEYWORD]: + self.state = 480 + self.outputBlock() + pass + elif token in [PyNestMLParser.FUNCTION_KEYWORD]: + self.state = 481 + self.function() + pass + elif token in [PyNestMLParser.ON_RECEIVE_KEYWORD]: + self.state = 482 + self.onReceiveBlock() + pass + elif token in [PyNestMLParser.UPDATE_KEYWORD]: + self.state = 483 + self.updateBlock() + pass + else: + raise NoViableAltException(self) + + self.state = 488 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 489 + self.match(PyNestMLParser.END_KEYWORD) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class OnReceiveBlockContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.inputPortName = None # Token + + def ON_RECEIVE_KEYWORD(self): + return self.getToken(PyNestMLParser.ON_RECEIVE_KEYWORD, 0) + + def LEFT_PAREN(self): + return self.getToken(PyNestMLParser.LEFT_PAREN, 0) + + def RIGHT_PAREN(self): + return self.getToken(PyNestMLParser.RIGHT_PAREN, 0) + + def COLON(self): + return self.getToken(PyNestMLParser.COLON, 0) + + def block(self): + return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + + + def END_KEYWORD(self): + return self.getToken(PyNestMLParser.END_KEYWORD, 0) + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def COMMA(self, i:int=None): + if i is None: + return self.getTokens(PyNestMLParser.COMMA) + else: + return self.getToken(PyNestMLParser.COMMA, i) + + def constParameter(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.ConstParameterContext) + else: + return self.getTypedRuleContext(PyNestMLParser.ConstParameterContext,i) + + + def getRuleIndex(self): + return PyNestMLParser.RULE_onReceiveBlock + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitOnReceiveBlock" ): + return visitor.visitOnReceiveBlock(self) + else: + return visitor.visitChildren(self) + + + + + def onReceiveBlock(self): + + localctx = PyNestMLParser.OnReceiveBlockContext(self, self._ctx, self.state) + self.enterRule(localctx, 72, self.RULE_onReceiveBlock) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 491 + self.match(PyNestMLParser.ON_RECEIVE_KEYWORD) + self.state = 492 + self.match(PyNestMLParser.LEFT_PAREN) + self.state = 493 + localctx.inputPortName = self.match(PyNestMLParser.NAME) + self.state = 498 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==PyNestMLParser.COMMA: + self.state = 494 + self.match(PyNestMLParser.COMMA) + self.state = 495 + self.constParameter() + self.state = 500 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 501 + self.match(PyNestMLParser.RIGHT_PAREN) + self.state = 502 + self.match(PyNestMLParser.COLON) + self.state = 503 + self.block() + self.state = 504 + self.match(PyNestMLParser.END_KEYWORD) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class BlockWithVariablesContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.BlockWithVariablesContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.blockType = None # Token @@ -3060,17 +3723,14 @@ def PARAMETERS_KEYWORD(self): def INTERNALS_KEYWORD(self): return self.getToken(PyNestMLParser.INTERNALS_KEYWORD, 0) - def INITIAL_VALUES_KEYWORD(self): - return self.getToken(PyNestMLParser.INITIAL_VALUES_KEYWORD, 0) - - def declaration(self, i=None): + def declaration(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.DeclarationContext) else: return self.getTypedRuleContext(PyNestMLParser.DeclarationContext,i) - def NEWLINE(self, i=None): + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NEWLINE) else: @@ -3079,8 +3739,8 @@ def NEWLINE(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_blockWithVariables - def accept(self, visitor): - if hasattr(visitor, "visitBlockWithVariables"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitBlockWithVariables" ): return visitor.visitBlockWithVariables(self) else: return visitor.visitChildren(self) @@ -3091,43 +3751,43 @@ def accept(self, visitor): def blockWithVariables(self): localctx = PyNestMLParser.BlockWithVariablesContext(self, self._ctx, self.state) - self.enterRule(localctx, 60, self.RULE_blockWithVariables) + self.enterRule(localctx, 74, self.RULE_blockWithVariables) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 400 + self.state = 506 localctx.blockType = self._input.LT(1) _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.STATE_KEYWORD) | (1 << PyNestMLParser.PARAMETERS_KEYWORD) | (1 << PyNestMLParser.INTERNALS_KEYWORD) | (1 << PyNestMLParser.INITIAL_VALUES_KEYWORD))) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.STATE_KEYWORD) | (1 << PyNestMLParser.PARAMETERS_KEYWORD) | (1 << PyNestMLParser.INTERNALS_KEYWORD))) != 0)): localctx.blockType = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 401 + self.state = 507 self.match(PyNestMLParser.COLON) - self.state = 406 + self.state = 512 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.FUNCTION_KEYWORD) | (1 << PyNestMLParser.RECORDABLE_KEYWORD))) != 0) or _la==PyNestMLParser.NAME: - self.state = 404 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.INLINE_KEYWORD) | (1 << PyNestMLParser.RECORDABLE_KEYWORD))) != 0) or _la==PyNestMLParser.NAME: + self.state = 510 self._errHandler.sync(self) token = self._input.LA(1) - if token in [PyNestMLParser.FUNCTION_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD, PyNestMLParser.NAME]: - self.state = 402 + if token in [PyNestMLParser.INLINE_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD, PyNestMLParser.NAME]: + self.state = 508 self.declaration() pass elif token in [PyNestMLParser.NEWLINE]: - self.state = 403 + self.state = 509 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 408 + self.state = 514 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 409 + self.state = 515 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -3137,10 +3797,12 @@ def blockWithVariables(self): self.exitRule() return localctx + class UpdateBlockContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.UpdateBlockContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def UPDATE_KEYWORD(self): @@ -3159,8 +3821,8 @@ def END_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_updateBlock - def accept(self, visitor): - if hasattr(visitor, "visitUpdateBlock"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitUpdateBlock" ): return visitor.visitUpdateBlock(self) else: return visitor.visitChildren(self) @@ -3171,16 +3833,16 @@ def accept(self, visitor): def updateBlock(self): localctx = PyNestMLParser.UpdateBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 62, self.RULE_updateBlock) + self.enterRule(localctx, 76, self.RULE_updateBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 411 + self.state = 517 self.match(PyNestMLParser.UPDATE_KEYWORD) - self.state = 412 + self.state = 518 self.match(PyNestMLParser.COLON) - self.state = 413 + self.state = 519 self.block() - self.state = 414 + self.state = 520 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -3190,10 +3852,12 @@ def updateBlock(self): self.exitRule() return localctx + class EquationsBlockContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.EquationsBlockContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def EQUATIONS_KEYWORD(self): @@ -3205,28 +3869,28 @@ def COLON(self): def END_KEYWORD(self): return self.getToken(PyNestMLParser.END_KEYWORD, 0) - def inlineExpression(self, i=None): + def inlineExpression(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.InlineExpressionContext) else: return self.getTypedRuleContext(PyNestMLParser.InlineExpressionContext,i) - def odeEquation(self, i=None): + def odeEquation(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.OdeEquationContext) else: return self.getTypedRuleContext(PyNestMLParser.OdeEquationContext,i) - def kernel(self, i=None): + def kernel(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.KernelContext) else: return self.getTypedRuleContext(PyNestMLParser.KernelContext,i) - def NEWLINE(self, i=None): + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NEWLINE) else: @@ -3235,8 +3899,8 @@ def NEWLINE(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_equationsBlock - def accept(self, visitor): - if hasattr(visitor, "visitEquationsBlock"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitEquationsBlock" ): return visitor.visitEquationsBlock(self) else: return visitor.visitChildren(self) @@ -3247,45 +3911,45 @@ def accept(self, visitor): def equationsBlock(self): localctx = PyNestMLParser.EquationsBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 64, self.RULE_equationsBlock) + self.enterRule(localctx, 78, self.RULE_equationsBlock) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 416 + self.state = 522 self.match(PyNestMLParser.EQUATIONS_KEYWORD) - self.state = 417 + self.state = 523 self.match(PyNestMLParser.COLON) - self.state = 424 + self.state = 530 self._errHandler.sync(self) _la = self._input.LA(1) while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.NEWLINE) | (1 << PyNestMLParser.INLINE_KEYWORD) | (1 << PyNestMLParser.RECORDABLE_KEYWORD) | (1 << PyNestMLParser.KERNEL_KEYWORD))) != 0) or _la==PyNestMLParser.NAME: - self.state = 422 + self.state = 528 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.INLINE_KEYWORD, PyNestMLParser.RECORDABLE_KEYWORD]: - self.state = 418 + self.state = 524 self.inlineExpression() pass elif token in [PyNestMLParser.NAME]: - self.state = 419 + self.state = 525 self.odeEquation() pass elif token in [PyNestMLParser.KERNEL_KEYWORD]: - self.state = 420 + self.state = 526 self.kernel() pass elif token in [PyNestMLParser.NEWLINE]: - self.state = 421 + self.state = 527 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 426 + self.state = 532 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 427 + self.state = 533 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -3295,10 +3959,12 @@ def equationsBlock(self): self.exitRule() return localctx + class InputBlockContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.InputBlockContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def INPUT_KEYWORD(self): @@ -3310,14 +3976,14 @@ def COLON(self): def END_KEYWORD(self): return self.getToken(PyNestMLParser.END_KEYWORD, 0) - def inputPort(self, i=None): + def inputPort(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.InputPortContext) else: return self.getTypedRuleContext(PyNestMLParser.InputPortContext,i) - def NEWLINE(self, i=None): + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NEWLINE) else: @@ -3326,8 +3992,8 @@ def NEWLINE(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_inputBlock - def accept(self, visitor): - if hasattr(visitor, "visitInputBlock"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitInputBlock" ): return visitor.visitInputBlock(self) else: return visitor.visitChildren(self) @@ -3338,37 +4004,37 @@ def accept(self, visitor): def inputBlock(self): localctx = PyNestMLParser.InputBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 66, self.RULE_inputBlock) + self.enterRule(localctx, 80, self.RULE_inputBlock) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 429 + self.state = 535 self.match(PyNestMLParser.INPUT_KEYWORD) - self.state = 430 + self.state = 536 self.match(PyNestMLParser.COLON) - self.state = 435 + self.state = 541 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.NEWLINE or _la==PyNestMLParser.NAME: - self.state = 433 + self.state = 539 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.NAME]: - self.state = 431 + self.state = 537 self.inputPort() pass elif token in [PyNestMLParser.NEWLINE]: - self.state = 432 + self.state = 538 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 437 + self.state = 543 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 438 + self.state = 544 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -3378,20 +4044,22 @@ def inputBlock(self): self.exitRule() return localctx + class InputPortContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.InputPortContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.name = None # Token self.sizeParameter = None # Token - self.isCurrent = None # Token + self.isContinuous = None # Token self.isSpike = None # Token def LEFT_ANGLE_MINUS(self): return self.getToken(PyNestMLParser.LEFT_ANGLE_MINUS, 0) - def NAME(self, i=None): + def NAME(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.NAME) else: @@ -3407,15 +4075,15 @@ def dataType(self): return self.getTypedRuleContext(PyNestMLParser.DataTypeContext,0) - def inputQualifier(self, i=None): + def inputQualifier(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.InputQualifierContext) else: return self.getTypedRuleContext(PyNestMLParser.InputQualifierContext,i) - def CURRENT_KEYWORD(self): - return self.getToken(PyNestMLParser.CURRENT_KEYWORD, 0) + def CONTINUOUS_KEYWORD(self): + return self.getToken(PyNestMLParser.CONTINUOUS_KEYWORD, 0) def SPIKE_KEYWORD(self): return self.getToken(PyNestMLParser.SPIKE_KEYWORD, 0) @@ -3423,8 +4091,8 @@ def SPIKE_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_inputPort - def accept(self, visitor): - if hasattr(visitor, "visitInputPort"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitInputPort" ): return visitor.visitInputPort(self) else: return visitor.visitChildren(self) @@ -3435,53 +4103,53 @@ def accept(self, visitor): def inputPort(self): localctx = PyNestMLParser.InputPortContext(self, self._ctx, self.state) - self.enterRule(localctx, 68, self.RULE_inputPort) + self.enterRule(localctx, 82, self.RULE_inputPort) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 440 + self.state = 546 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 444 + self.state = 550 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.LEFT_SQUARE_BRACKET: - self.state = 441 + self.state = 547 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 442 + self.state = 548 localctx.sizeParameter = self.match(PyNestMLParser.NAME) - self.state = 443 + self.state = 549 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 447 + self.state = 553 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.INTEGER_KEYWORD) | (1 << PyNestMLParser.REAL_KEYWORD) | (1 << PyNestMLParser.STRING_KEYWORD) | (1 << PyNestMLParser.BOOLEAN_KEYWORD) | (1 << PyNestMLParser.VOID_KEYWORD) | (1 << PyNestMLParser.LEFT_PAREN))) != 0) or _la==PyNestMLParser.NAME or _la==PyNestMLParser.UNSIGNED_INTEGER: - self.state = 446 + self.state = 552 self.dataType() - self.state = 449 + self.state = 555 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 453 + self.state = 559 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.INHIBITORY_KEYWORD or _la==PyNestMLParser.EXCITATORY_KEYWORD: - self.state = 450 + self.state = 556 self.inputQualifier() - self.state = 455 + self.state = 561 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 458 + self.state = 564 self._errHandler.sync(self) token = self._input.LA(1) - if token in [PyNestMLParser.CURRENT_KEYWORD]: - self.state = 456 - localctx.isCurrent = self.match(PyNestMLParser.CURRENT_KEYWORD) + if token in [PyNestMLParser.CONTINUOUS_KEYWORD]: + self.state = 562 + localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass elif token in [PyNestMLParser.SPIKE_KEYWORD]: - self.state = 457 + self.state = 563 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) pass else: @@ -3495,10 +4163,12 @@ def inputPort(self): self.exitRule() return localctx + class InputQualifierContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.InputQualifierContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.isInhibitory = None # Token self.isExcitatory = None # Token @@ -3512,8 +4182,8 @@ def EXCITATORY_KEYWORD(self): def getRuleIndex(self): return PyNestMLParser.RULE_inputQualifier - def accept(self, visitor): - if hasattr(visitor, "visitInputQualifier"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitInputQualifier" ): return visitor.visitInputQualifier(self) else: return visitor.visitChildren(self) @@ -3524,18 +4194,18 @@ def accept(self, visitor): def inputQualifier(self): localctx = PyNestMLParser.InputQualifierContext(self, self._ctx, self.state) - self.enterRule(localctx, 70, self.RULE_inputQualifier) + self.enterRule(localctx, 84, self.RULE_inputQualifier) try: self.enterOuterAlt(localctx, 1) - self.state = 462 + self.state = 568 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.INHIBITORY_KEYWORD]: - self.state = 460 + self.state = 566 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass elif token in [PyNestMLParser.EXCITATORY_KEYWORD]: - self.state = 461 + self.state = 567 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) pass else: @@ -3549,13 +4219,15 @@ def inputQualifier(self): self.exitRule() return localctx + class OutputBlockContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.OutputBlockContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.isSpike = None # Token - self.isCurrent = None # Token + self.isContinuous = None # Token def OUTPUT_KEYWORD(self): return self.getToken(PyNestMLParser.OUTPUT_KEYWORD, 0) @@ -3566,14 +4238,14 @@ def COLON(self): def SPIKE_KEYWORD(self): return self.getToken(PyNestMLParser.SPIKE_KEYWORD, 0) - def CURRENT_KEYWORD(self): - return self.getToken(PyNestMLParser.CURRENT_KEYWORD, 0) + def CONTINUOUS_KEYWORD(self): + return self.getToken(PyNestMLParser.CONTINUOUS_KEYWORD, 0) def getRuleIndex(self): return PyNestMLParser.RULE_outputBlock - def accept(self, visitor): - if hasattr(visitor, "visitOutputBlock"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitOutputBlock" ): return visitor.visitOutputBlock(self) else: return visitor.visitChildren(self) @@ -3584,23 +4256,23 @@ def accept(self, visitor): def outputBlock(self): localctx = PyNestMLParser.OutputBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 72, self.RULE_outputBlock) + self.enterRule(localctx, 86, self.RULE_outputBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 464 + self.state = 570 self.match(PyNestMLParser.OUTPUT_KEYWORD) - self.state = 465 + self.state = 571 self.match(PyNestMLParser.COLON) - self.state = 468 + self.state = 574 self._errHandler.sync(self) token = self._input.LA(1) if token in [PyNestMLParser.SPIKE_KEYWORD]: - self.state = 466 + self.state = 572 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) pass - elif token in [PyNestMLParser.CURRENT_KEYWORD]: - self.state = 467 - localctx.isCurrent = self.match(PyNestMLParser.CURRENT_KEYWORD) + elif token in [PyNestMLParser.CONTINUOUS_KEYWORD]: + self.state = 573 + localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass else: raise NoViableAltException(self) @@ -3613,10 +4285,12 @@ def outputBlock(self): self.exitRule() return localctx + class FunctionContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.FunctionContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser self.returnType = None # DataTypeContext @@ -3642,7 +4316,7 @@ def block(self): def END_KEYWORD(self): return self.getToken(PyNestMLParser.END_KEYWORD, 0) - def parameter(self, i=None): + def parameter(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.ParameterContext) else: @@ -3653,7 +4327,7 @@ def dataType(self): return self.getTypedRuleContext(PyNestMLParser.DataTypeContext,0) - def COMMA(self, i=None): + def COMMA(self, i:int=None): if i is None: return self.getTokens(PyNestMLParser.COMMA) else: @@ -3662,8 +4336,8 @@ def COMMA(self, i=None): def getRuleIndex(self): return PyNestMLParser.RULE_function - def accept(self, visitor): - if hasattr(visitor, "visitFunction"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFunction" ): return visitor.visitFunction(self) else: return visitor.visitChildren(self) @@ -3674,51 +4348,51 @@ def accept(self, visitor): def function(self): localctx = PyNestMLParser.FunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 74, self.RULE_function) + self.enterRule(localctx, 88, self.RULE_function) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 470 + self.state = 576 self.match(PyNestMLParser.FUNCTION_KEYWORD) - self.state = 471 + self.state = 577 self.match(PyNestMLParser.NAME) - self.state = 472 + self.state = 578 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 481 + self.state = 587 self._errHandler.sync(self) _la = self._input.LA(1) if _la==PyNestMLParser.NAME: - self.state = 473 + self.state = 579 self.parameter() - self.state = 478 + self.state = 584 self._errHandler.sync(self) _la = self._input.LA(1) while _la==PyNestMLParser.COMMA: - self.state = 474 + self.state = 580 self.match(PyNestMLParser.COMMA) - self.state = 475 + self.state = 581 self.parameter() - self.state = 480 + self.state = 586 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 483 + self.state = 589 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 485 + self.state = 591 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << PyNestMLParser.INTEGER_KEYWORD) | (1 << PyNestMLParser.REAL_KEYWORD) | (1 << PyNestMLParser.STRING_KEYWORD) | (1 << PyNestMLParser.BOOLEAN_KEYWORD) | (1 << PyNestMLParser.VOID_KEYWORD) | (1 << PyNestMLParser.LEFT_PAREN))) != 0) or _la==PyNestMLParser.NAME or _la==PyNestMLParser.UNSIGNED_INTEGER: - self.state = 484 + self.state = 590 localctx.returnType = self.dataType() - self.state = 487 + self.state = 593 self.match(PyNestMLParser.COLON) - self.state = 488 + self.state = 594 self.block() - self.state = 489 + self.state = 595 self.match(PyNestMLParser.END_KEYWORD) except RecognitionException as re: localctx.exception = re @@ -3728,10 +4402,12 @@ def function(self): self.exitRule() return localctx + class ParameterContext(ParserRuleContext): + __slots__ = 'parser' - def __init__(self, parser, parent=None, invokingState=-1): - super(PyNestMLParser.ParameterContext, self).__init__(parent, invokingState) + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) self.parser = parser def NAME(self): @@ -3744,8 +4420,8 @@ def dataType(self): def getRuleIndex(self): return PyNestMLParser.RULE_parameter - def accept(self, visitor): - if hasattr(visitor, "visitParameter"): + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitParameter" ): return visitor.visitParameter(self) else: return visitor.visitChildren(self) @@ -3756,12 +4432,12 @@ def accept(self, visitor): def parameter(self): localctx = PyNestMLParser.ParameterContext(self, self._ctx, self.state) - self.enterRule(localctx, 76, self.RULE_parameter) + self.enterRule(localctx, 90, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 491 + self.state = 597 self.match(PyNestMLParser.NAME) - self.state = 492 + self.state = 598 self.dataType() except RecognitionException as re: localctx.exception = re @@ -3772,8 +4448,78 @@ def parameter(self): return localctx + class ConstParameterContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.name = None # Token + self.value = None # Token + + def EQUALS(self): + return self.getToken(PyNestMLParser.EQUALS, 0) + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def BOOLEAN_LITERAL(self): + return self.getToken(PyNestMLParser.BOOLEAN_LITERAL, 0) + + def UNSIGNED_INTEGER(self): + return self.getToken(PyNestMLParser.UNSIGNED_INTEGER, 0) + + def FLOAT(self): + return self.getToken(PyNestMLParser.FLOAT, 0) + + def STRING_LITERAL(self): + return self.getToken(PyNestMLParser.STRING_LITERAL, 0) + + def INF_KEYWORD(self): + return self.getToken(PyNestMLParser.INF_KEYWORD, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_constParameter + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitConstParameter" ): + return visitor.visitConstParameter(self) + else: + return visitor.visitChildren(self) + + + + + def constParameter(self): + + localctx = PyNestMLParser.ConstParameterContext(self, self._ctx, self.state) + self.enterRule(localctx, 92, self.RULE_constParameter) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 600 + localctx.name = self.match(PyNestMLParser.NAME) + self.state = 601 + self.match(PyNestMLParser.EQUALS) + self.state = 602 + localctx.value = self._input.LT(1) + _la = self._input.LA(1) + if not(_la==PyNestMLParser.INF_KEYWORD or ((((_la - 84)) & ~0x3f) == 0 and ((1 << (_la - 84)) & ((1 << (PyNestMLParser.BOOLEAN_LITERAL - 84)) | (1 << (PyNestMLParser.STRING_LITERAL - 84)) | (1 << (PyNestMLParser.UNSIGNED_INTEGER - 84)) | (1 << (PyNestMLParser.FLOAT - 84)))) != 0)): + localctx.value = self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + - def sempred(self, localctx, ruleIndex, predIndex): + def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): if self._predicates == None: self._predicates = dict() self._predicates[1] = self.unitType_sempred @@ -3784,7 +4530,7 @@ def sempred(self, localctx, ruleIndex, predIndex): else: return pred(localctx, predIndex) - def unitType_sempred(self, localctx, predIndex): + def unitType_sempred(self, localctx:UnitTypeContext, predIndex:int): if predIndex == 0: return self.precpred(self._ctx, 3) @@ -3793,7 +4539,7 @@ def unitType_sempred(self, localctx, predIndex): return self.precpred(self._ctx, 4) - def expression_sempred(self, localctx, predIndex): + def expression_sempred(self, localctx:ExpressionContext, predIndex:int): if predIndex == 2: return self.precpred(self._ctx, 10) diff --git a/pynestml/generated/PyNestMLParser.tokens b/pynestml/generated/PyNestMLParser.tokens deleted file mode 100644 index a8c14cc33..000000000 --- a/pynestml/generated/PyNestMLParser.tokens +++ /dev/null @@ -1,154 +0,0 @@ -SL_COMMENT=1 -ML_COMMENT=2 -NEWLINE=3 -WS=4 -LINE_ESCAPE=5 -END_KEYWORD=6 -INTEGER_KEYWORD=7 -REAL_KEYWORD=8 -STRING_KEYWORD=9 -BOOLEAN_KEYWORD=10 -VOID_KEYWORD=11 -FUNCTION_KEYWORD=12 -INLINE_KEYWORD=13 -RETURN_KEYWORD=14 -IF_KEYWORD=15 -ELIF_KEYWORD=16 -ELSE_KEYWORD=17 -FOR_KEYWORD=18 -WHILE_KEYWORD=19 -IN_KEYWORD=20 -STEP_KEYWORD=21 -INF_KEYWORD=22 -AND_KEYWORD=23 -OR_KEYWORD=24 -NOT_KEYWORD=25 -RECORDABLE_KEYWORD=26 -KERNEL_KEYWORD=27 -NEURON_KEYWORD=28 -STATE_KEYWORD=29 -PARAMETERS_KEYWORD=30 -INTERNALS_KEYWORD=31 -INITIAL_VALUES_KEYWORD=32 -UPDATE_KEYWORD=33 -EQUATIONS_KEYWORD=34 -INPUT_KEYWORD=35 -OUTPUT_KEYWORD=36 -CURRENT_KEYWORD=37 -SPIKE_KEYWORD=38 -INHIBITORY_KEYWORD=39 -EXCITATORY_KEYWORD=40 -ELLIPSIS=41 -LEFT_PAREN=42 -RIGHT_PAREN=43 -PLUS=44 -TILDE=45 -PIPE=46 -CARET=47 -AMPERSAND=48 -LEFT_SQUARE_BRACKET=49 -LEFT_ANGLE_MINUS=50 -RIGHT_SQUARE_BRACKET=51 -LEFT_LEFT_SQUARE=52 -RIGHT_RIGHT_SQUARE=53 -LEFT_LEFT_ANGLE=54 -RIGHT_RIGHT_ANGLE=55 -LEFT_ANGLE=56 -RIGHT_ANGLE=57 -LEFT_ANGLE_EQUALS=58 -PLUS_EQUALS=59 -MINUS_EQUALS=60 -STAR_EQUALS=61 -FORWARD_SLASH_EQUALS=62 -EQUALS_EQUALS=63 -EXCLAMATION_EQUALS=64 -LEFT_ANGLE_RIGHT_ANGLE=65 -RIGHT_ANGLE_EQUALS=66 -COMMA=67 -MINUS=68 -EQUALS=69 -STAR=70 -STAR_STAR=71 -FORWARD_SLASH=72 -PERCENT=73 -QUESTION=74 -COLON=75 -SEMICOLON=76 -DIFFERENTIAL_ORDER=77 -BOOLEAN_LITERAL=78 -STRING_LITERAL=79 -NAME=80 -UNSIGNED_INTEGER=81 -FLOAT=82 -'end'=6 -'integer'=7 -'real'=8 -'string'=9 -'boolean'=10 -'void'=11 -'function'=12 -'inline'=13 -'return'=14 -'if'=15 -'elif'=16 -'else'=17 -'for'=18 -'while'=19 -'in'=20 -'step'=21 -'inf'=22 -'and'=23 -'or'=24 -'not'=25 -'recordable'=26 -'kernel'=27 -'neuron'=28 -'state'=29 -'parameters'=30 -'internals'=31 -'initial_values'=32 -'update'=33 -'equations'=34 -'input'=35 -'output'=36 -'current'=37 -'spike'=38 -'inhibitory'=39 -'excitatory'=40 -'...'=41 -'('=42 -')'=43 -'+'=44 -'~'=45 -'|'=46 -'^'=47 -'&'=48 -'['=49 -'<-'=50 -']'=51 -'[['=52 -']]'=53 -'<<'=54 -'>>'=55 -'<'=56 -'>'=57 -'<='=58 -'+='=59 -'-='=60 -'*='=61 -'/='=62 -'=='=63 -'!='=64 -'<>'=65 -'>='=66 -','=67 -'-'=68 -'='=69 -'*'=70 -'**'=71 -'/'=72 -'%'=73 -'?'=74 -':'=75 -';'=76 -'\''=77 diff --git a/pynestml/generated/PyNestMLParserVisitor.py b/pynestml/generated/PyNestMLParserVisitor.py index 06a009a04..85204955c 100644 --- a/pynestml/generated/PyNestMLParserVisitor.py +++ b/pynestml/generated/PyNestMLParserVisitor.py @@ -1,202 +1,248 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.7.1 +# Generated from PyNestMLParser.g4 by ANTLR 4.10 from antlr4 import * +if __name__ is not None and "." in __name__: + from .PyNestMLParser import PyNestMLParser +else: + from PyNestMLParser import PyNestMLParser # This class defines a complete generic visitor for a parse tree produced by PyNestMLParser. class PyNestMLParserVisitor(ParseTreeVisitor): # Visit a parse tree produced by PyNestMLParser#dataType. - def visitDataType(self, ctx): + def visitDataType(self, ctx:PyNestMLParser.DataTypeContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#unitType. - def visitUnitType(self, ctx): + def visitUnitType(self, ctx:PyNestMLParser.UnitTypeContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#unitTypeExponent. - def visitUnitTypeExponent(self, ctx): + def visitUnitTypeExponent(self, ctx:PyNestMLParser.UnitTypeExponentContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#expression. - def visitExpression(self, ctx): + def visitExpression(self, ctx:PyNestMLParser.ExpressionContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#simpleExpression. - def visitSimpleExpression(self, ctx): + def visitSimpleExpression(self, ctx:PyNestMLParser.SimpleExpressionContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#unaryOperator. - def visitUnaryOperator(self, ctx): + def visitUnaryOperator(self, ctx:PyNestMLParser.UnaryOperatorContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#bitOperator. - def visitBitOperator(self, ctx): + def visitBitOperator(self, ctx:PyNestMLParser.BitOperatorContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#comparisonOperator. - def visitComparisonOperator(self, ctx): + def visitComparisonOperator(self, ctx:PyNestMLParser.ComparisonOperatorContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#logicalOperator. - def visitLogicalOperator(self, ctx): + def visitLogicalOperator(self, ctx:PyNestMLParser.LogicalOperatorContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#indexParameter. + def visitIndexParameter(self, ctx:PyNestMLParser.IndexParameterContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#variable. - def visitVariable(self, ctx): + def visitVariable(self, ctx:PyNestMLParser.VariableContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#functionCall. - def visitFunctionCall(self, ctx): + def visitFunctionCall(self, ctx:PyNestMLParser.FunctionCallContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#inlineExpression. - def visitInlineExpression(self, ctx): + def visitInlineExpression(self, ctx:PyNestMLParser.InlineExpressionContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#odeEquation. - def visitOdeEquation(self, ctx): + def visitOdeEquation(self, ctx:PyNestMLParser.OdeEquationContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#kernel. - def visitKernel(self, ctx): + def visitKernel(self, ctx:PyNestMLParser.KernelContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#block. - def visitBlock(self, ctx): + def visitBlock(self, ctx:PyNestMLParser.BlockContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#stmt. - def visitStmt(self, ctx): + def visitStmt(self, ctx:PyNestMLParser.StmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#compoundStmt. - def visitCompoundStmt(self, ctx): + def visitCompoundStmt(self, ctx:PyNestMLParser.CompoundStmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#smallStmt. - def visitSmallStmt(self, ctx): + def visitSmallStmt(self, ctx:PyNestMLParser.SmallStmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#assignment. - def visitAssignment(self, ctx): + def visitAssignment(self, ctx:PyNestMLParser.AssignmentContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#declaration. - def visitDeclaration(self, ctx): + def visitDeclaration(self, ctx:PyNestMLParser.DeclarationContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#anyDecorator. + def visitAnyDecorator(self, ctx:PyNestMLParser.AnyDecoratorContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#namespaceDecoratorNamespace. + def visitNamespaceDecoratorNamespace(self, ctx:PyNestMLParser.NamespaceDecoratorNamespaceContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#namespaceDecoratorName. + def visitNamespaceDecoratorName(self, ctx:PyNestMLParser.NamespaceDecoratorNameContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#returnStmt. - def visitReturnStmt(self, ctx): + def visitReturnStmt(self, ctx:PyNestMLParser.ReturnStmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#ifStmt. - def visitIfStmt(self, ctx): + def visitIfStmt(self, ctx:PyNestMLParser.IfStmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#ifClause. - def visitIfClause(self, ctx): + def visitIfClause(self, ctx:PyNestMLParser.IfClauseContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#elifClause. - def visitElifClause(self, ctx): + def visitElifClause(self, ctx:PyNestMLParser.ElifClauseContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#elseClause. - def visitElseClause(self, ctx): + def visitElseClause(self, ctx:PyNestMLParser.ElseClauseContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#forStmt. - def visitForStmt(self, ctx): + def visitForStmt(self, ctx:PyNestMLParser.ForStmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#whileStmt. - def visitWhileStmt(self, ctx): + def visitWhileStmt(self, ctx:PyNestMLParser.WhileStmtContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#nestMLCompilationUnit. - def visitNestMLCompilationUnit(self, ctx): + def visitNestMLCompilationUnit(self, ctx:PyNestMLParser.NestMLCompilationUnitContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#neuron. - def visitNeuron(self, ctx): + def visitNeuron(self, ctx:PyNestMLParser.NeuronContext): return self.visitChildren(ctx) - # Visit a parse tree produced by PyNestMLParser#body. - def visitBody(self, ctx): + # Visit a parse tree produced by PyNestMLParser#neuronBody. + def visitNeuronBody(self, ctx:PyNestMLParser.NeuronBodyContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#synapse. + def visitSynapse(self, ctx:PyNestMLParser.SynapseContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#synapseBody. + def visitSynapseBody(self, ctx:PyNestMLParser.SynapseBodyContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#onReceiveBlock. + def visitOnReceiveBlock(self, ctx:PyNestMLParser.OnReceiveBlockContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#blockWithVariables. - def visitBlockWithVariables(self, ctx): + def visitBlockWithVariables(self, ctx:PyNestMLParser.BlockWithVariablesContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#updateBlock. - def visitUpdateBlock(self, ctx): + def visitUpdateBlock(self, ctx:PyNestMLParser.UpdateBlockContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#equationsBlock. - def visitEquationsBlock(self, ctx): + def visitEquationsBlock(self, ctx:PyNestMLParser.EquationsBlockContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#inputBlock. - def visitInputBlock(self, ctx): + def visitInputBlock(self, ctx:PyNestMLParser.InputBlockContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#inputPort. - def visitInputPort(self, ctx): + def visitInputPort(self, ctx:PyNestMLParser.InputPortContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#inputQualifier. - def visitInputQualifier(self, ctx): + def visitInputQualifier(self, ctx:PyNestMLParser.InputQualifierContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#outputBlock. - def visitOutputBlock(self, ctx): + def visitOutputBlock(self, ctx:PyNestMLParser.OutputBlockContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#function. - def visitFunction(self, ctx): + def visitFunction(self, ctx:PyNestMLParser.FunctionContext): return self.visitChildren(ctx) # Visit a parse tree produced by PyNestMLParser#parameter. - def visitParameter(self, ctx): + def visitParameter(self, ctx:PyNestMLParser.ParameterContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#constParameter. + def visitConstParameter(self, ctx:PyNestMLParser.ConstParameterContext): return self.visitChildren(ctx) + +del PyNestMLParser \ No newline at end of file diff --git a/pynestml/grammars/PyNestMLLexer.g4 b/pynestml/grammars/PyNestMLLexer.g4 index 54af6c84b..38e62160e 100644 --- a/pynestml/grammars/PyNestMLLexer.g4 +++ b/pynestml/grammars/PyNestMLLexer.g4 @@ -22,21 +22,28 @@ lexer grammar PyNestMLLexer; - // N.B. the zeroth channel is the normal channel, the first is HIDDEN, so COMMENT=2 and NEW_LINE=3 - channels {COMMENT, NEW_LINE} + // N.B. the zeroth channel is the normal channel, the first is HIDDEN, so COMMENT=2 + channels {COMMENT} + DOCSTRING_TRIPLEQUOTE : '"""'; + fragment NEWLINE_FRAG : '\r'? '\n'; // non-capturing newline, as a helper to define the channel rules - SL_COMMENT: ('#' (~('\n' |'\r' ))*) -> channel(2); + WS : (' ' | '\t') -> channel(1); - ML_COMMENT : ('/*' .*? '*/' | '"""' .*? '"""')-> channel(2); - - NEWLINE : ('\r' '\n' | '\r' | '\n' ) -> channel(3); + // this token enables an expression that stretches over multiple lines. The first line ends with a `\` character + LINE_ESCAPE : '\\' NEWLINE_FRAG -> channel(1); - WS : (' ' | '\t')->channel(1); + DOCSTRING : DOCSTRING_TRIPLEQUOTE .*? DOCSTRING_TRIPLEQUOTE NEWLINE_FRAG+? -> channel(2); - // this token enables an expression that stretches over multiple lines. The first line ends with a `\` character - LINE_ESCAPE : '\\' '\r'? '\n'->channel(1); + SL_COMMENT: ('#' (~('\n' |'\r' ))*) NEWLINE_FRAG -> channel(2); + // newline is defined as a token + NEWLINE : '\r'? '\n'; + /** + * Symbols and literals are parsed first + * + * Decorator (@) keywords are defined with their @-symbol in front, because otherwise they would preclude the user from defining variables with the same name as a decorator keyword. (Rules are matched in the order in which they appear.) + */ END_KEYWORD : 'end'; INTEGER_KEYWORD : 'integer'; @@ -62,19 +69,24 @@ lexer grammar PyNestMLLexer; RECORDABLE_KEYWORD : 'recordable'; KERNEL_KEYWORD : 'kernel'; NEURON_KEYWORD : 'neuron'; + SYNAPSE_KEYWORD : 'synapse'; STATE_KEYWORD : 'state'; PARAMETERS_KEYWORD : 'parameters'; INTERNALS_KEYWORD : 'internals'; - INITIAL_VALUES_KEYWORD : 'initial_values'; UPDATE_KEYWORD : 'update'; EQUATIONS_KEYWORD : 'equations'; INPUT_KEYWORD : 'input'; OUTPUT_KEYWORD : 'output'; - CURRENT_KEYWORD : 'current'; + CONTINUOUS_KEYWORD : 'continuous'; + ON_RECEIVE_KEYWORD : 'onReceive'; SPIKE_KEYWORD : 'spike'; INHIBITORY_KEYWORD : 'inhibitory'; EXCITATORY_KEYWORD : 'excitatory'; + DECORATOR_HOMOGENEOUS : '@homogeneous'; + DECORATOR_HETEROGENEOUS : '@heterogeneous'; + + AT : '@'; ELLIPSIS : '...'; LEFT_PAREN : '('; RIGHT_PAREN : ')'; @@ -110,6 +122,7 @@ lexer grammar PyNestMLLexer; PERCENT : '%'; QUESTION : '?'; COLON : ':'; + DOUBLE_COLON : '::'; SEMICOLON : ';'; DIFFERENTIAL_ORDER : '\''; @@ -125,7 +138,7 @@ lexer grammar PyNestMLLexer; * String literals are always enclosed in "...". */ - STRING_LITERAL : '"' ( [a-zA-Z] | '_' | '$' )( [a-zA-Z] | '_' | [0-9] | '$' )* '"'; + STRING_LITERAL : '"' ('\\' (([ \t]+ ('\r'? '\n')?)|.) | ~[\\\r\n"])* '"'; NAME : ( [a-zA-Z] | '_' | '$' )( [a-zA-Z] | '_' | [0-9] | '$' )*; diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 2707cb262..3f0a6674f 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -71,7 +71,7 @@ parser grammar PyNestMLParser; | left=expression comparisonOperator right=expression | logicalNot=NOT_KEYWORD term=expression | left=expression logicalOperator right=expression - | condition=expression QUESTION ifTrue=expression COLON ifNot=expression + | condition=expression NEWLINE* QUESTION NEWLINE* ifTrue=expression NEWLINE* COLON NEWLINE* ifNot=expression | simpleExpression ; @@ -100,12 +100,16 @@ parser grammar PyNestMLParser; logicalOperator : (logicalAnd=AND_KEYWORD | logicalOr=OR_KEYWORD ); + indexParameter : (sizeStr=NAME | sizeInt=UNSIGNED_INTEGER); /** ASTVariable Provides a 'marker' AST node to identify variables used in expressions. @attribute name: The name of the variable without the differential order, e.g. V_m + @attribute vectorParameter: An optional array parameter, e.g., 'tau_syn ms[n_receptors]'. @attribute differentialOrder: The corresponding differential order, e.g. 2 */ - variable : name=NAME (DIFFERENTIAL_ORDER)*; + variable : name=NAME + (LEFT_SQUARE_BRACKET vectorParameter=indexParameter RIGHT_SQUARE_BRACKET)? + (DIFFERENTIAL_ORDER)*; /** ASTFunctionCall Represents a function call, e.g. myFun("a", "b"). @@ -122,7 +126,7 @@ parser grammar PyNestMLParser; odeEquation : lhs=variable EQUALS rhs=expression (SEMICOLON)?; - kernel : KERNEL_KEYWORD variable EQUALS expression (COMMA variable EQUALS expression)* (SEMICOLON)?; + kernel : KERNEL_KEYWORD variable EQUALS expression (COMMA NEWLINE* variable EQUALS expression)* (SEMICOLON)?; /********************************************************************************************************************* * Procedural-Language @@ -151,23 +155,34 @@ parser grammar PyNestMLParser; /** ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: 'a,b,c real = 0'. Or an function declaration 'function a = b + c'. - @attribute isRecordable: Is true iff. declaration is track-able. - @attribute isFunction: Is true iff. declaration is a function. + @attribute isRecordable: Is true iff. declaration is recordable. + @attribute isInlineExpression: Is true iff. declaration is an inline expression. @attribute variable: List with variables. @attribute datatype: Obligatory data type, e.g., 'real' or 'mV/s'. - @attribute sizeParameter: An optional array parameter, e.g., 'tau_syn ms[n_receptros]'. @attribute rhs: An optional initial expression, e.g., 'a real = 10+10' @attribute invariant: A single, optional invariant expression, e.g., '[a < 21]' */ declaration : - (isRecordable=RECORDABLE_KEYWORD)? (isFunction=FUNCTION_KEYWORD)? + (isRecordable=RECORDABLE_KEYWORD)? (isInlineExpression=INLINE_KEYWORD)? variable (COMMA variable)* dataType - (LEFT_SQUARE_BRACKET sizeParameter=NAME RIGHT_SQUARE_BRACKET)? ( EQUALS rhs = expression)? - (LEFT_LEFT_SQUARE invariant=expression RIGHT_RIGHT_SQUARE)?; + (LEFT_LEFT_SQUARE invariant=expression RIGHT_RIGHT_SQUARE)? + decorator=anyDecorator*; + + /** ... + */ + anyDecorator : DECORATOR_HOMOGENEOUS | DECORATOR_HETEROGENEOUS | AT namespaceDecoratorNamespace DOUBLE_COLON namespaceDecoratorName; - /** ATReturnStmt Models the return statement in a function. + /** + ASTVariable Provides a 'marker' AST node to identify variables used in expressions. + @attribute name: The name of the variable without the differential order, e.g. V_m + @attribute differentialOrder: The corresponding differential order, e.g. 2 + */ + namespaceDecoratorNamespace : name=NAME; + namespaceDecoratorName : name=NAME; + + /** ASTReturnStmt Models the return statement in a function. @expression An optional return expression, e.g., return tempVar */ returnStmt : RETURN_KEYWORD expression?; @@ -192,32 +207,66 @@ parser grammar PyNestMLParser; whileStmt : WHILE_KEYWORD expression COLON block END_KEYWORD; /********************************************************************************************************************* - * NestML-Language + * NestML: language root element *********************************************************************************************************************/ /** ASTNestMLCompilationUnit represents a collection of neurons as stored in a model. @attribute neuron: A list of processed models. */ - nestMLCompilationUnit: (neuron | NEWLINE )* EOF; + nestMLCompilationUnit: (neuron | synapse | NEWLINE )* EOF; + +/********************************************************************************************************************* + * NestML neuron + *********************************************************************************************************************/ /** ASTNeuron Represents a single neuron. @attribute Name: The name of the neuron, e.g., ht_neuron. @attribute body: The body of the neuron consisting of several sub-blocks. */ - neuron : NEURON_KEYWORD NAME body; + neuron : NEURON_KEYWORD NAME neuronBody; /** ASTBody The body of the neuron, e.g. internal, state, parameter... + @attribute blockWithVariables: A single block of variables, e.g. the state block. + @attribute equationsBlock: A block of ode declarations. + @attribute inputBlock: A block of input port declarations. + @attribute outputBlock: A block of output declarations. + @attribute updateBlock: A single update block containing the dynamic behavior. + @attribute function: A block declaring a user-defined function. + */ + neuronBody: COLON + (NEWLINE | blockWithVariables | equationsBlock | inputBlock | outputBlock | updateBlock | function)* + END_KEYWORD; + +/********************************************************************************************************************* + * NestML synapse + *********************************************************************************************************************/ + + /** ASTSynapse Represents a single synapse. + @attribute Name: The name of the synapse, e.g., ht_synapse. + @attribute body: The body of the synapse consisting of several sub-blocks. + */ + synapse : SYNAPSE_KEYWORD NAME COLON synapseBody; + + /** ASTBody The body of the synapse, e.g. internal, state, parameter... @attribute blockWithVariables: A single block of variables, e.g. the state block. @attribute updateBlock: A single update block containing the dynamic behavior. @attribute equationsBlock: A block of ode declarations. @attribute inputBlock: A block of input buffer declarations. @attribute outputBlock: A block of output declarations. @attribute function: A block declaring a used-defined function. + @attribute onReceive: A block declaring an event handler. */ - body: COLON - (NEWLINE | blockWithVariables | equationsBlock | inputBlock | outputBlock | updateBlock | function)* + synapseBody: + ( NEWLINE | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | updateBlock )* END_KEYWORD; + /** ASTOnReceiveBlock + @attribute block implementation of the dynamics + */ + onReceiveBlock: ON_RECEIVE_KEYWORD LEFT_PAREN inputPortName=NAME (COMMA constParameter)* RIGHT_PAREN COLON + block + END_KEYWORD; + /** ASTBlockWithVariables Represent a block with variables and constants, e.g.: state: y0, y1, y2, y3 mV [y1 > 0; y2 > 0] @@ -229,7 +278,7 @@ parser grammar PyNestMLParser; @attribute declaration: A list of corresponding declarations. */ blockWithVariables: - blockType=(STATE_KEYWORD | PARAMETERS_KEYWORD | INTERNALS_KEYWORD | INITIAL_VALUES_KEYWORD) + blockType=(STATE_KEYWORD | PARAMETERS_KEYWORD | INTERNALS_KEYWORD) COLON (declaration | NEWLINE)* END_KEYWORD; @@ -246,7 +295,7 @@ parser grammar PyNestMLParser; block END_KEYWORD; - /** ASTEquationsBlock A block declaring special functions: + /** ASTEquationsBlock A block declaring equations, kernels and inline expressions: equations: G = (e/tau_syn) * t * exp(-1/tau_syn*t) V' = -1/Tau * V + 1/C_m * (convolve(G, spikes) + I_e + I_stim) @@ -261,8 +310,8 @@ parser grammar PyNestMLParser; /** ASTInputBlock represents a single input block, e.g.: input: - spikeBuffer <- excitatory spike - currentBuffer pA <- current + spike_in <- excitatory spike + current_in pA <- continuous end @attribute inputPort: A list of input ports. */ @@ -271,20 +320,20 @@ parser grammar PyNestMLParser; END_KEYWORD; /** ASTInputPort represents a single input port, e.g.: - spikeBuffer type <- excitatory spike + spike_in <- excitatory spike @attribute name: The name of the input port. @attribute sizeParameter: Optional size parameter for multisynapse neuron. - @attribute datatype: Optional data type of the buffer. + @attribute datatype: Optional data type of the port. @attribute inputQualifier: The qualifier keyword of the input port, to indicate e.g. inhibitory-only or excitatory-only spiking inputs on this port. @attribute isSpike: Indicates that this input port accepts spikes. - @attribute isCurrent: Indicates that this input port accepts current generator input. + @attribute isContinuous: Indicates that this input port accepts continuous-time input. */ inputPort: name=NAME (LEFT_SQUARE_BRACKET sizeParameter=NAME RIGHT_SQUARE_BRACKET)? (dataType)? LEFT_ANGLE_MINUS inputQualifier* - (isCurrent = CURRENT_KEYWORD | isSpike = SPIKE_KEYWORD); + (isContinuous = CONTINUOUS_KEYWORD | isSpike = SPIKE_KEYWORD); /** ASTInputQualifier represents the qualifier of an inputPort. Only valid for spiking inputs. @attribute isInhibitory: Indicates that this spiking input port is inhibitory. @@ -292,12 +341,12 @@ parser grammar PyNestMLParser; */ inputQualifier : (isInhibitory=INHIBITORY_KEYWORD | isExcitatory=EXCITATORY_KEYWORD); - /** ASTOutputBlock Represents the output block of the neuron,i.e., declarations of output buffers: + /** ASTOutputBlock Represents the output block of the neuron, i.e., declarations of output ports: output: spike - @attribute isSpike: true iff the neuron has a spike output. - @attribute isCurrent: true iff. the neuron is a current output. + @attribute isSpike: true if and only if the neuron has a spike output. + @attribute isContinuous: true if and only if the neuron has a continuous-time output. */ - outputBlock: OUTPUT_KEYWORD COLON (isSpike=SPIKE_KEYWORD | isCurrent=CURRENT_KEYWORD) ; + outputBlock: OUTPUT_KEYWORD COLON (isSpike=SPIKE_KEYWORD | isContinuous=CONTINUOUS_KEYWORD) ; /** ASTFunction A single declaration of a user-defined function definition: function set_V_m(v mV): @@ -305,7 +354,7 @@ parser grammar PyNestMLParser; end @attribute name: The name of the function. @attribute parameters: List with function parameters. - @attribute returnType: An arbitrary return type, e.g. String or mV. + @attribute returnType: An arbitrary return type, e.g. string or mV. @attribute block: Implementation of the function. */ function: FUNCTION_KEYWORD NAME LEFT_PAREN (parameter (COMMA parameter)*)? RIGHT_PAREN (returnType=dataType)? @@ -320,3 +369,12 @@ parser grammar PyNestMLParser; */ parameter : NAME dataType; + /** ASTConstParameter represents a single parameter consisting of a name and a literal default value, e.g. "foo=42". + @attribute name: The name of the parameter. + @attribute value: The corresponding default value. + */ + constParameter : name=NAME EQUALS value=(BOOLEAN_LITERAL + | UNSIGNED_INTEGER + | FLOAT + | STRING_LITERAL + | INF_KEYWORD); diff --git a/pynestml/grammars/generate_lexer_parser b/pynestml/grammars/generate_lexer_parser index 14ae240f3..6f695a202 100755 --- a/pynestml/grammars/generate_lexer_parser +++ b/pynestml/grammars/generate_lexer_parser @@ -22,5 +22,4 @@ # Do not change the position of this file! In order to generate the corresponding code into `pynestml/generated`, this script has to be executed from `pynestml/grammars`. -antlr4 -Dlanguage=Python2 *.g4 -visitor -no-listener -o ../generated - +antlr4 -Dlanguage=Python3 *.g4 -visitor -no-listener -o ../generated diff --git a/pynestml/meta_model/__init__.py b/pynestml/meta_model/__init__.py index 28d49803b..a96344eaf 100644 --- a/pynestml/meta_model/__init__.py +++ b/pynestml/meta_model/__init__.py @@ -24,7 +24,6 @@ 'ast_bit_operator', 'ast_block', 'ast_block_with_variables', - 'ast_body', 'ast_comparison_operator', 'ast_compound_stmt', 'ast_data_type', @@ -45,17 +44,20 @@ 'ast_logical_operator', 'ast_nestml_compilation_unit', 'ast_neuron', + 'ast_neuron_or_synapse_body', 'ast_node', 'ast_node_factory', 'ast_ode_equation', 'ast_inline_expression', 'ast_kernel', + 'ast_on_receive_block', 'ast_output_block', 'ast_parameter', 'ast_return_stmt', 'ast_simple_expression', 'ast_small_stmt', 'ast_stmt', + 'ast_synapse', 'ast_unary_operator', 'ast_unit_type', 'ast_update_block', diff --git a/pynestml/meta_model/ast_bit_operator.py b/pynestml/meta_model/ast_bit_operator.py index 1d78ca1fb..0f098159d 100644 --- a/pynestml/meta_model/ast_bit_operator.py +++ b/pynestml/meta_model/ast_bit_operator.py @@ -104,5 +104,5 @@ def equals(self, other): if not isinstance(other, ASTBitOperator): return False return (self.is_bit_and == other.is_bit_and and self.is_bit_or == other.is_bit_or - and self.is_bit_xor == other.is_bit_xor and self.is_bit_shift_left == self.is_bit_shift_left + and self.is_bit_xor == other.is_bit_xor and self.is_bit_shift_left == other.is_bit_shift_left and self.is_bit_shift_right == other.is_bit_shift_right) diff --git a/pynestml/meta_model/ast_block_with_variables.py b/pynestml/meta_model/ast_block_with_variables.py index 8fcddf0b7..ef44e4438 100644 --- a/pynestml/meta_model/ast_block_with_variables.py +++ b/pynestml/meta_model/ast_block_with_variables.py @@ -36,7 +36,7 @@ class ASTBlockWithVariables(ASTNode): attribute AliasDecl: a list with variable declarations Grammar: blockWithVariables: - blockType=('state'|'parameters'|'internals'|'initial_values') + blockType=('state'|'parameters'|'internals') BLOCK_OPEN (declaration | NEWLINE)* BLOCK_CLOSE; @@ -44,11 +44,10 @@ class ASTBlockWithVariables(ASTNode): is_state = False is_parameters = False is_internals = False - is_initial_values = False declarations = None """ - def __init__(self, is_state=False, is_parameters=False, is_internals=False, is_initial_values=False, + def __init__(self, is_state=False, is_parameters=False, is_internals=False, declarations=None, *args, **kwargs): """ Standard constructor. @@ -61,22 +60,19 @@ def __init__(self, is_state=False, is_parameters=False, is_internals=False, is_i :type is_parameters: bool :param is_internals: is an internals block. :type is_internals: bool - :param is_initial_values: is an initial values block. - :type is_initial_values: bool :param declarations: a list of declarations. :type declarations: List[ASTDeclaration] """ super(ASTBlockWithVariables, self).__init__(*args, **kwargs) - assert (is_internals or is_parameters or is_state or is_initial_values), \ + assert (is_internals or is_parameters or is_state), \ '(PyNESTML.AST.BlockWithVariables) Type of variable block specified!' - assert ((is_internals + is_parameters + is_state + is_initial_values) == 1), \ + assert ((is_internals + is_parameters + is_state) == 1), \ '(PyNestML.AST.BlockWithVariables) Type of block ambiguous!' assert (declarations is None or isinstance(declarations, list)), \ '(PyNESTML.AST.BlockWithVariables) Wrong type of declaration provided (%s)!' % type(declarations) self.declarations = declarations self.is_internals = is_internals self.is_parameters = is_parameters - self.is_initial_values = is_initial_values self.is_state = is_state def clone(self): @@ -92,7 +88,6 @@ def clone(self): dup = ASTBlockWithVariables(declarations=declarations_dup, is_internals=self.is_internals, is_parameters=self.is_parameters, - is_initial_values=self.is_initial_values, is_state=self.is_state, # ASTNode common attriutes: source_position=self.source_position, @@ -145,9 +140,9 @@ def equals(self, other=None): """ if not isinstance(other, ASTBlockWithVariables): return False - if not (self.is_initial_values == other.is_initial_values - and self.is_internals == other.is_internals - and self.is_parameters == other.is_parameters and self.is_state == other.is_state): + if not (self.is_internals == other.is_internals + and self.is_parameters == other.is_parameters + and self.is_state == other.is_state): return False if len(self.get_declarations()) != len(other.get_declarations()): return False diff --git a/pynestml/meta_model/ast_declaration.py b/pynestml/meta_model/ast_declaration.py index b0aa807b2..8f7760ca8 100644 --- a/pynestml/meta_model/ast_declaration.py +++ b/pynestml/meta_model/ast_declaration.py @@ -21,17 +21,21 @@ from typing import Optional, List +import copy + from pynestml.meta_model.ast_data_type import ASTDataType from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.meta_model.ast_namespace_decorator import ASTNamespaceDecorator class ASTDeclaration(ASTNode): """ This class is used to store declarations. ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: - 'a,b,c real = 0'. Or an function declaration 'function a = b + c'. + 'a,b,c real = 0'. + @attribute hide is true iff. declaration is not traceable. @attribute function is true iff. declaration is an function. @attribute vars List with variables @attribute Datatype Obligatory data type, e.g. 'real' or 'mV/s' @@ -48,7 +52,7 @@ class ASTDeclaration(ASTNode): ('[[' invariant=rhs ']]')?; Attributes: is_recordable = False - is_function = False + is_inline_expression = False variables = None data_type = None size_parameter = None @@ -56,38 +60,34 @@ class ASTDeclaration(ASTNode): invariant = None """ - def __init__(self, is_recordable: bool = False, is_function: bool = False, _variables: Optional[List[ASTVariable]] = None, data_type: Optional[ASTDataType] = None, size_parameter: Optional[str] = None, - expression: Optional[ASTExpression] = None, invariant: Optional[ASTExpression] = None, *args, **kwargs): + def __init__(self, is_recordable: bool = False, is_inline_expression: bool = False, _variables: Optional[List[ASTVariable]] = None, data_type: Optional[ASTDataType] = None, size_parameter: Optional[str] = None, + expression: Optional[ASTExpression] = None, invariant: Optional[ASTExpression] = None, decorators=None, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param is_recordable: is a recordable declaration. - :type is_recordable: bool - :param is_function: is a function declaration. - :type is_function: bool + :param is_inline_expression: is a function declaration. :param _variables: a list of variables. - :type _variables: Optional[List[ASTVariable]] :param data_type: the data type. - :type data_type: Optional[ASTDataType] :param size_parameter: an optional size parameter. - :type size_parameter: Optional[str] :param expression: an optional right-hand side rhs. - :type expression: ASTExpression :param invariant: a optional invariant. - :type invariant: ASTExpression """ super(ASTDeclaration, self).__init__(*args, **kwargs) self.is_recordable = is_recordable - self.is_function = is_function + self.is_inline_expression = is_inline_expression if _variables is None: _variables = [] + if decorators is None: + decorators = [] self.variables = _variables self.data_type = data_type self.size_parameter = size_parameter self.expression = expression self.invariant = invariant + self.decorators = decorators def clone(self): """ @@ -108,13 +108,17 @@ def clone(self): invariant_dup = None if self.invariant: invariant_dup = self.invariant.clone() + decorators_dup = None + if self.decorators: + decorators_dup = [dec.clone() for dec in self.decorators] dup = ASTDeclaration(is_recordable=self.is_recordable, - is_function=self.is_function, + is_inline_expression=self.is_inline_expression, _variables=variables_dup, data_type=data_type_dup, size_parameter=self.size_parameter, expression=expression_dup, invariant=invariant_dup, + decorators=decorators_dup, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -134,6 +138,11 @@ def get_variables(self): """ return self.variables + def get_decorators(self): + """ + """ + return self.decorators + def get_data_type(self): """ Returns the data type. @@ -243,7 +252,7 @@ def equals(self, other): """ if not isinstance(other, ASTDeclaration): return False - if not (self.is_function == other.is_function and self.is_recordable == other.is_recordable): + if not (self.is_inline_expression == other.is_inline_expression and self.is_recordable == other.is_recordable): return False if self.get_size_parameter() != other.get_size_parameter(): return False diff --git a/pynestml/meta_model/ast_equations_block.py b/pynestml/meta_model/ast_equations_block.py index 5e84b013f..49ea11aba 100644 --- a/pynestml/meta_model/ast_equations_block.py +++ b/pynestml/meta_model/ast_equations_block.py @@ -19,6 +19,8 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Any, Sequence + from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_ode_equation import ASTOdeEquation from pynestml.meta_model.ast_inline_expression import ASTInlineExpression @@ -108,11 +110,10 @@ def get_parent(self, ast): return decl.get_parent(ast) return None - def get_ode_equations(self): + def get_ode_equations(self) -> Sequence[ASTOdeEquation]: """ Returns a list of all ode equations in this block. :return: a list of all ode equations. - :rtype: list(ASTOdeEquations) """ ret = list() for decl in self.get_declarations(): @@ -120,11 +121,10 @@ def get_ode_equations(self): ret.append(decl) return ret - def get_kernels(self): + def get_kernels(self) -> Sequence[ASTKernel]: """ Returns a list of all kernels in this block. :return: a list of all kernels. - :rtype: list(ASTKernel) """ ret = list() for decl in self.get_declarations(): @@ -132,11 +132,10 @@ def get_kernels(self): ret.append(decl) return ret - def get_inline_expressions(self): + def get_inline_expressions(self) -> Sequence[ASTInlineExpression]: """ Returns a list of all inline expressions in this block. :return: a list of all inline expressions. - :rtype: list(ASTInlineExpression) """ ret = list() for decl in self.get_declarations(): @@ -151,13 +150,11 @@ def clear(self): del self.declarations self.declarations = list() - def equals(self, other): + def equals(self, other: Any) -> bool: """ The equals method. :param other: a different object. - :type other: object :return: True if equal, otherwise False. - :rtype: bool """ if not isinstance(other, ASTEquationsBlock): return False diff --git a/pynestml/meta_model/ast_expression.py b/pynestml/meta_model/ast_expression.py index d51eb4a02..4fa861bc1 100644 --- a/pynestml/meta_model/ast_expression.py +++ b/pynestml/meta_model/ast_expression.py @@ -18,12 +18,15 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from __future__ import annotations +from typing import Union from pynestml.meta_model.ast_expression_node import ASTExpressionNode from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_bit_operator import ASTBitOperator from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator +from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator class ASTExpression(ASTExpressionNode): @@ -61,41 +64,31 @@ class ASTExpression(ASTExpressionNode): simple_expression = None """ - def __init__(self, is_encapsulated=False, unary_operator=None, is_logical_not=False, - expression=None, lhs=None, binary_operator=None, rhs=None, condition=None, if_true=None, - if_not=None, *args, **kwargs): + def __init__(self, is_encapsulated: bool = False, unary_operator: ASTUnaryOperator = None, + is_logical_not: bool = False, expression: ASTExpression = None, lhs: ASTExpression = None, + binary_operator: Union[ASTLogicalOperator, ASTComparisonOperator, ASTBitOperator, + ASTArithmeticOperator] = None, + rhs: ASTExpression = None, condition: ASTExpression = None, if_true: ASTExpression = None, + if_not: ASTExpression = None, has_delay: bool = False, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param is_encapsulated: is encapsulated in brackets. - :type is_encapsulated: bool :param unary_operator: combined by unary operator, e.g., ~. - :type unary_operator: ASTUnaryOperator :param is_logical_not: is a negated rhs. - :type is_logical_not: bool - :param expression: the rhs either encapsulated in brackets or negated or with a with a unary op, or a simple rhs. - :type expression: ASTExpression + :param expression: the rhs either encapsulated in brackets or negated or with a with a unary op, or a simple + rhs. :param lhs: the left-hand side rhs. - :type lhs: ASTExpression :param binary_operator: a binary operator, e.g., a comparison operator or a logical operator. - :type binary_operator: ASTLogicalOperator,ASTComparisonOperator,ASTBitOperator,ASTArithmeticOperator :param rhs: the right-hand side rhs - :type rhs: ASTExpression :param condition: the condition of a ternary operator - :type condition: ASTExpression :param if_true: if condition holds, this rhs is executed. - :type if_true: ASTExpression :param if_not: if condition does not hold, this rhs is executed. - :type if_not: ASTExpression + :param has_delay: if this expression has a delay variable """ super(ASTExpression, self).__init__(*args, **kwargs) - assert ((binary_operator is None) or (isinstance(binary_operator, ASTArithmeticOperator) - or isinstance(binary_operator, ASTBitOperator) - or isinstance(binary_operator, ASTLogicalOperator) - or isinstance(binary_operator, ASTComparisonOperator))), \ - '(PyNestML.AST.Expression) Wrong type of binary operator provided (%s)!' % type(binary_operator) self.is_encapsulated = is_encapsulated self.is_logical_not = is_logical_not self.unary_operator = unary_operator @@ -108,6 +101,7 @@ def __init__(self, is_encapsulated=False, unary_operator=None, is_logical_not=Fa self.condition = condition self.if_true = if_true self.if_not = if_not + self.has_delay = has_delay def clone(self): """ @@ -150,6 +144,7 @@ def clone(self): condition=condition_dup, if_true=if_true_dup, if_not=if_not_dup, + has_delay=self.has_delay, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -255,6 +250,13 @@ def get_if_not(self): """ return self.if_not + def get_has_delay(self): + """ + Returns the has_delay parameter + :return: + """ + return self.has_delay + def get_variables(self): """ Returns a list of all variables as used in this rhs. @@ -392,6 +394,9 @@ def equals(self, other): return False if self.is_ternary_operator() and other.is_ternary_operator() and \ not (self.get_condition().equals(other.get_condition()) - and self.get_if_true().equals(other.get_if_true()) and self.get_if_not().equals(other.get_if_not())): + and self.get_if_true().equals(other.get_if_true()) + and self.get_if_not().equals(other.get_if_not())): + return False + if self.get_has_delay() + other.get_has_delay() == 1: return False return True diff --git a/pynestml/meta_model/ast_external_variable.py b/pynestml/meta_model/ast_external_variable.py new file mode 100644 index 000000000..a929c608f --- /dev/null +++ b/pynestml/meta_model/ast_external_variable.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# +# ast_external_variable.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Optional + +from copy import copy + +from pynestml.meta_model.ast_variable import ASTVariable + + +class ASTExternalVariable(ASTVariable): + r""" + This class is used to store a single "external" variable: a variable the value of which is obtained during runtime from a neuron's postsynaptic partner. + """ + _altscope = None + _altname = None + + def __init__(self, name, altname=None, altscope=None, *args, **kwargs): + r""" + Standard constructor. + """ + super(ASTExternalVariable, self).__init__(name, *args, **kwargs) + self._altname = altname + self._altscope = altscope + + def clone(self): + r""" + Return a clone ("deep copy") of this node. + """ + return ASTExternalVariable(altname=self._altname, + altscape=self._altscope, + # ASTVariable attributes: + name=self.name, + differential_order=self.differential_order, + type_symbol=self.type_symbol, + vector_parameter=self.vector_parameter, + # ASTNode common attributes: + source_position=self.get_source_position(), + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + post_comments=[s for s in self.post_comments], + implicit_conversion_factor=self.implicit_conversion_factor) + + def update_alt_scope(self, scope): + self._altscope = scope + + def set_alternate_name(self, alternate_name: Optional[str]): + self._altname = alternate_name + + def get_alternate_name(self): + return self._altname + + def get_scope(self): + if self._altscope: + return self._altscope.get_scope() + return self.scope diff --git a/pynestml/meta_model/ast_for_stmt.py b/pynestml/meta_model/ast_for_stmt.py index db436337b..d5d47cfa6 100644 --- a/pynestml/meta_model/ast_for_stmt.py +++ b/pynestml/meta_model/ast_for_stmt.py @@ -69,7 +69,7 @@ def clone(self): """ variable_dup = None if self.variable: - variable_dup = self.variable.clone() + variable_dup = self.variable start_from_dup = None if self.start_from: start_from_dup = self.start_from.clone() @@ -78,7 +78,7 @@ def clone(self): end_at_dup = self.end_at.clone() step_dup = None if self.step: - step_dup = self.step.clone() + step_dup = self.step block_dup = None if self.block: block_dup = self.block.clone() diff --git a/pynestml/meta_model/ast_function.py b/pynestml/meta_model/ast_function.py index 8449b5f45..7c6aa3861 100644 --- a/pynestml/meta_model/ast_function.py +++ b/pynestml/meta_model/ast_function.py @@ -19,9 +19,14 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import List, Optional + from copy import copy +from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_data_type import ASTDataType from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_parameter import ASTParameter class ASTFunction(ASTNode): @@ -50,20 +55,16 @@ class ASTFunction(ASTNode): type_symbol = None """ - def __init__(self, name, parameters, return_type, block, type_symbol=None, *args, **kwargs): + def __init__(self, name: str, parameters: List[ASTParameter], return_type: Optional[ASTDataType], block: ASTBlock, type_symbol=None, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param name: the name of the defined function. - :type name: str :param parameters: (Optional) Set of parameters. - :type parameters: List[ASTParameter] :param return_type: (Optional) Return type. - :type return_type: ASTDataType :param block: a block of declarations. - :type block: ASTBlock """ super(ASTFunction, self).__init__(*args, **kwargs) self.block = block @@ -86,8 +87,7 @@ def clone(self): if self.return_type: return_type_dup = self.return_type.clone() parameters_dup = None - if self.parameters: - parameters_dup = [parameter.clone() for parameter in self.parameters] + parameters_dup = [parameter.clone() for parameter in self.parameters] dup = ASTFunction(name=self.name, parameters=parameters_dup, return_type=return_type_dup, @@ -112,19 +112,17 @@ def get_name(self): """ return self.name - def has_parameters(self): + def has_parameters(self) -> bool: """ Returns whether parameters have been defined. :return: True if parameters defined, otherwise False. - :rtype: bool """ - return (self.parameters is not None) and (len(self.parameters) > 0) + return len(self.parameters) > 0 - def get_parameters(self): + def get_parameters(self) -> List[ASTParameter]: """ Returns the list of parameters. :return: a parameters object containing the list. - :rtype: list(ASTParameter) """ return self.parameters diff --git a/pynestml/meta_model/ast_inline_expression.py b/pynestml/meta_model/ast_inline_expression.py index 97ff34491..8182c8015 100644 --- a/pynestml/meta_model/ast_inline_expression.py +++ b/pynestml/meta_model/ast_inline_expression.py @@ -94,6 +94,13 @@ def get_variable_name(self): """ return self.variable_name + def set_variable_name(self, variable_name: str): + """ + Set the variable name. + :param variable_name: the name of the variable. + """ + self.variable_name = variable_name + def get_data_type(self): """ Returns the data type as an object of ASTDatatype. diff --git a/pynestml/meta_model/ast_input_block.py b/pynestml/meta_model/ast_input_block.py index 0a7f2be69..40ecdcb6e 100644 --- a/pynestml/meta_model/ast_input_block.py +++ b/pynestml/meta_model/ast_input_block.py @@ -27,10 +27,13 @@ class ASTInputBlock(ASTNode): """ This class is used to store blocks of input definitions. ASTInputBlock represents the input block, e.g.: - input: - spikeBuffer pA <- excitatory spike - currentBuffer pA <- current - end + + .. code-block:: nestml + + input: + spike_in pA <- excitatory spike + current_in pA <- continuous + end @attribute inputPort set of input ports. Grammar: diff --git a/pynestml/meta_model/ast_input_port.py b/pynestml/meta_model/ast_input_port.py index d9e4409fd..e50937103 100644 --- a/pynestml/meta_model/ast_input_port.py +++ b/pynestml/meta_model/ast_input_port.py @@ -19,6 +19,10 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from __future__ import annotations + +from typing import Any, List, Optional + from pynestml.meta_model.ast_data_type import ASTDataType from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier from pynestml.meta_model.ast_node import ASTNode @@ -26,17 +30,20 @@ class ASTInputPort(ASTNode): - """ + r""" This class is used to store a declaration of an input port. ASTInputPort represents a single input port, e.g.: - spikeBuffer type <- excitatory spike + + .. code-block:: nestml + + spike_in pA <- excitatory spike @attribute name: The name of the input port. @attribute sizeParameter: Optional size parameter for multisynapse neuron. - @attribute datatype: Optional data type of the buffer. + @attribute datatype: Optional data type of the port. @attribute inputQualifier: The qualifier keyword of the input port, to indicate e.g. inhibitory-only or excitatory-only spiking inputs on this port. @attribute isSpike: Indicates that this input port accepts spikes. - @attribute isCurrent: Indicates that this input port accepts current generator input. + @attribute isContinuous: Indicates that this input port accepts continuous time input. Grammar: inputPort: @@ -44,65 +51,51 @@ class ASTInputPort(ASTNode): (LEFT_SQUARE_BRACKET sizeParameter=NAME RIGHT_SQUARE_BRACKET)? (dataType)? LEFT_ANGLE_MINUS inputQualifier* - (isCurrent = CURRENT_KEYWORD | isSpike = SPIKE_KEYWORD); + (isContinuous = CONTINUOUS_KEYWORD | isSpike = SPIKE_KEYWORD); """ - def __init__(self, name=None, size_parameter=None, data_type=None, input_qualifiers=None, signal_type=None, + def __init__(self, + name: str, + signal_type: PortSignalType, + size_parameter: Optional[str] = None, + data_type: Optional[ASTDataType] = None, + input_qualifiers: Optional[List[ASTInputQualifier]] = None, *args, **kwargs): - """ + r""" Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param name: the name of the port - :type name: str :param size_parameter: a parameter indicating the index in an array. - :type size_parameter: str - :param data_type: the data type of this buffer - :type data_type: ASTDataType + :param data_type: the data type of this input port :param input_qualifiers: a list of input qualifiers for this port. - :type input_qualifiers: list(ASTInputQualifier) - :param signal_type: type of signal received, i.e., spikes or currents - :type signal_type: SignalType + :param signal_type: type of signal received, i.e., spikes or continuous """ super(ASTInputPort, self).__init__(*args, **kwargs) - assert name is not None and isinstance(name, str), \ - '(PyNestML.ASTInputPort) No or wrong type of name provided (%s)!' % type(name) - assert signal_type is not None and isinstance(signal_type, PortSignalType), \ - '(PyNestML.ASTInputPort) No or wrong type of input signal type provided (%s)!' % type(signal_type) if input_qualifiers is None: input_qualifiers = [] - assert input_qualifiers is not None and isinstance(input_qualifiers, list), \ - '(PyNestML.ASTInputPort) No or wrong type of input qualifiers provided (%s)!' % type(input_qualifiers) - for qual in input_qualifiers: - assert qual is not None and isinstance(qual, ASTInputQualifier), \ - '(PyNestML.ASTInputPort) No or wrong type of input qualifier provided (%s)!' % type(qual) - assert size_parameter is None or isinstance(size_parameter, str), \ - '(PyNestML.ASTInputPort) Wrong type of index parameter provided (%s)!' % type(size_parameter) - assert data_type is None or isinstance(data_type, ASTDataType), \ - '(PyNestML.ASTInputPort) Wrong type of data-type provided (%s)!' % type(data_type) + self.name = name self.signal_type = signal_type - self.input_qualifiers = input_qualifiers self.size_parameter = size_parameter - self.name = name self.data_type = data_type + self.input_qualifiers = input_qualifiers - def clone(self): - """ + def clone(self) -> ASTInputPort: + r""" Return a clone ("deep copy") of this node. :return: new AST node instance - :rtype: ASTInputPort """ data_type_dup = None if self.data_type: data_type_dup = self.data_type.clone() dup = ASTInputPort(name=self.name, + signal_type=self.signal_type, size_parameter=self.size_parameter, data_type=data_type_dup, input_qualifiers=[input_qualifier.clone() for input_qualifier in self.input_qualifiers], - signal_type=self.signal_type, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -114,68 +107,60 @@ def clone(self): return dup - def get_name(self): - """ - Returns the name of the declared buffer. + def get_name(self) -> str: + r""" + Returns the name of the declared input port. :return: the name. - :rtype: str """ return self.name - def has_index_parameter(self): - """ + def has_index_parameter(self) -> bool: + r""" Returns whether a index parameter has been defined. :return: True if index has been used, otherwise False. - :rtype: bool """ return self.size_parameter is not None - def get_index_parameter(self): - """ + def get_index_parameter(self) -> str: + r""" Returns the index parameter. :return: the index parameter. - :rtype: str """ return self.size_parameter - def has_input_qualifiers(self): - """ + def has_input_qualifiers(self) -> bool: + r""" Returns whether input qualifiers have been defined. :return: True, if at least one input qualifier has been defined. - :rtype: bool """ return len(self.input_qualifiers) > 0 - def get_input_qualifiers(self): - """ + def get_input_qualifiers(self) -> List[ASTInputQualifier]: + r""" Returns the list of input qualifiers. :return: a list of input qualifiers. - :rtype: list(ASTInputQualifier) """ return self.input_qualifiers - def is_spike(self): - """ - Returns whether this is a spike buffer or not. - :return: True if spike buffer, False else. - :rtype: bool + def is_spike(self) -> bool: + r""" + Returns whether this is a spiking input port or not. + :return: True if spike input port, False otherwise. """ return self.signal_type is PortSignalType.SPIKE - def is_current(self): - """ - Returns whether this is a current buffer or not. - :return: True if current buffer, False else. - :rtype: bool + def is_continuous(self) -> bool: + r""" + Returns whether this is a continous time port or not. + :return: True if continuous time, False otherwise. """ - return self.signal_type is PortSignalType.CURRENT + return self.signal_type is PortSignalType.CONTINUOUS - def is_excitatory(self): - """ - Returns whether this buffer is excitatory or not. For this, it has to be marked explicitly by the + def is_excitatory(self) -> bool: + r""" + Returns whether this port is excitatory or not. For this, it has to be marked explicitly by the excitatory keyword or no keywords at all shall occur (implicitly all types). :return: True if excitatory, False otherwise. - :rtype: bool """ if self.get_input_qualifiers() is not None and len(self.get_input_qualifiers()) == 0: return True @@ -184,12 +169,11 @@ def is_excitatory(self): return True return False - def is_inhibitory(self): - """ - Returns whether this buffer is inhibitory or not. For this, it has to be marked explicitly by the + def is_inhibitory(self) -> bool: + r""" + Returns whether this port is inhibitory or not. For this, it has to be marked explicitly by the inhibitory keyword or no keywords at all shall occur (implicitly all types). :return: True if inhibitory, False otherwise. - :rtype: bool """ if self.get_input_qualifiers() is not None and len(self.get_input_qualifiers()) == 0: return True @@ -199,28 +183,24 @@ def is_inhibitory(self): return False def has_datatype(self): - """ - Returns whether this buffer has a defined data type or not. + r""" + Returns whether this port has a defined data type or not. :return: True if it has a datatype, otherwise False. - :rtype: bool """ return self.data_type is not None and isinstance(self.data_type, ASTDataType) - def get_datatype(self): - """ - Returns the currently used data type of this buffer. + def get_datatype(self) -> ASTDataType: + r""" + Returns the currently used data type of this port. :return: a single data type object. - :rtype: ASTDataType """ return self.data_type - def get_parent(self, ast): - """ + def get_parent(self, ast: ASTNode) -> Optional[ASTNode]: + r""" Indicates whether a this node contains the handed over node. :param ast: an arbitrary meta_model node. - :type ast: AST_ :return: AST if this or one of the child nodes contains the handed over element. - :rtype: AST_ or None """ if self.has_datatype(): if self.get_datatype() is ast: @@ -234,13 +214,11 @@ def get_parent(self, ast): return qual.get_parent(ast) return None - def equals(self, other): - """ + def equals(self, other: Any) -> bool: + r""" The equals method. :param other: a different object. - :type other: object :return: True if equal,otherwise False. - :rtype: bool """ if not isinstance(other, ASTInputPort): return False @@ -262,4 +240,4 @@ def equals(self, other): for i in range(0, len(my_input_qualifiers)): if not my_input_qualifiers[i].equals(your_input_qualifiers[i]): return False - return self.is_spike() == other.is_spike() and self.is_current() == other.is_current() + return self.is_spike() == other.is_spike() and self.is_continuous() == other.is_continuous() diff --git a/pynestml/meta_model/ast_namespace_decorator.py b/pynestml/meta_model/ast_namespace_decorator.py new file mode 100644 index 000000000..8de80a5ee --- /dev/null +++ b/pynestml/meta_model/ast_namespace_decorator.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# +# ast_namespace_decorator.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.meta_model.ast_node import ASTNode +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.meta_model.ast_variable import ASTVariable + + +class ASTNamespaceDecorator(ASTNode): + """ + """ + + def __init__(self, namespace=None, name=None, *args, **kwargs): + """ + """ + super(ASTNamespaceDecorator, self).__init__(*args, **kwargs) + self.namespace = namespace + self.name = name + + def clone(self): + """ + Return a clone ("deep copy") of this node. + + :return: new AST node instance + :rtype: ASTExpression + """ + dup = ASTNamespaceDecorator(namespace=self.namespace, + name=self.name, + # ASTNode common attributes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + post_comments=[s for s in self.post_comments], + implicit_conversion_factor=self.implicit_conversion_factor) + + return dup + + def get_namespace(self): + """ + Returns the left-hand side variable. + :return: left-hand side variable object. + :rtype: ASTVariable + """ + return self.namespace + + def get_name(self): + """ + Returns the right-hand side rhs. + :return: rhs object. + :rtype: ast_expression + """ + return self.name + + def get_parent(self, ast): + """ + Indicates whether a this node contains the handed over node. + :param ast: an arbitrary meta_model node. + :type ast: AST_ + :return: AST if this or one of the child nodes contains the handed over element. + :rtype: AST_ or None + """ + if self.get_name() is ast: + return self + elif self.get_namespace() is ast: + return self + return None + + def equals(self, other): + """ + The equals operation. + :param other: a different object. + :type other: object + :return: True if equal, otherwise False. + :rtype: bool + """ + if not isinstance(other, ASTNamespaceDecorator): + return False + return (self.get_name().equals(other.get_name()) + and self.get_namespace().equals(other.get_namespace())) diff --git a/pynestml/meta_model/ast_nestml_compilation_unit.py b/pynestml/meta_model/ast_nestml_compilation_unit.py index 3f339df5a..fa157646f 100644 --- a/pynestml/meta_model/ast_nestml_compilation_unit.py +++ b/pynestml/meta_model/ast_nestml_compilation_unit.py @@ -19,7 +19,9 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Optional from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_node import ASTNode @@ -33,7 +35,7 @@ class ASTNestMLCompilationUnit(ASTNode): artifact_name = None """ - def __init__(self, neuron_list=None, artifact_name=None, *args, **kwargs): + def __init__(self, neuron_list=None, synapse_list=None, artifact_name=None, *args, **kwargs): """ Standard constructor. @@ -51,6 +53,10 @@ def __init__(self, neuron_list=None, artifact_name=None, *args, **kwargs): if neuron_list is not None: assert type(neuron_list) is list self.neuron_list.extend(neuron_list) + self.synapse_list = [] + if not synapse_list is None: + assert type(synapse_list) is list + self.synapse_list.extend(synapse_list) self.artifact_name = artifact_name def clone(self): @@ -104,6 +110,54 @@ def get_neuron_list(self): """ return self.neuron_list + def add_synapse(self, synapse): + """ + Expects an instance of synapse element which is added to the collection. + :param synapse: an instance of a synapse + :type synapse: ASTsynapse + :return: no returned value + :rtype: void + """ + assert (synapse is not None and isinstance(synapse, ASTSynapse)), \ + '(PyNestML.AST.CompilationUnit) No or wrong type of synapse provided (%s)!' % type(synapse) + self.synapse_list.append(synapse) + return + + def delete_synapse(self, synapse): + """ + Expects an instance of synapse element which is deleted from the collection. + :param synapse: an instance of a ASTsynapse + :type synapse:ASTsynapse + :return: True if element deleted from list, False else. + :rtype: bool + """ + if self.synapse_list.__contains__(synapse): + self.synapse_list.remove(synapse) + return True + else: + return False + + def get_synapse_list(self): + """ + :return: a list of synapse elements as stored in the unit + :rtype: list(ASTsynapse) + """ + return self.synapse_list + + def get_neuron_by_name(self, name: str) -> Optional[ASTNeuron]: + for neuron in self.get_neuron_list(): + if neuron.get_name() == name: + return neuron + + return None + + def get_synapse_by_name(self, name: str) -> Optional[ASTSynapse]: + for synapse in self.get_synapse_list(): + if synapse.get_name() == name: + return synapse + + return None + def get_parent(self, ast): """ Indicates whether a this node contains the handed over node. @@ -117,6 +171,11 @@ def get_parent(self, ast): return self if neuron.get_parent(ast) is not None: return neuron.get_parent(ast) + for synapse in self.get_synapse_list(): + if synapse is ast: + return self + elif synapse.get_parent(ast) is not None: + return synapse.get_parent(ast) return None def equals(self, other): @@ -131,9 +190,16 @@ def equals(self, other): return False if len(self.get_neuron_list()) != len(other.get_neuron_list()): return False + if len(self.get_synapse_list()) != len(other.get_synapse_list()): + return False my_neurons = self.get_neuron_list() your_neurons = other.get_neuron_list() for i in range(0, len(my_neurons)): if not my_neurons[i].equals(your_neurons[i]): return False + my_synapses = self.get_synapse_list() + your_synapses = other.get_synapse_list() + for i in range(0, len(my_synapses)): + if not my_synapses[i].equals(your_synapses[i]): + return False return True diff --git a/pynestml/meta_model/ast_neuron.py b/pynestml/meta_model/ast_neuron.py index 06ea3282f..21b6fd249 100644 --- a/pynestml/meta_model/ast_neuron.py +++ b/pynestml/meta_model/ast_neuron.py @@ -19,22 +19,22 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import Optional, Union, List, Dict +from typing import Dict, List, Optional, Union from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_neuron_or_synapse import ASTNeuronOrSynapse from pynestml.meta_model.ast_kernel import ASTKernel -from pynestml.meta_model.ast_body import ASTBody +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody from pynestml.meta_model.ast_equations_block import ASTEquationsBlock -from pynestml.symbols.variable_symbol import BlockType -from pynestml.symbols.variable_symbol import VariableSymbol -from pynestml.utils.ast_utils import ASTUtils +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import BlockType, VariableSymbol from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages from pynestml.utils.ast_source_location import ASTSourceLocation -class ASTNeuron(ASTNode): +class ASTNeuron(ASTNeuronOrSynapse): """ This class is used to store instances of neurons. ASTNeuron represents neuron. @@ -61,16 +61,7 @@ def __init__(self, name, body, artifact_name=None, *args, **kwargs): :param artifact_name: the name of the file this neuron is contained in :type artifact_name: str """ - super(ASTNeuron, self).__init__(*args, **kwargs) - assert isinstance(name, str), \ - '(PyNestML.ASTNeuron) No or wrong type of neuron name provided (%s)!' % type(name) - assert isinstance(body, ASTBody), \ - '(PyNestML.ASTNeuron) No or wrong type of neuron body provided (%s)!' % type(body) - assert (artifact_name is not None and isinstance(artifact_name, str)), \ - '(PyNestML.ASTNeuron) No or wrong type of artifact name provided (%s)!' % type(artifact_name) - self.name = name - self.body = body - self.artifact_name = artifact_name + super(ASTNeuron, self).__init__(name, body, artifact_name, *args, **kwargs) def clone(self): """ @@ -105,7 +96,7 @@ def get_body(self): """ Return the body of the neuron. :return: the body containing the definitions. - :rtype: ASTBody + :rtype: ASTNeuronOrSynapseBody """ return self.body @@ -130,23 +121,6 @@ def get_functions(self): ret.append(elem) return ret - def get_update_blocks(self): - """ - Returns a list of all update blocks defined in this body. - :return: a list of update-block elements. - :rtype: list(ASTUpdateBlock) - """ - ret = list() - from pynestml.meta_model.ast_update_block import ASTUpdateBlock - for elem in self.get_body().get_body_elements(): - if isinstance(elem, ASTUpdateBlock): - ret.append(elem) - if isinstance(ret, list) and len(ret) == 1: - return ret[0] - if isinstance(ret, list) and len(ret) == 0: - return None - return ret - def get_state_blocks(self): """ Returns a list of all state blocks defined in this body. @@ -164,23 +138,6 @@ def get_state_blocks(self): return None return ret - def get_initial_blocks(self): - """ - Returns a list of all initial blocks defined in this body. - :return: a list of initial-blocks. - :rtype: list(ASTBlockWithVariables) - """ - ret = list() - from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables - for elem in self.get_body().get_body_elements(): - if isinstance(elem, ASTBlockWithVariables) and elem.is_initial_values: - ret.append(elem) - if isinstance(ret, list) and len(ret) == 1: - return ret[0] - if isinstance(ret, list) and len(ret) == 0: - return None - return ret - def get_parameter_blocks(self): """ Returns a list of all parameter blocks defined in this body. @@ -247,23 +204,10 @@ def remove_equations_block(self) -> None: if isinstance(elem, ASTEquationsBlock): self.get_body().get_body_elements().remove(elem) - def get_initial_values_declarations(self): - """ - Returns a list of initial values declarations made in this neuron. - :return: a list of initial values declarations - :rtype: list(ASTDeclaration) - """ - initial_values_block = self.get_initial_blocks() - initial_values_declarations = list() - if initial_values_block is not None: - for decl in initial_values_block.get_declarations(): - initial_values_declarations.append(decl) - return initial_values_declarations - def get_initial_value(self, variable_name): assert type(variable_name) is str - for decl in self.get_initial_values_blocks().get_declarations(): + for decl in self.get_state_blocks().get_declarations(): for var in decl.variables: if var.get_complete_name() == variable_name: return decl.get_expression() @@ -302,42 +246,36 @@ def get_input_blocks(self): return None return ret - def get_input_buffers(self): + def get_input_ports(self) -> List[VariableSymbol]: """ - Returns a list of all defined input buffers. - :return: a list of all input buffers. - :rtype: list(VariableSymbol) + Returns a list of all defined input ports. + :return: a list of all input ports. """ symbols = self.get_scope().get_symbols_in_this_scope() ret = list() for symbol in symbols: - if isinstance(symbol, VariableSymbol) and (symbol.block_type == BlockType.INPUT_BUFFER_SPIKE - or symbol.block_type == BlockType.INPUT_BUFFER_CURRENT): + if isinstance(symbol, VariableSymbol) and symbol.block_type == BlockType.INPUT: ret.append(symbol) return ret - def get_spike_buffers(self): + def get_spike_input_ports(self) -> List[VariableSymbol]: """ - Returns a list of all spike input buffers defined in the model. - :return: a list of all spike input buffers. - :rtype: list(VariableSymbol) + Returns a list of all spike input ports defined in the model. """ ret = list() - for BUFFER in self.get_input_buffers(): - if BUFFER.is_spike_buffer(): - ret.append(BUFFER) + for port in self.get_input_ports(): + if port.is_spike_input_port(): + ret.append(port) return ret - def get_current_buffers(self): + def get_continuous_input_ports(self) -> List[VariableSymbol]: """ - Returns a list of all current buffers defined in the model. - :return: a list of all current input buffers. - :rtype: list(VariableSymbol) + Returns a list of all continuous time input ports defined in the model. """ ret = list() - for BUFFER in self.get_input_buffers(): - if BUFFER.is_current_buffer(): - ret.append(BUFFER) + for port in self.get_input_ports(): + if port.is_continuous_input_port(): + ret.append(port) return ret def get_parameter_symbols(self): @@ -349,16 +287,15 @@ def get_parameter_symbols(self): symbols = self.get_scope().get_symbols_in_this_scope() ret = list() for symbol in symbols: - if isinstance(symbol, VariableSymbol) and symbol.block_type == BlockType.PARAMETERS and \ + if isinstance(symbol, VariableSymbol) and symbol.block_type in [BlockType.PARAMETERS, BlockType.COMMON_PARAMETERS] and \ not symbol.is_predefined: ret.append(symbol) return ret - def get_state_symbols(self): + def get_state_symbols(self) -> List[VariableSymbol]: """ Returns a list of all state symbol defined in the model. :return: a list of state symbols. - :rtype: list(VariableSymbol) """ symbols = self.get_scope().get_symbols_in_this_scope() ret = list() @@ -368,6 +305,36 @@ def get_state_symbols(self): ret.append(symbol) return ret + def get_vector_state_symbols(self) -> List[VariableSymbol]: + """ + Returns a list of all state symbols that are vectors + :return: a list of vector state symbols + """ + symbols = self.get_scope().get_symbols_in_this_scope() + vector_state_symbols = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and symbol.block_type == BlockType.STATE and \ + not symbol.is_predefined and symbol.has_vector_parameter(): + vector_state_symbols.append(symbol) + return vector_state_symbols + + def get_vector_symbols(self) -> List[VariableSymbol]: + """ + Returns a list of all the vector variables declared in State, Parameters, and Internals block + :return: a list of vector symbols + """ + symbols = self.get_scope().get_symbols_in_this_scope() + vector_symbols = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) \ + and (symbol.block_type == BlockType.STATE or symbol.block_type == BlockType.PARAMETERS + or symbol.block_type == BlockType.INTERNALS) \ + and not symbol.is_predefined \ + and symbol.has_vector_parameter(): + vector_symbols.append(symbol) + + return vector_symbols + def get_internal_symbols(self): """ Returns a list of all internals symbol defined in the model. @@ -383,19 +350,17 @@ def get_internal_symbols(self): ret.append(symbol) return ret - def get_function_symbols(self): + def get_inline_expression_symbols(self) -> List[VariableSymbol]: """ - Returns a list of all function symbols defined in the model. - :return: a list of function symbols. - :rtype: list(VariableSymbol) + Returns a list of all inline expression symbols defined in the model. + :return: a list of symbols """ - from pynestml.symbols.variable_symbol import BlockType symbols = self.get_scope().get_symbols_in_this_scope() ret = list() for symbol in symbols: if isinstance(symbol, VariableSymbol) \ - and (symbol.block_type == BlockType.EQUATION or symbol.block_type == BlockType.INITIAL_VALUES) \ - and symbol.is_function: + and (symbol.block_type == BlockType.EQUATION or symbol.block_type == BlockType.STATE) \ + and symbol.is_inline_expression: ret.append(symbol) return ret @@ -416,106 +381,36 @@ def get_output_blocks(self): return None return ret - def is_multisynapse_spikes(self): + def is_multisynapse_spikes(self) -> bool: """ - Returns whether this neuron uses multi-synapse spikes. + Returns whether this neuron uses multi-synapse inputs. :return: True if multi-synaptic, otherwise False. - :rtype: bool """ - buffers = self.get_spike_buffers() - for iBuffer in buffers: - if iBuffer.has_vector_parameter(): + ports = self.get_spike_input_ports() + for port in ports: + if port.has_vector_parameter(): return True return False - def get_multiple_receptors(self): + def get_multiple_receptors(self) -> List[VariableSymbol]: """ - Returns a list of all spike buffers which are defined as inhibitory and excitatory. - :return: a list of spike buffers variable symbols - :rtype: list(VariableSymbol) + Returns a list of all spike input ports which are defined as both inhibitory *and* excitatory at the same time. + :return: a list of spike input port variable symbols """ ret = list() - for iBuffer in self.get_spike_buffers(): - if iBuffer.is_excitatory() and iBuffer.is_inhibitory(): - if iBuffer is not None: - ret.append(iBuffer) + for port in self.get_spike_input_ports(): + if port.is_excitatory() and port.is_inhibitory(): + if port is not None: + ret.append(port) else: - code, message = Messages.get_could_not_resolve(iBuffer.get_symbol_name()) + code, message = Messages.get_could_not_resolve(port.get_symbol_name()) Logger.log_message( message=message, code=code, - error_position=iBuffer.get_source_position(), + error_position=port.get_source_position(), log_level=LoggingLevel.ERROR) return ret - def get_parameter_non_alias_symbols(self): - """ - Returns a list of all variable symbols representing non-function parameter variables. - :return: a list of variable symbols - :rtype: list(VariableSymbol) - """ - ret = list() - for param in self.get_parameter_symbols(): - if not param.is_function and not param.is_predefined: - ret.append(param) - return ret - - def get_state_non_alias_symbols(self): - """ - Returns a list of all variable symbols representing non-function state variables. - :return: a list of variable symbols - :rtype: list(VariableSymbol) - """ - ret = list() - for param in self.get_state_symbols(): - if not param.is_function and not param.is_predefined: - ret.append(param) - return ret - - def get_initial_values_non_alias_symbols(self): - ret = list() - for init in self.get_initial_values_symbols(): - if not init.is_function and not init.is_predefined: - ret.append(init) - return ret - - def get_internal_non_alias_symbols(self): - """ - Returns a list of all variable symbols representing non-function internal variables. - :return: a list of variable symbols - :rtype: list(VariableSymbol) - """ - ret = list() - for param in self.get_internal_symbols(): - if not param.is_function and not param.is_predefined: - ret.append(param) - - return ret - - def get_initial_values_symbols(self): - """ - Returns a list of all initial values symbol defined in the model. Note that the order here is the same as the - order by which the symbols are defined in the model: this is important if a particular variable is defined in - terms of another (earlier) variable. - - :return: a list of initial values symbols. - :rtype: list(VariableSymbol) - """ - - iv_blk = self.get_initial_values_blocks() - if iv_blk is None: - return [] - iv_syms = [] - symbols = self.get_scope().get_symbols_in_this_scope() - for decl in iv_blk.get_declarations(): - for var in decl.get_variables(): - _syms = [sym for sym in symbols if sym.name == var.get_complete_name()] - assert len(_syms) > 0, "Symbol by name \"" + var.get_complete_name() + \ - "\" not found in initial values block" - iv_sym = _syms[0] - iv_syms.append(iv_sym) - return iv_syms - def get_kernel_by_name(self, kernel_name: str) -> Optional[ASTKernel]: assert type(kernel_name) is str kernel_name = kernel_name.split("__X__")[0] @@ -530,12 +425,12 @@ def get_kernel_by_name(self, kernel_name: str) -> Optional[ASTKernel]: # check if defined for a higher order of differentiation for decl in self.get_equations_block().get_declarations(): - if type(decl) is ASTKernel and kernel_name in [s.replace("$", "__DOLLAR").replace("'", "") for s in decl.get_variable_names()]: + if type(decl) is ASTKernel and kernel_name in [s.replace("$", "__DOLLAR").replace("'", "") for s in + decl.get_variable_names()]: return decl return None - def get_all_kernels(self): kernels = [] for decl in self.get_equations_block().get_declarations(): @@ -543,68 +438,29 @@ def get_all_kernels(self): kernels.append(decl) return kernels - def get_initial_values_blocks(self): - """ - Returns a list of all initial blocks defined in this body. - :return: a list of initial-blocks. - :rtype: list(ASTBlockWithVariables) - """ - ret = list() - from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables - for elem in self.get_body().get_body_elements(): - if isinstance(elem, ASTBlockWithVariables) and elem.is_initial_values: - ret.append(elem) - if isinstance(ret, list) and len(ret) == 1: - return ret[0] - if isinstance(ret, list) and len(ret) == 0: - return None - return ret - - def remove_initial_blocks(self): - """ - Remove all equations blocks - """ - from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables - for elem in self.get_body().get_body_elements(): - if isinstance(elem, ASTBlockWithVariables) and elem.is_initial_values: - self.get_body().get_body_elements().remove(elem) - - def get_function_initial_values_symbols(self): - """ - Returns a list of all initial values symbols as defined in the model which are marked as functions. - :return: a list of symbols - :rtype: list(VariableSymbol) - """ - ret = list() - for symbol in self.get_initial_values_symbols(): - if symbol.is_function: - ret.append(symbol) - return ret - - def get_non_function_initial_values_symbols(self): + def get_non_inline_state_symbols(self) -> List[VariableSymbol]: """ - Returns a list of all initial values symbols as defined in the model which are not marked as functions. + Returns a list of all state symbols as defined in the model which are not marked as inline expressions. :return: a list of symbols - :rtype:list(VariableSymbol) """ ret = list() - for symbol in self.get_initial_values_symbols(): - if not symbol.is_function: + for symbol in self.get_state_symbols(): + if not symbol.is_inline_expression: ret.append(symbol) return ret def get_ode_defined_symbols(self): """ - Returns a list of all variable symbols which have been defined in th initial_values blocks + Returns a list of all variable symbols which have been defined in th state blocks and are provided with an ode. - :return: a list of initial value variables with odes + :return: a list of state variables with odes :rtype: list(VariableSymbol) """ symbols = self.get_scope().get_symbols_in_this_scope() ret = list() for symbol in symbols: if isinstance(symbol, VariableSymbol) and \ - symbol.block_type == BlockType.INITIAL_VALUES and symbol.is_ode_defined() \ + symbol.block_type == BlockType.STATE and symbol.is_ode_defined() \ and not symbol.is_predefined: ret.append(symbol) return ret @@ -624,18 +480,29 @@ def get_state_symbols_without_ode(self): ret.append(symbol) return ret - def is_array_buffer(self): + def has_vector_port(self) -> bool: """ - This method indicates whether this neuron uses buffers defined vector-wise. - :return: True if vector buffers defined, otherwise False. - :rtype: bool + This method indicates whether this neuron contains input ports defined vector-wise. + :return: True if vector ports defined, otherwise False. """ - buffers = self.get_input_buffers() - for BUFFER in buffers: - if BUFFER.has_vector_parameter(): + ports = self.get_input_ports() + for port in ports: + if port.has_vector_parameter(): return True return False + def has_state_vectors(self) -> bool: + """ + This method indicates if the neuron has variables defined as vectors. + :return: True if vectors are defined, false otherwise. + """ + state_symbols = self.get_state_symbols() + for symbol in state_symbols: + if symbol.has_vector_parameter(): + return True + + return False + def get_parameter_invariants(self): """ Returns a list of all invariants of all parameters. @@ -674,6 +541,7 @@ def add_to_internal_block(self, declaration, index=-1): :param declaration: a single declaration :type declaration: ast_declaration """ + from pynestml.utils.ast_utils import ASTUtils if self.get_internals_blocks() is None: ASTUtils.create_internal_block(self) n_declarations = len(self.get_internals_blocks().get_declarations()) @@ -689,23 +557,23 @@ def add_to_internal_block(self, declaration, index=-1): declaration.accept(symtable_vistor) symtable_vistor.block_type_stack.pop() - def add_to_initial_values_block(self, declaration): + def add_to_state_block(self, declaration): """ - Adds the handed over declaration to the initial values block. + Adds the handed over declaration to the state block. :param declaration: a single declaration. :type declaration: ast_declaration """ - if self.get_initial_blocks() is None: - ASTUtils.create_initial_values_block(self) - self.get_initial_blocks().get_declarations().append(declaration) - declaration.update_scope(self.get_initial_blocks().get_scope()) + from pynestml.utils.ast_utils import ASTUtils + if self.get_state_blocks() is None: + ASTUtils.create_state_block(self) + self.get_state_blocks().get_declarations().append(declaration) + declaration.update_scope(self.get_state_blocks().get_scope()) from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor symtable_vistor = ASTSymbolTableVisitor() - symtable_vistor.block_type_stack.push(BlockType.INITIAL_VALUES) + symtable_vistor.block_type_stack.push(BlockType.STATE) declaration.accept(symtable_vistor) symtable_vistor.block_type_stack.pop() - # self.get_initial_blocks().accept(symtable_vistor) from pynestml.symbols.symbol import SymbolKind assert declaration.get_variables()[0].get_scope().resolve_to_symbol( declaration.get_variables()[0].get_name(), SymbolKind.VARIABLE) is not None @@ -714,7 +582,7 @@ def add_to_initial_values_block(self, declaration): def add_kernel(self, kernel: ASTKernel) -> None: """ - Adds the handed over declaration to the initial values block. + Adds the handed over declaration to the state block. :param kernel: a single declaration. """ assert self.get_equations_block() is not None diff --git a/pynestml/meta_model/ast_neuron_or_synapse.py b/pynestml/meta_model/ast_neuron_or_synapse.py new file mode 100644 index 000000000..6eeed2221 --- /dev/null +++ b/pynestml/meta_model/ast_neuron_or_synapse.py @@ -0,0 +1,741 @@ +# -*- coding: utf-8 -*- +# +# ast_neuron_or_synapse.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Dict, List, Optional, Union + +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody +from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_kernel import ASTKernel +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import BlockType, VariableSymbol +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages +from pynestml.utils.ast_source_location import ASTSourceLocation + + +class ASTNeuronOrSynapse(ASTNode): + """ + This class is used to stuff common to neurons and synapses + """ + + def __init__(self, name, body, artifact_name=None, *args, **kwargs): + """ + Standard constructor. + + Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. + + :param name: the name of the neuron. + :type name: str + :param body: the body containing the definitions. + :type body: ASTNeuronOrSynapseBody or ASTNeuronOrSynapseBody + :param source_position: the position of this element in the source file. + :type source_position: ASTSourceLocation. + :param artifact_name: the name of the file this neuron is contained in + :type artifact_name: str + """ + super(ASTNeuronOrSynapse, self).__init__(*args, **kwargs) + assert isinstance(name, str), \ + '(PyNestML.AST.ASTNeuronOrSynapse) No or wrong type of neuron name provided (%s)!' % type(name) + assert isinstance(body, ASTNeuronOrSynapseBody) or isinstance(body, ASTNeuronOrSynapseBody), \ + '(PyNestML.AST.Neuron) No or wrong type of neuron body provided (%s)!' % type(body) + assert (artifact_name is not None and isinstance(artifact_name, str)), \ + '(PyNestML.AST.Neuron) No or wrong type of artifact name provided (%s)!' % type(artifact_name) + + self.name = name + self.body = body + self.artifact_name = artifact_name + + def clone(self): + """ + Return a clone ("deep copy") of this node. + + :return: new AST node instance + :rtype: ASTNeuronOrSynapse + """ + dup = ASTNeuronOrSynapse(name=self.name, + body=self.body.clone(), + artifact_name=self.artifact_name, + # ASTNode common attributes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + post_comments=[s for s in self.post_comments], + implicit_conversion_factor=self.implicit_conversion_factor) + + return dup + + def get_name(self): + """ + Returns the name of the neuron. + :return: the name of the neuron. + :rtype: str + """ + return self.name + + def set_name(self, name): + """ + Set the name of the node. + """ + self.name = name + + def get_body(self): + """ + Return the body of the neuron. + :return: the body containing the definitions. + :rtype: ASTNeuronOrSynapseBody or ASTNeuronOrSynapseBody + """ + return self.body + + def get_artifact_name(self): + """ + Returns the name of the artifact this neuron has been stored in. + :return: the name of the file + :rtype: str + """ + return self.artifact_name + + def get_functions(self): + """ + Returns a list of all function block declarations in this body. + :return: a list of function declarations. + :rtype: list(ASTFunction) + """ + ret = list() + from pynestml.meta_model.ast_function import ASTFunction + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTFunction): + ret.append(elem) + return ret + + def get_update_blocks(self): + """ + Returns a list of all update blocks defined in this body. + :return: a list of update-block elements. + :rtype: list(ASTUpdateBlock) + """ + ret = list() + from pynestml.meta_model.ast_update_block import ASTUpdateBlock + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTUpdateBlock): + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def get_state_blocks(self): + """ + Returns a list of all state blocks defined in this body. + :return: a list of state-blocks. + :rtype: list(ASTBlockWithVariables) + """ + ret = list() + from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTBlockWithVariables) and elem.is_state: + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def get_parameter_blocks(self): + """ + Returns a list of all parameter blocks defined in this body. + :return: a list of parameters-blocks. + :rtype: list(ASTBlockWithVariables) + """ + ret = list() + from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTBlockWithVariables) and elem.is_parameters: + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def get_internals_blocks(self): + """ + Returns a list of all internals blocks defined in this body. + :return: a list of internals-blocks. + :rtype: list(ASTBlockWithVariables) + """ + ret = list() + from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTBlockWithVariables) and elem.is_internals: + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def get_equations_blocks(self) -> Optional[Union[ASTEquationsBlock, List[ASTEquationsBlock]]]: + """ + Returns a list of all ``equations`` blocks defined in this body. + :return: a list of equations-blocks. + """ + ret = list() + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTEquationsBlock): + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def get_equations_block(self): + """ + Returns the unique equations block defined in this body. + :return: a equations-block. + :rtype: ASTEquationsBlock + """ + return self.get_equations_blocks() + + def remove_equations_block(self) -> None: + """ + Deletes all equations blocks. By construction as checked through cocos there is only one there. + """ + + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTEquationsBlock): + self.get_body().get_body_elements().remove(elem) + + def get_initial_value(self, variable_name): + assert type(variable_name) is str + + for decl in self.get_state_blocks().get_declarations(): + for var in decl.variables: + if var.get_complete_name() == variable_name: + return decl.get_expression() + + return None + + def get_state_declarations(self): + """ + Returns a list of initial values declarations made in this neuron. + :return: a list of initial values declarations + :rtype: list(ASTDeclaration) + """ + initial_values_block = self.get_state_blocks() + initial_values_declarations = list() + if initial_values_block is not None: + for decl in initial_values_block.get_declarations(): + initial_values_declarations.append(decl) + return initial_values_declarations + + def get_equations(self): + """ + Returns all ode equations as defined in this neuron. + :return list of ode-equations + :rtype list(ASTOdeEquation) + """ + ret = list() + blocks = self.get_equations_blocks() + # the get equations block is not deterministic method, it can return a list or a single object. + if isinstance(blocks, list): + for block in blocks: + ret.extend(block.get_ode_equations()) + if isinstance(blocks, ASTEquationsBlock): + return blocks.get_ode_equations() + return ret + + def get_input_blocks(self): + """ + Returns a list of all input-blocks defined. + :return: a list of defined input-blocks. + :rtype: list(ASTInputBlock) + """ + ret = list() + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTInputBlock): + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def get_input_buffers(self): + """ + Returns a list of all defined input buffers. + :return: a list of all input buffers. + :rtype: list(VariableSymbol) + """ + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and (symbol.block_type == BlockType.INPUT_BUFFER_SPIKE + or symbol.block_type == BlockType.INPUT_BUFFER_CURRENT): + ret.append(symbol) + return ret + + def get_spike_buffers(self): + """ + Returns a list of all spike input buffers defined in the model. + :return: a list of all spike input buffers. + :rtype: list(VariableSymbol) + """ + ret = list() + for BUFFER in self.get_input_buffers(): + if BUFFER.is_spike_buffer(): + ret.append(BUFFER) + return ret + + def get_current_buffers(self): + """ + Returns a list of all current buffers defined in the model. + :return: a list of all current input buffers. + :rtype: list(VariableSymbol) + """ + ret = list() + for BUFFER in self.get_input_buffers(): + if BUFFER.is_current_buffer(): + ret.append(BUFFER) + return ret + + def get_parameter_symbols(self): + """ + Returns a list of all parameter symbol defined in the model. + :return: a list of parameter symbols. + :rtype: list(VariableSymbol) + """ + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and symbol.block_type in [BlockType.PARAMETERS, BlockType.COMMON_PARAMETERS] and \ + not symbol.is_predefined: + ret.append(symbol) + return ret + + def get_state_symbols(self) -> List[VariableSymbol]: + """ + Returns a list of all state symbol defined in the model. + :return: a list of state symbols. + """ + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and symbol.block_type == BlockType.STATE and \ + not symbol.is_predefined: + ret.append(symbol) + return ret + + def get_internal_symbols(self): + """ + Returns a list of all internals symbol defined in the model. + :return: a list of internals symbols. + :rtype: list(VariableSymbol) + """ + from pynestml.symbols.variable_symbol import BlockType + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and symbol.block_type == BlockType.INTERNALS and \ + not symbol.is_predefined: + ret.append(symbol) + return ret + + def get_inline_expression_symbols(self) -> List[VariableSymbol]: + """ + Returns a list of all inline expression symbols defined in the model. + :return: a list of symbols + """ + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) \ + and (symbol.block_type == BlockType.EQUATION or symbol.block_type == BlockType.STATE) \ + and symbol.is_inline_expression: + ret.append(symbol) + return ret + + def get_output_blocks(self): + """ + Returns a list of all output-blocks defined. + :return: a list of defined output-blocks. + :rtype: list(ASTOutputBlock) + """ + ret = list() + from pynestml.meta_model.ast_output_block import ASTOutputBlock + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTOutputBlock): + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + if isinstance(ret, list) and len(ret) == 0: + return None + return ret + + def is_multisynapse_spikes(self): + """ + Returns whether this neuron uses multi-synapse spikes. + :return: True if multi-synaptic, otherwise False. + :rtype: bool + """ + buffers = self.get_spike_buffers() + for iBuffer in buffers: + if iBuffer.has_vector_parameter(): + return True + return False + + def get_multiple_receptors(self): + """ + Returns a list of all spike buffers which are defined as inhibitory and excitatory. + :return: a list of spike buffers variable symbols + :rtype: list(VariableSymbol) + """ + ret = list() + for iBuffer in self.get_spike_buffers(): + if iBuffer.is_excitatory() and iBuffer.is_inhibitory(): + if iBuffer is not None: + ret.append(iBuffer) + else: + code, message = Messages.get_could_not_resolve(iBuffer.get_symbol_name()) + Logger.log_message( + message=message, + code=code, + error_position=iBuffer.get_source_position(), + log_level=LoggingLevel.ERROR) + return ret + + def get_kernel_by_name(self, kernel_name: str) -> Optional[ASTKernel]: + assert type(kernel_name) is str + kernel_name = kernel_name.split("__X__")[0] + + if not self.get_equations_block(): + return None + + # check if defined as a direct function of time + for decl in self.get_equations_block().get_declarations(): + if type(decl) is ASTKernel and kernel_name in decl.get_variable_names(): + return decl + + # check if defined for a higher order of differentiation + for decl in self.get_equations_block().get_declarations(): + if type(decl) is ASTKernel and kernel_name in [s.replace("$", "__DOLLAR").replace("'", "") for s in decl.get_variable_names()]: + return decl + + return None + + def get_all_kernels(self): + kernels = [] + for decl in self.get_equations_block().get_declarations(): + if type(decl) is ASTKernel: + kernels.append(decl) + return kernels + + def get_non_inline_state_symbols(self) -> List[VariableSymbol]: + """ + Returns a list of all state symbols as defined in the model which are not marked as inline expressions. + :return: a list of symbols + """ + ret = list() + for symbol in self.get_state_symbols(): + if not symbol.is_inline_expression: + ret.append(symbol) + return ret + + def get_ode_defined_symbols(self): + """ + Returns a list of all variable symbols which have been defined in th state blocks + and are provided with an ode. + :return: a list of state variables with odes + :rtype: list(VariableSymbol) + """ + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and \ + symbol.block_type == BlockType.STATE and symbol.is_ode_defined() \ + and not symbol.is_predefined: + ret.append(symbol) + return ret + + def get_state_symbols_without_ode(self): + """ + Returns a list of all elements which have been defined in the state block. + :return: a list of of state variable symbols. + :rtype: list(VariableSymbol) + """ + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and \ + symbol.block_type == BlockType.STATE and not symbol.is_ode_defined() \ + and not symbol.is_predefined: + ret.append(symbol) + return ret + + def is_array_buffer(self): + """ + This method indicates whether this neuron uses buffers defined vector-wise. + :return: True if vector buffers defined, otherwise False. + :rtype: bool + """ + buffers = self.get_input_buffers() + for BUFFER in buffers: + if BUFFER.has_vector_parameter(): + return True + return False + + def get_parameter_invariants(self): + """ + Returns a list of all invariants of all parameters. + :return: a list of rhs representing invariants + :rtype: list(ASTExpression) + """ + from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables + ret = list() + blocks = self.get_parameter_blocks() + # the get parameters block is not deterministic method, it can return a list or a single object. + if isinstance(blocks, list): + for block in blocks: + for decl in block.get_declarations(): + if decl.has_invariant(): + ret.append(decl.get_invariant()) + elif isinstance(blocks, ASTBlockWithVariables): + for decl in blocks.get_declarations(): + if decl.has_invariant(): + ret.append(decl.get_invariant()) + return ret + + def create_empty_update_block(self): + """ + Create an empty update block. Only makes sense if one does not already exist. + """ + assert self.get_update_blocks() is None or len(self.get_update_blocks( + )) == 0, "create_empty_update_block() called although update block already present" + from pynestml.meta_model.ast_node_factory import ASTNodeFactory + block = ASTNodeFactory.create_ast_block([], ASTSourceLocation.get_predefined_source_position()) + update_block = ASTNodeFactory.create_ast_update_block(block, ASTSourceLocation.get_predefined_source_position()) + self.get_body().get_body_elements().append(update_block) + + def add_to_internal_block(self, declaration, index=-1): + """ + Adds the handed over declaration the internal block + :param declaration: a single declaration + :type declaration: ast_declaration + """ + from pynestml.utils.ast_utils import ASTUtils + if self.get_internals_blocks() is None: + ASTUtils.create_internal_block(self) + n_declarations = len(self.get_internals_blocks().get_declarations()) + if n_declarations == 0: + index = 0 + else: + index = 1 + (index % len(self.get_internals_blocks().get_declarations())) + self.get_internals_blocks().get_declarations().insert(index, declaration) + declaration.update_scope(self.get_internals_blocks().get_scope()) + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + symtable_vistor = ASTSymbolTableVisitor() + symtable_vistor.block_type_stack.push(BlockType.INTERNALS) + declaration.accept(symtable_vistor) + symtable_vistor.block_type_stack.pop() + + def add_to_state_block(self, declaration): + """ + Adds the handed over declaration to the state block. + :param declaration: a single declaration. + :type declaration: ast_declaration + """ + from pynestml.utils.ast_utils import ASTUtils + if self.get_state_blocks() is None: + ASTUtils.create_state_block(self) + self.get_state_blocks().get_declarations().append(declaration) + declaration.update_scope(self.get_state_blocks().get_scope()) + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + + symtable_vistor = ASTSymbolTableVisitor() + symtable_vistor.block_type_stack.push(BlockType.STATE) + declaration.accept(symtable_vistor) + symtable_vistor.block_type_stack.pop() + from pynestml.symbols.symbol import SymbolKind + assert declaration.get_variables()[0].get_scope().resolve_to_symbol( + declaration.get_variables()[0].get_name(), SymbolKind.VARIABLE) is not None + assert declaration.get_scope().resolve_to_symbol(declaration.get_variables()[0].get_name(), + SymbolKind.VARIABLE) is not None + + def add_kernel(self, kernel: ASTKernel) -> None: + """ + Adds the handed over declaration to the state block. + :param kernel: a single declaration. + """ + assert self.get_equations_block() is not None + self.get_equations_block().get_declarations().append(kernel) + kernel.update_scope(self.get_equations_blocks().get_scope()) + + """ + The following print methods are used by the backend and represent the comments as stored at the corresponding + parts of the neuron definition. + """ + + def print_dynamics_comment(self, prefix=None): + """ + Prints the dynamic block comment. + :param prefix: a prefix string + :type prefix: str + :return: the corresponding comment. + :rtype: str + """ + block = self.get_update_blocks() + if block is None: + return prefix if prefix is not None else '' + return block.print_comment(prefix) + + def print_parameter_comment(self, prefix=None): + """ + Prints the update block comment. + :param prefix: a prefix string + :type prefix: str + :return: the corresponding comment. + :rtype: str + """ + block = self.get_parameter_blocks() + if block is None: + return prefix if prefix is not None else '' + return block.print_comment(prefix) + + def print_state_comment(self, prefix=None): + """ + Prints the state block comment. + :param prefix: a prefix string + :type prefix: str + :return: the corresponding comment. + :rtype: str + """ + block = self.get_state_blocks() + if block is None: + return prefix if prefix is not None else '' + return block.print_comment(prefix) + + def print_internal_comment(self, prefix=None): + """ + Prints the internal block comment. + :param prefix: a prefix string + :type prefix: str + :return: the corresponding comment. + :rtype: str + """ + block = self.get_internals_blocks() + if block is None: + return prefix if prefix is not None else '' + return block.print_comment(prefix) + + def print_comment(self, prefix=None): + """ + Prints the header information of this neuron. + :param prefix: a prefix string + :type prefix: str + :return: the comment. + :rtype: str + """ + ret = '' + if self.get_comment() is None or len(self.get_comment()) == 0: + return prefix if prefix is not None else '' + for comment in self.get_comment(): + ret += (prefix if prefix is not None else '') + comment + '\n' + return ret + + def get_parent(self, ast): + """ + Indicates whether a this node contains the handed over node. + :param ast: an arbitrary meta_model node. + :type ast: AST_ + :return: AST if this or one of the child nodes contains the handed over element. + :rtype: AST_ or None + """ + if self.get_body() is ast: + return self + if self.get_body().get_parent(ast) is not None: + return self.get_body().get_parent(ast) + return None + + def equals(self, other): + """ + The equals method. + :param other: a different object. + :type other: object + :return: True if equal, otherwise False. + :rtype: bool + """ + if not isinstance(other, ASTNeuron): + return False + return self.get_name() == other.get_name() and self.get_body().equals(other.get_body()) + + def get_initial_value(self, variable_name): + assert type(variable_name) is str + + if self.get_state_blocks() is None: + return None + + for decl in self.get_state_blocks().get_declarations(): + for var in decl.variables: + if var.get_complete_name() == variable_name: + return decl.get_expression() + + return None + + def get_kernel_by_name(self, kernel_name) -> Optional[ASTKernel]: + assert type(kernel_name) is str + kernel_name = kernel_name.split("__X__")[0] + + # check if defined as a direct function of time + if self.get_equations_block(): + for decl in self.get_equations_block().get_declarations(): + if type(decl) is ASTKernel and kernel_name in decl.get_variable_names(): + return decl + + # check if defined for a higher order of differentiation + for decl in self.get_equations_block().get_declarations(): + if type(decl) is ASTKernel and kernel_name in [s.replace("$", "__DOLLAR").replace("'", "") for s in decl.get_variable_names()]: + return decl + + return None + + def get_all_kernels(self): + kernels = [] + for decl in self.get_equations_block().get_declarations(): + if type(decl) is ASTKernel: + kernels.append(decl) + return kernels + + def has_delay_variables(self) -> bool: + """ + This method indicates if the neuron has variables with a delay parameter. + :return: True if variables with delay parameter exist, False otherwise. + """ + state_symbols = self.get_state_symbols() + for symbol in state_symbols: + if symbol.has_delay_parameter(): + return True + + return False diff --git a/pynestml/meta_model/ast_body.py b/pynestml/meta_model/ast_neuron_or_synapse_body.py similarity index 78% rename from pynestml/meta_model/ast_body.py rename to pynestml/meta_model/ast_neuron_or_synapse_body.py index c9721c5a3..35929e2f2 100644 --- a/pynestml/meta_model/ast_body.py +++ b/pynestml/meta_model/ast_neuron_or_synapse_body.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# ast_body.py +# ast_neuron_or_synapse_body.py # # This file is part of NEST. # @@ -19,13 +19,17 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import List, Optional + from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_input_port import ASTInputPort +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock -class ASTBody(ASTNode): +class ASTNeuronOrSynapseBody(ASTNode): """ - This class is used to store the body of a neuron, an object containing all the definitions. - ASTBody The body of the neuron, e.g. internal, state, parameter... + This class is used to store the body of a neuron or synapse, an object containing all the definitions. + ASTNeuronOrSynapseBody The body of the neuron, e.g. internal, state, parameter... Grammar: body : BLOCK_OPEN (NEWLINE | blockWithVariables | updateBlock | equationsBlock | inputBlock | outputBlock | function)* @@ -43,7 +47,7 @@ def __init__(self, body_elements, *args, **kwargs): :param body_elements: a list of elements, e.g. variable blocks. :type body_elements: List[ASTNode] """ - super(ASTBody, self).__init__(*args, **kwargs) + super(ASTNeuronOrSynapseBody, self).__init__(*args, **kwargs) self.body_elements = body_elements def clone(self): @@ -51,20 +55,20 @@ def clone(self): Return a clone ("deep copy") of this node. :return: new AST node instance - :rtype: ASTBody + :rtype: ASTNeuronOrSynapseBody """ body_elements_dup = None if self.body_elements: body_elements_dup = [body_element.clone() for body_element in self.body_elements] - dup = ASTBody(body_elements=body_elements_dup, - # ASTNode common attriutes: - source_position=self.source_position, - scope=self.scope, - comment=self.comment, - pre_comments=[s for s in self.pre_comments], - in_comment=self.in_comment, - post_comments=[s for s in self.post_comments], - implicit_conversion_factor=self.implicit_conversion_factor) + dup = ASTNeuronOrSynapseBody(body_elements=body_elements_dup, + # ASTNode common attriutes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + post_comments=[s for s in self.post_comments], + implicit_conversion_factor=self.implicit_conversion_factor) return dup @@ -141,6 +145,19 @@ def get_internals_blocks(self): ret.append(elem) return ret + def get_on_receive_block(self, port_name) -> Optional[ASTOnReceiveBlock]: + for elem in self.get_body_elements(): + if isinstance(elem, ASTOnReceiveBlock) and elem.port_name == port_name: + return elem + return None + + def get_on_receive_blocks(self) -> List[ASTOnReceiveBlock]: + on_receive_blocks = [] + for elem in self.get_body_elements(): + if isinstance(elem, ASTOnReceiveBlock): + on_receive_blocks.append(elem) + return on_receive_blocks + def get_equations_blocks(self): """ Returns a list of all equations blocks defined in this body. @@ -195,11 +212,10 @@ def get_parent(self, ast=None): return stmt.get_parent(ast) return None - def get_spike_buffers(self): + def get_spike_input_ports(self) -> List[ASTInputPort]: """ - Returns a list of all spike input buffers defined in the model. - :return: a list of all spike input buffers - :rtype: list(ASTInputPort) + Returns a list of all spike input ports defined in the model. + :return: a list of all spike input ports """ ret = list() blocks = self.get_input_blocks() @@ -218,7 +234,7 @@ def equals(self, other): :return: True if equal, otherwise False. :rtype: bool """ - if not isinstance(other, ASTBody): + if not isinstance(other, ASTNeuronOrSynapseBody): return False if len(self.get_body_elements()) != len(other.get_body_elements()): return False diff --git a/pynestml/meta_model/ast_node.py b/pynestml/meta_model/ast_node.py index 95a99a036..7b5a7dcc4 100644 --- a/pynestml/meta_model/ast_node.py +++ b/pynestml/meta_model/ast_node.py @@ -19,6 +19,8 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Optional + from abc import ABCMeta, abstractmethod from pynestml.utils.ast_source_location import ASTSourceLocation @@ -102,32 +104,20 @@ def get_parent(self, ast): """ pass - def set_implicit_conversion_factor(self, implicit_factor): + def set_implicit_conversion_factor(self, implicit_factor: Optional[float]) -> None: """ Sets a factor that, when applied to the (unit-typed) expression, converts it to the magnitude of the context where it is used. eg. Volt + milliVolt needs to either be 1000*Volt + milliVolt or Volt + 0.001 * milliVolt :param implicit_factor: the factor to be installed - :type implicit_factor: Optional[float] - :return: nothing """ - from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression - from pynestml.meta_model.ast_expression import ASTExpression - - assert isinstance(self, ASTExpression) or isinstance(self, ASTSimpleExpression) self.implicit_conversion_factor = implicit_factor - def get_implicit_conversion_factor(self): + def get_implicit_conversion_factor(self) -> Optional[float]: """ Returns the factor installed as implicitConversionFactor for this expression :return: the conversion factor, if present, or None - :rtype: Optional[float] """ - - from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression - from pynestml.meta_model.ast_expression import ASTExpression - - assert isinstance(self, ASTExpression) or isinstance(self, ASTSimpleExpression) return self.implicit_conversion_factor def get_source_position(self): @@ -208,6 +198,17 @@ def print_comment(self, prefix): ('\n' if self.get_comment().index(comment) < len(self.get_comment()) - 1 else '') return ret + def get_comments(self): + comments = list() + comments.extend(self.pre_comments) + if self.in_comment is not None: + comments.append(self.in_comment) + comments.extend(self.post_comments) + return comments + + def get_post_comments(self): + return self.post_comments + def accept(self, visitor): """ Double dispatch for visitor pattern. @@ -217,5 +218,5 @@ def accept(self, visitor): visitor.handle(self) def __str__(self): - from pynestml.utils.ast_nestml_printer import ASTNestMLPrinter - return ASTNestMLPrinter().print_node(self) + from pynestml.codegeneration.printers.nestml_printer import NESTMLPrinter + return NESTMLPrinter().print_node(self) diff --git a/pynestml/meta_model/ast_node_factory.py b/pynestml/meta_model/ast_node_factory.py index c1b6c97f6..76fe6b3ac 100644 --- a/pynestml/meta_model/ast_node_factory.py +++ b/pynestml/meta_model/ast_node_factory.py @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import Union +from typing import Optional, Union from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator @@ -33,8 +33,8 @@ from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_declaration import ASTDeclaration from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables -from pynestml.meta_model.ast_body import ASTBody from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock from pynestml.meta_model.ast_if_stmt import ASTIfStmt from pynestml.meta_model.ast_while_stmt import ASTWhileStmt from pynestml.meta_model.ast_for_stmt import ASTForStmt @@ -52,19 +52,25 @@ from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_port import ASTInputPort from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier +from pynestml.utils.port_signal_type import PortSignalType from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody +from pynestml.meta_model.ast_synapse import ASTSynapse +from pynestml.meta_model.ast_namespace_decorator import ASTNamespaceDecorator from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_ode_equation import ASTOdeEquation from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_output_block import ASTOutputBlock from pynestml.meta_model.ast_return_stmt import ASTReturnStmt +from pynestml.meta_model.ast_stmt import ASTStmt +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_update_block import ASTUpdateBlock from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.utils.port_signal_type import PortSignalType -class ASTNodeFactory(): +class ASTNodeFactory: """ An implementation of the factory pattern for an easier initialization of new AST nodes. """ @@ -102,15 +108,23 @@ def create_ast_block(cls, stmts, source_position): @classmethod def create_ast_block_with_variables(cls, is_state=False, is_parameters=False, is_internals=False, - is_initial_values=False, declarations=None, source_position=None): + declarations=None, source_position=None): # type: (bool,bool,bool,bool,list(ASTDeclaration),ASTSourceLocation) -> ASTBlockWithVariables - return ASTBlockWithVariables(is_state, is_parameters, is_internals, is_initial_values, declarations, + return ASTBlockWithVariables(is_state, is_parameters, is_internals, declarations, source_position=source_position) @classmethod - def create_ast_body(cls, body_elements, source_position): - # type: (list,ASTSourceLocation) -> ASTBody - return ASTBody(body_elements, source_position=source_position) + def create_ast_namespace_decorator(cls, namespace=None, name=None, source_position=None): + return ASTNamespaceDecorator(namespace, name, source_position=source_position) + + @classmethod + def create_ast_on_receive_block(cls, block=None, port_name=None, const_parameters=None, source_position=None): + return ASTOnReceiveBlock(block, port_name, const_parameters, source_position=source_position) + + @classmethod + def create_ast_neuron_or_synapse_body(cls, body_elements, source_position): + # type: (list,ASTSourceLocation) -> ASTNeuronOrSynapseBody + return ASTNeuronOrSynapseBody(body_elements, source_position=source_position) @classmethod def create_ast_comparison_operator(cls, is_lt=False, is_le=False, is_eq=False, is_ne=False, is_ne2=False, @@ -131,16 +145,17 @@ def create_ast_data_type(cls, is_integer=False, is_real=False, is_string=False, @classmethod def create_ast_declaration(cls, - is_recordable=False, # type: bool - is_function=False, # type: bool + is_recordable: bool=False, + is_inline_expression: bool=False, variables=None, # type: list data_type=None, # type: ASTDataType size_parameter=None, # type: str expression=None, # type: Union(ASTSimpleExpression,ASTExpression) invariant=None, # type: Union(ASTSimpleExpression,ASTExpression) - source_position=None # type: ASTSourceLocation - ): # type: (...) -> ASTDeclaration - return ASTDeclaration(is_recordable, is_function, variables, data_type, size_parameter, expression, invariant, + source_position=None, # type: ASTSourceLocation + decorators=None, # type: list + ) -> ASTDeclaration: + return ASTDeclaration(is_recordable, is_inline_expression, variables, data_type, size_parameter, expression, invariant, decorators, source_position=source_position) @classmethod @@ -252,15 +267,24 @@ def create_ast_logical_operator(cls, is_logical_and=False, is_logical_or=False, return ASTLogicalOperator(is_logical_and, is_logical_or, source_position=source_position) @classmethod - def create_ast_nestml_compilation_unit(cls, list_of_neurons, source_position, artifact_name): - # type: (list(ASTNeuron),ASTSourceLocation,str) -> ASTNestMLCompilationUnit - return ASTNestMLCompilationUnit(artifact_name=artifact_name, neuron_list=list_of_neurons, source_position=source_position) + def create_ast_nestml_compilation_unit(cls, list_of_neurons, list_of_synapses, source_position: ASTSourceLocation, artifact_name: str) -> ASTNestMLCompilationUnit: + instance = ASTNestMLCompilationUnit(artifact_name=artifact_name, source_position=source_position) + for i in list_of_neurons: + instance.add_neuron(i) + for i in list_of_synapses: + instance.add_synapse(i) + return instance @classmethod def create_ast_neuron(cls, name, body, source_position, artifact_name): # type: (str,ASTBody,ASTSourceLocation,str) -> ASTNeuron return ASTNeuron(name, body, artifact_name, source_position=source_position) + @classmethod + def create_ast_synapse(cls, name, body, source_position, artifact_name): + # type: (str,ASTNeuronOrSynapseBody,ASTSourceLocation,str) -> ASTSynapse + return ASTSynapse(name, body, artifact_name=artifact_name, source_position=source_position) + @classmethod def create_ast_ode_equation(cls, lhs, rhs, source_position): # type: (ASTVariable,ASTSimpleExpression|ASTExpression,ASTSourceLocation) -> ASTOdeEquation @@ -343,9 +367,8 @@ def create_ast_update_block(cls, block, source_position): return ASTUpdateBlock(block, source_position=source_position) @classmethod - def create_ast_variable(cls, name, differential_order=0, source_position=None): - # type: (str,int,ASTSourceLocation) -> ASTVariable - return ASTVariable(name, differential_order, source_position=source_position) + def create_ast_variable(cls, name: str, differential_order: int = 0, vector_parameter=None, is_homogeneous=False, source_position: Optional[ASTSourceLocation] = None) -> ASTVariable: + return ASTVariable(name, differential_order, vector_parameter=vector_parameter, is_homogeneous=is_homogeneous, source_position=source_position) @classmethod def create_ast_while_stmt(cls, diff --git a/pynestml/meta_model/ast_on_receive_block.py b/pynestml/meta_model/ast_on_receive_block.py new file mode 100644 index 000000000..173bdd9ea --- /dev/null +++ b/pynestml/meta_model/ast_on_receive_block.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# +# ast_on_receive_block.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +from typing import Any, Optional, Mapping + +from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_node import ASTNode + + +class ASTOnReceiveBlock(ASTNode): + r""" + This class is used to store a declaration of an onReceive block, for example: + + .. code-block:: nestml + + onReceive(pre_spikes): + pre_tr += 1 + end + + """ + + def __init__(self, block: ASTBlock, port_name: str, const_parameters: Optional[Mapping] = None, *args, **kwargs): + r""" + Standard constructor. + :param block: a block of definitions. + :param source_position: the position of this element in the source file. + """ + super(ASTOnReceiveBlock, self).__init__(*args, **kwargs) + self.block = block + self.port_name = port_name + self.const_parameters = const_parameters + if self.const_parameters is None: + self.const_parameters = {} + + def clone(self) -> ASTOnReceiveBlock: + r""" + Return a clone ("deep copy") of this node. + + :return: new AST node instance + """ + dup = ASTOnReceiveBlock(block=self.block.clone(), + port_name=self.port_name, + const_parameters=self.const_parameters, + # ASTNode common attributes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + post_comments=[s for s in self.post_comments], + implicit_conversion_factor=self.implicit_conversion_factor) + + return dup + + def get_const_parameters(self): + return self.const_parameters + + def get_block(self) -> ASTBlock: + r""" + Returns the block of definitions. + :return: the block + """ + return self.block + + def get_port_name(self) -> str: + r""" + Returns the port name. + :return: the port name + """ + return self.port_name + + def get_parent(self, ast: ASTNode) -> Optional[ASTNode]: + r""" + Indicates whether a this node contains the handed over node. + :param ast: an arbitrary meta_model node. + :return: AST if this or one of the child nodes contains the handed over element. + """ + if self.get_block() is ast: + return self + + if self.get_block().get_parent(ast) is not None: + return self.get_block().get_parent(ast) + + return None + + def equals(self, other: Any) -> bool: + r""" + The equals method. + :param other: a different object. + :return: True if equal, otherwise False. + """ + if not isinstance(other, ASTOnReceiveBlock): + return False + return self.get_block().equals(other.get_block()) and self.port_name == other.port_name diff --git a/pynestml/meta_model/ast_output_block.py b/pynestml/meta_model/ast_output_block.py index 963e61e03..44c90f2a4 100644 --- a/pynestml/meta_model/ast_output_block.py +++ b/pynestml/meta_model/ast_output_block.py @@ -25,13 +25,13 @@ class ASTOutputBlock(ASTNode): """ - This class is used to store output buffer declarations. + This class is used to store output port declarations. ASTOutput represents the output block of the neuron: output: spike - @attribute spike true iff the neuron has a spike output. - @attribute current true iff. the neuron is a current output. + @attribute spike true if and only if the neuron has a spike output. + @attribute continuous true if and only if the neuron has a continuous time output. Grammar: - outputBlock: 'output' BLOCK_OPEN ('spike' | 'current') ; + outputBlock: 'output' BLOCK_OPEN ('spike' | 'continuous') ; Attributes: type = None """ @@ -42,7 +42,7 @@ def __init__(self, o_type, *args, **kwargs): Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. - :param o_type: the type of the output buffer. + :param o_type: the type of the output port. :type o_type: PortSignalType """ assert isinstance(o_type, PortSignalType) @@ -68,21 +68,19 @@ def clone(self): return dup - def is_spike(self): + def is_spike(self) -> bool: """ - Returns whether it is a spike buffer or not. + Returns whether it is a spike type port or not. :return: True if spike, otherwise False. - :rtype: bool """ return self.type is PortSignalType.SPIKE - def is_current(self): + def is_continuous(self) -> bool: """ - Returns whether it is a current buffer or not. - :return: True if current, otherwise False. - :rtype: bool + Returns whether it is a continuous time type or not. + :return: True if continuous time, otherwise False. """ - return self.type is PortSignalType.CURRENT + return self.type is PortSignalType.CONTINUOUS def get_parent(self, ast): """ @@ -94,14 +92,13 @@ def get_parent(self, ast): """ return None - def equals(self, other): + def equals(self, other) -> bool: """ The equals method. :param other: a different object. :type other: object :return: True if equals, otherwise False. - :rtype: bool """ if not isinstance(other, ASTOutputBlock): return False - return self.is_spike() == other.is_spike() and self.is_current() == other.is_current() + return self.is_spike() == other.is_spike() and self.is_continuous() == other.is_continuous() diff --git a/pynestml/meta_model/ast_parameter.py b/pynestml/meta_model/ast_parameter.py index 4aaae69ad..eca37f11a 100644 --- a/pynestml/meta_model/ast_parameter.py +++ b/pynestml/meta_model/ast_parameter.py @@ -19,7 +19,6 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . - from pynestml.meta_model.ast_data_type import ASTDataType from pynestml.meta_model.ast_node import ASTNode @@ -27,9 +26,7 @@ class ASTParameter(ASTNode): """ This class is used to store a single function parameter definition. - ASTParameter represents singe: - output: spike - @attribute compartments Lists with compartments. + Grammar: parameter : NAME datatype; Attributes: @@ -37,7 +34,7 @@ class ASTParameter(ASTNode): data_type (ASTDataType): The data type of the parameter. """ - def __init__(self, name=None, data_type=None, *args, **kwargs): + def __init__(self, name: str, data_type: ASTDataType, *args, **kwargs): """ Standard constructor. :param name: the name of the parameter. @@ -45,10 +42,6 @@ def __init__(self, name=None, data_type=None, *args, **kwargs): :param data_type: the type of the parameter. :type data_type: ASTDataType """ - assert (name is not None and isinstance(name, str)), \ - '(PyNestML.AST.Parameter) No or wrong type of name provided (%s)!' % type(name) - assert (data_type is not None and isinstance(data_type, ASTDataType)), \ - '(PyNestML.AST.Parameter) No or wrong type of datatype provided (%s)!' % type(data_type) super(ASTParameter, self).__init__(*args, **kwargs) self.data_type = data_type self.name = name diff --git a/pynestml/meta_model/ast_simple_expression.py b/pynestml/meta_model/ast_simple_expression.py index ec5297144..4ba76ba3d 100644 --- a/pynestml/meta_model/ast_simple_expression.py +++ b/pynestml/meta_model/ast_simple_expression.py @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import Optional +from typing import Optional, Union import numpy as np @@ -52,25 +52,21 @@ class ASTSimpleExpression(ASTExpressionNode): """ - def __init__(self, function_call=None, boolean_literal=None, numeric_literal=None, is_inf=False, - variable=None, string=None, *args, **kwargs): + def __init__(self, function_call: ASTFunctionCall = None, boolean_literal: bool = None, + numeric_literal: Union[int, float] = None, is_inf: bool = False, + variable: ASTVariable = None, string: str = None, has_delay: bool = False, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param function_call: a function call. - :type function_call: ASTFunctionCall :param boolean_literal: a boolean value. - :type boolean_literal: bool :param numeric_literal: a numeric value. - :type numeric_literal: float/int :param is_inf: is inf symbol. - :type is_inf: bool :param variable: a variable object. - :type variable: ASTVariable :param string: a single string literal - :type string: str + :param has_delay: whether this simple expression node has a delay variable """ super(ASTSimpleExpression, self).__init__(*args, **kwargs) assert (function_call is None or isinstance(function_call, ASTFunctionCall)), \ @@ -97,6 +93,7 @@ def __init__(self, function_call=None, boolean_literal=None, numeric_literal=Non self.is_inf_literal = is_inf self.variable = variable self.string = string + self.has_delay = has_delay def clone(self): """ @@ -125,6 +122,7 @@ def clone(self): is_inf=self.is_inf_literal, variable=variable_dup, string=self.string, + has_delay=self.has_delay, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -207,6 +205,23 @@ def is_variable(self): """ return self.variable is not None and self.numeric_literal is None + def is_delay_variable(self): + """ + Returns whether it is a delay variable or not + :return: True if the variable has a delay parameter, False otherwise + """ + if self.is_variable() and self.has_delay \ + and self.get_variable().get_delay_parameter() is not None: + return True + return False + + def get_has_delay(self): + """ + Returns the has_delay parameter + :return: returns the value of has_delay parameter + """ + return self.has_delay + def get_variables(self): """ This function is used for better interactions with the general rhs meta_model class. diff --git a/pynestml/meta_model/ast_stmt.py b/pynestml/meta_model/ast_stmt.py index cf90f1d5b..6a24cbe36 100644 --- a/pynestml/meta_model/ast_stmt.py +++ b/pynestml/meta_model/ast_stmt.py @@ -19,6 +19,8 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Optional + from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_small_stmt import ASTSmallStmt @@ -75,11 +77,10 @@ def clone(self): return dup - def get_parent(self, ast=None): + def get_parent(self, ast: ASTNode=None) -> Optional[ASTNode]: """ Returns the parent node of a handed over AST object. """ - # type: ASTNode -> ASTNode if self.small_stmt is ast: return self if self.small_stmt is not None and self.small_stmt.get_parent(ast) is not None: @@ -88,6 +89,7 @@ def get_parent(self, ast=None): return self if self.compound_stmt is not None and self.compound_stmt.get_parent(ast) is not None: return self.compound_stmt.get_parent(ast) + return None def is_small_stmt(self): return self.small_stmt is not None diff --git a/pynestml/meta_model/ast_synapse.py b/pynestml/meta_model/ast_synapse.py new file mode 100644 index 000000000..6fa97e58d --- /dev/null +++ b/pynestml/meta_model/ast_synapse.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- +# +# ast_synapse.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import List, Optional + +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.meta_model.ast_neuron_or_synapse import ASTNeuronOrSynapse +from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock +from pynestml.symbols.variable_symbol import BlockType +from pynestml.symbols.variable_symbol import VariableSymbol +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages + + +class ASTSynapse(ASTNeuronOrSynapse): + """ + This class is used to store instances of synapses. + ASTSynapse represents synapse. + @attribute Name The name of the synapse + @attribute Body The body of the synapse, e.g. internal, state, parameter... + Grammar: + synapse : 'synapse' NAME body; + Attributes: + name = None + body = None + artifact_name = None + """ + + def __init__(self, name, body, default_weight=None, artifact_name=None, *args, **kwargs): + """ + Standard constructor. + :param name: the name of the synapse. + :type name: str + :param body: the body containing the definitions. + :type body: ASTNeuronOrSynapseBody + :param source_position: the position of this element in the source file. + :type source_position: ASTSourceLocation. + :param artifact_name: the name of the file this synapse is contained in + :type artifact_name: str + """ + super(ASTSynapse, self).__init__(name, body, artifact_name, *args, **kwargs) + self._default_weight = default_weight + + def clone(self): + """ + Return a clone ("deep copy") of this node. + + :return: new AST node instance + :rtype: ASTSynapse + """ + dup = ASTSynapse(name=self.name, + body=self.body.clone(), + default_weight=self._default_weight, + artifact_name=self.artifact_name, + # ASTNode common attributes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + post_comments=[s for s in self.post_comments], + implicit_conversion_factor=self.implicit_conversion_factor) + + return dup + + def set_default_weight(self, w): + self._default_weight = w + + def set_default_delay(self, var, expr, dtype): + self._default_delay_variable = var + self._default_delay_expression = expr + self._default_delay_dtype = dtype + + def get_default_delay_expression(self): + return self._default_delay_expression + + def get_default_delay_variable(self): + return self._default_delay_variable + + def get_default_delay_dtype(self): + return self._default_delay_dtype + + def get_weight_variable(self): + return self._default_weight + + def get_default_weight(self): + return self._default_weight + + def get_body(self): + """ + Return the body of the synapse. + :return: the body containing the definitions. + :rtype: ASTNeuronOrSynapseBody + """ + return self.body + + def get_on_receive_blocks(self) -> List[ASTOnReceiveBlock]: + if not self.get_body(): + return [] + return self.get_body().get_on_receive_blocks() + + def get_on_receive_block(self, port_name: str) -> Optional[ASTOnReceiveBlock]: + if not self.get_body(): + return None + return self.get_body().get_on_receive_block(port_name) + + def get_input_blocks(self): + """ + Returns a list of all input-blocks defined. + :return: a list of defined input-blocks. + :rtype: list(ASTInputBlock) + """ + ret = list() + from pynestml.meta_model.ast_input_block import ASTInputBlock + for elem in self.get_body().get_body_elements(): + if isinstance(elem, ASTInputBlock): + ret.append(elem) + if isinstance(ret, list) and len(ret) == 1: + return ret[0] + elif isinstance(ret, list) and len(ret) == 0: + return None + else: + return ret + + def get_input_buffers(self): + """ + Returns a list of all defined input buffers. + :return: a list of all input buffers. + :rtype: list(VariableSymbol) + """ + from pynestml.symbols.variable_symbol import BlockType + symbols = self.get_scope().get_symbols_in_this_scope() + ret = list() + for symbol in symbols: + if isinstance(symbol, VariableSymbol) and (symbol.block_type == BlockType.INPUT_BUFFER_SPIKE + or symbol.block_type == BlockType.INPUT_BUFFER_CURRENT): + ret.append(symbol) + return ret + + def get_spike_buffers(self): + """ + Returns a list of all spike input buffers defined in the model. + :return: a list of all spike input buffers. + :rtype: list(VariableSymbol) + """ + ret = list() + for BUFFER in self.get_input_buffers(): + if BUFFER.is_spike_buffer(): + ret.append(BUFFER) + return ret diff --git a/pynestml/meta_model/ast_variable.py b/pynestml/meta_model/ast_variable.py index 9ea04e101..c58f6aab7 100644 --- a/pynestml/meta_model/ast_variable.py +++ b/pynestml/meta_model/ast_variable.py @@ -19,14 +19,17 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Any, Optional + from copy import copy from pynestml.meta_model.ast_node import ASTNode +from pynestml.symbols.type_symbol import TypeSymbol from pynestml.utils.either import Either class ASTVariable(ASTNode): - """ + r""" This class is used to store a single variable. ASTVariable Provides a 'marker' AST node to identify variables used in expressions. @@ -39,13 +42,17 @@ class ASTVariable(ASTNode): type_symbol = None """ - def __init__(self, name, differential_order=0, type_symbol=None, *args, **kwargs): + def __init__(self, name, differential_order=0, type_symbol: Optional[str] = None, + vector_parameter: Optional[str] = None, is_homogeneous: bool = False, delay_parameter: Optional[str] = None, *args, **kwargs): """ Standard constructor. :param name: the name of the variable :type name: str :param differential_order: the differential order of the variable. :type differential_order: int + :param type_symbol: the type of the variable + :param vector_parameter: the vector parameter of the variable + :param delay_parameter: the delay value to be used in the differential equation """ super(ASTVariable, self).__init__(*args, **kwargs) assert isinstance(differential_order, int), \ @@ -57,14 +64,19 @@ def __init__(self, name, differential_order=0, type_symbol=None, *args, **kwargs self.name = name self.differential_order = differential_order self.type_symbol = type_symbol + self.vector_parameter = vector_parameter + self.is_homogeneous = is_homogeneous + self.delay_parameter = delay_parameter def clone(self): - """ + r""" Return a clone ("deep copy") of this node. """ return ASTVariable(name=self.name, differential_order=self.differential_order, type_symbol=self.type_symbol, + vector_parameter=self.vector_parameter, + delay_parameter=self.delay_parameter, # ASTNode common attriutes: source_position=self.get_source_position(), scope=self.scope, @@ -79,100 +91,118 @@ def resolve_in_own_scope(self): assert self.get_scope() is not None return self.get_scope().resolve_to_symbol(self.get_complete_name(), SymbolKind.VARIABLE) - def get_name(self): - """ + def get_name(self) -> str: + r""" Returns the name of the variable. :return: the name of the variable. - :rtype: str """ return self.name - def set_name(self, name): - # type: (str) -> None + def set_name(self, name: str) -> None: """ Sets the name of the variable. :name: the name to set. """ self.name = name + def get_is_homogeneous(self) -> bool: + return self.is_homogeneous + def get_differential_order(self) -> int: - """ + r""" Returns the differential order of the variable. :return: the differential order. """ return self.differential_order def set_differential_order(self, differential_order: int) -> None: - """ - Set the differential order of the variable. + r""" + Returns the differential order of the variable. """ self.differential_order = differential_order - def get_complete_name(self): - """ + def get_complete_name(self) -> str: + r""" Returns the complete name, consisting of the name and the differential order. :return: the complete name. - :rtype: str """ return self.get_name() + '\'' * self.get_differential_order() - def get_name_of_lhs(self): - """ + def get_name_of_lhs(self) -> str: + r""" Returns the complete name but with differential order reduced by one. :return: the name. - :rtype: str """ if self.get_differential_order() > 0: return self.get_name() + '\'' * (self.get_differential_order() - 1) return self.get_name() - def get_type_symbol(self): - """ + def get_type_symbol(self) -> TypeSymbol: + r""" Returns the type symbol of this rhs. :return: a single type symbol. - :rtype: type_symbol """ return copy(self.type_symbol) - def set_type_symbol(self, type_symbol): - """ + def set_type_symbol(self, type_symbol: TypeSymbol): + r""" Updates the current type symbol to the handed over one. :param type_symbol: a single type symbol object. - :type type_symbol: type_symbol """ - assert (type_symbol is not None and isinstance(type_symbol, Either)), \ - '(PyNestML.AST.Variable) No or wrong type of type symbol provided (%s)!' % type(type_symbol) self.type_symbol = type_symbol - def get_parent(self, ast): + def get_vector_parameter(self) -> str: + r""" + Returns the vector parameter of the variable + :return: the vector parameter + """ + return self.vector_parameter + + def set_size_parameter(self, vector_parameter): + r""" + Updates the vector parameter of the variable + """ + self.vector_parameter = vector_parameter + + def get_delay_parameter(self): + r""" + Returns the delay parameter + :return: delay parameter + """ + return self.delay_parameter + + def set_delay_parameter(self, delay: str): + """ + Updates the current delay parameter to the handed over value + :param delay: delay parameter + """ + assert (delay is not None), '(PyNestML.AST.Variable) No delay parameter provided' + self.delay_parameter = delay + + def get_parent(self, ast: ASTNode) -> Optional[ASTNode]: """ Indicates whether a this node contains the handed over node. :param ast: an arbitrary meta_model node. - :type ast: ASTNode :return: AST if this or one of the child nodes contains the handed over element. - :rtype: ASTNode or None """ return None - def is_unit_variable(self): - """ + def is_unit_variable(self) -> bool: + r""" Provided on-the-fly information whether this variable represents a unit-variable, e.g., nS. Caution: It assumes that the symbol table has already been constructed. :return: True if unit-variable, otherwise False. - :rtype: bool """ from pynestml.symbols.predefined_types import PredefinedTypes if self.get_name() in PredefinedTypes.get_types(): return True return False - def equals(self, other): - """ + def equals(self, other: Any) -> bool: + r""" The equals method. :param other: a different object. - :type other: object :return: True if equals, otherwise False. - :rtype: bool """ if not isinstance(other, ASTVariable): return False diff --git a/pynestml/symbol_table/scope.py b/pynestml/symbol_table/scope.py index 9684f9d27..d9e21c0d2 100644 --- a/pynestml/symbol_table/scope.py +++ b/pynestml/symbol_table/scope.py @@ -18,13 +18,30 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from __future__ import annotations + from enum import Enum from pynestml.symbols.symbol import Symbol, SymbolKind +from pynestml.utils.ast_source_location import ASTSourceLocation -class Scope(object): +class ScopeType(Enum): + """ + This enum is used to distinguish between different types of scopes, namely: + -The global scope (neuron), in which all the sub-scopes are embedded. + -The function scope, as embedded in the global scope. + -The update scope, as embedded in the global scope. """ + GLOBAL = 1 + UPDATE = 2 + FUNCTION = 3 + ON_RECEIVE = 4 + + +class Scope: + r""" This class is used to store a single scope, i.e., a set of elements as declared in this scope directly and a set of sub-scopes with additional elements. Attributes: @@ -34,78 +51,69 @@ class Scope(object): source_position The position in the source file this scope spans over. """ - def __init__(self, scope_type, enclosing_scope=None, source_position=None): - """ + def __init__(self, scope_type: ScopeType, enclosing_scope: Scope = None, source_position: ASTSourceLocation = None): + r""" Standard constructor as used to create a new scope. :param scope_type: the type of this scope - :type scope_type: ScopeType :param enclosing_scope: the parent scope of this scope, as used for resolution of symbols. - :type enclosing_scope: Scope :param source_position: the start and end of the scope in the source file - :type source_position: ast_source_location """ self.declared_elements = list() self.scope_type = scope_type self.enclosing_scope = enclosing_scope - self.source_position = source_position + self.source_location = source_position - def add_symbol(self, symbol): - """ + def add_symbol(self, symbol: Symbol) -> None: + r""" Adds the handed over symbol to the current scope. :param symbol: a single symbol object. - :type symbol: Symbol """ + self.delete_symbol(symbol) self.declared_elements.append(symbol) - def update_variable_symbol(self, _symbol): + def update_variable_symbol(self, _symbol: Symbol) -> None: for symbol in self.get_symbols_in_this_scope(): - if (symbol.get_symbol_kind() == SymbolKind.VARIABLE - and symbol.get_symbol_name() == _symbol.get_symbol_name()): + if (symbol.get_symbol_kind() == SymbolKind.VARIABLE and symbol.get_symbol_name() == _symbol.get_symbol_name()): self.declared_elements.remove(symbol) self.add_symbol(_symbol) break - def add_scope(self, scope): - """ + def add_scope(self, scope: Scope) -> None: + r""" Adds the handed over scope as a sub-scope to the current one. :param scope: a single scope object. - :type scope: Scope """ self.declared_elements.append(scope) - def delete_symbol(self, symbol): - """ + def delete_symbol(self, symbol: Symbol) -> bool: + r""" Used to delete a single symbol from the current scope. :param symbol: a single symbol object. :type symbol: Symbol :return: True, if the element has been deleted, otherwise False. - :rtype: bool """ if symbol in self.declared_elements: self.declared_elements.remove(symbol) return True - else: - return False - def delete_scope(self, scope): - """ + return False + + def delete_scope(self, scope: Scope) -> bool: + r""" Used to delete a single sub-scope from the current scope. :param scope: a single scope object. - :type scope: Scope :return: True, if the element has been deleted, otherwise False. - :rtype: bool """ if scope in self.declared_elements: self.declared_elements.remove(scope) return True - else: - return False - def get_symbols_in_this_scope(self): - """ + return False + + def get_symbols_in_this_scope(self) -> List[Symbol]: + r""" Returns the set of elements as defined in this scope, but not in the corresponding super scope. :return: a list of symbols defined only in this scope, but not in the upper scopes. - :rtype: list """ ret = list() for elem in self.declared_elements: @@ -113,11 +121,10 @@ def get_symbols_in_this_scope(self): ret.append(elem) return ret - def get_symbols_in_complete_scope(self): - """ + def get_symbols_in_complete_scope(self) -> List[Symbol]: + r""" Returns the set of elements as defined in this scope as well as all scopes enclosing this scope. :return: a list of symbols defined in this and all enclosing scopes. - :rtype: list """ symbols = list() if self.enclosing_scope is not None: @@ -125,8 +132,8 @@ def get_symbols_in_complete_scope(self): symbols.extend(self.get_symbols_in_this_scope()) return symbols - def get_scopes(self): - """ + def get_scopes(self) -> List[Scope]: + r""" Returns the set of scopes as defined in this scope. :return: a list of scope objects :rtype: list @@ -137,36 +144,31 @@ def get_scopes(self): ret.append(elem) return ret - def resolve_to_all_scopes(self, name, kind): - """ + def resolve_to_all_scopes(self, name: str, kind: SymbolKind) -> Optional[Scope]: + r""" Resolves the handed over name and type and returns the scope in which the corresponding symbol has been defined. If element has been defined in several scopes, all scopes are returned as a list. :param name: the name of the element. - :type name: str :param kind: the type of the element - :type kind: SymbolKind :return: the scope in which the element has been defined in - :rtype: Scope """ g_scope = self.get_global_scope() scopes = g_scope.__resolve_to_scope_in_spanned_scope(name, kind) # the following step is done in order to return, whenever the list contains only one element, only this element if isinstance(scopes, list) and len(scopes) == 1: return scopes[0] - elif isinstance(scopes, list) and len(scopes) == 0: + + if isinstance(scopes, list) and len(scopes) == 0: return None - else: - return scopes - def __resolve_to_scope_in_spanned_scope(self, name, kind): - """ + return scopes + + def __resolve_to_scope_in_spanned_scope(self, name: str, kind: SymbolKind) -> List[Scope]: + r""" Private method: returns this scope or one of the sub-scopes in which the handed over symbol is defined in. :param name: the name of the element. - :type name: str :param kind: the type of the element - :type kind: SymbolKind :return: the corresponding scope object. - :rtype: Scope """ ret = list() for sim in self.get_symbols_in_this_scope(): @@ -178,182 +180,159 @@ def __resolve_to_scope_in_spanned_scope(self, name, kind): ret.extend(temp) return ret - def resolve_to_all_symbols(self, name, kind): - """ + def resolve_to_all_symbols(self, name: str, kind: SymbolKind) -> Optional[Union[Symbol, List[Symbol]]]: + r""" Resolves the name and type and returns the corresponding symbol. Caution: Here, we also take redeclaration into account. This has to be prevented - if required - by cocos. If element has been defined in several scopes, all scopes are returned as a list. :param name: the name of the element. - :type name: str :param kind: the type of the element - :type kind: SymbolType :return: a single symbol element. - :rtype: Symbol/list(Symbols) """ g_scope = self.get_global_scope() symbols = g_scope.__resolve_to_symbol_in_spanned_scope(name, kind) # the following step is done in order to return, whenever the list contains only one element, only this element if isinstance(symbols, list) and len(symbols) == 1: return symbols[0] - elif len(symbols) == 0: + + if len(symbols) == 0: return None - else: - return symbols - def __resolve_to_symbol_in_spanned_scope(self, name, kind): - """ + return symbols + + def __resolve_to_symbol_in_spanned_scope(self, name: str, kind: SymbolKind) -> List[Symbol]: + r""" Private method: returns a symbol if the handed over name and type belong to a symbol in this or one of the sub-scope. Caution: Here, we also take redeclaration into account. This has to be prevented - if required - by cocos. :param name: the name of the element. - :type name: str :param kind: the type of the element - :type kind: SymbolType :return: the corresponding symbol object. - :rtype: list(Symbol) """ ret = list() for sim in self.get_symbols_in_this_scope(): if sim.get_symbol_name() == name and sim.get_symbol_kind() == kind: ret.append(sim) + for elem in self.get_scopes(): # otherwise check if it is in one of the sub-scopes temp = elem.__resolve_to_symbol_in_spanned_scope(name, kind) if temp is not None: ret.extend(temp) + return ret - def resolve_to_scope(self, name, kind): - """ + def resolve_to_scope(self, name: str, kind: SymbolKind) -> Optional[Scope]: + r""" Returns the first scope (starting from this) in which the handed over symbol has been defined, i.e., starting from this, climbs recursively upwards unit the element has been located or no enclosing scope is left. :param name: the name of the symbol. - :type name: str :param kind: the type of the symbol, i.e., Variable,function or type. - :type kind: SymbolType :return: the first matching scope. - :rtype: Scope. """ for sim in self.get_symbols_in_this_scope(): if sim.get_symbol_name() == name and sim.get_symbol_kind() == kind: return self + if self.has_enclosing_scope(): - return self.get_enclosing_scope().resolve_to_symbol(name, kind) + return self.get_enclosing_scope().resolve_to_scope(name, kind) + return None - def resolve_to_symbol(self, name, kind): - """ + def resolve_to_symbol(self, name: str, kind: SymbolKind) -> Optional[Symbol]: + r""" Returns the first symbol corresponding to the handed over parameters, starting from this scope. Starting from this, climbs recursively upwards until the element has been located or no enclosing scope is left. :param name: the name of the symbol. - :type name: str :param kind: the type of the symbol, i.e., Variable,function or type. - :type kind: SymbolType :return: the first matching symbol. - :rtype: variable_symbol or function_symbol """ for sim in self.get_symbols_in_this_scope(): if sim.get_symbol_name() == name and sim.get_symbol_kind() == kind: return sim + if self.has_enclosing_scope(): return self.get_enclosing_scope().resolve_to_symbol(name, kind) + return None - def get_global_scope(self): - """ + def get_global_scope(self) -> Optional[Scope]: + r""" Returns the GLOBAL scope in which all sub-scopes are embedded in. :return: the global scope element. - :rtype: Scope """ if self.get_scope_type() is ScopeType.GLOBAL: return self + if self.has_enclosing_scope(): return self.get_enclosing_scope().get_global_scope() + return None - def get_enclosing_scope(self): - """ + def get_enclosing_scope(self) -> Optional[Scope]: + r""" Returns the enclosing scope if any is defined. :return: a scope symbol if available. - :rtype: Scope """ if self.enclosing_scope is not None: return self.enclosing_scope - else: - return None - def has_enclosing_scope(self): - """ + return None + + def has_enclosing_scope(self) -> bool: + r""" Returns this scope is embedded in a different scope. :return: True, if enclosed, otherwise False. - :rtype: bool """ return (self.enclosing_scope is not None) and (self.scope_type is not ScopeType.GLOBAL) - def get_source_position(self): - """ + def get_source_location(self) -> ASTSourceLocation: + r""" Returns the position in the source as enclosed by this scope :return: - :rtype: - """ - return self.source_position + r""" + return self.source_location - def get_scope_type(self): - """ + def get_scope_type(self) -> ScopeType: + r""" Returns the type of scope. :return: a ScopeType element. - :rtype: ScopeType """ return self.scope_type - def is_enclosed_in(self, scope): - """ + def is_enclosed_in(self, scope: Scope) -> bool: + r""" Returns if this scope is directly or indirectly enclosed in the handed over scope. :param scope: the scope in which this scope can be enclosed in. - :type scope Scope :return: True, if this scope is directly or indirectly enclosed in the handed over one, otherwise False. - :rtype: bool """ if self.has_enclosing_scope() and self.get_enclosing_scope() is scope: return True - elif self.has_enclosing_scope(): + + if self.has_enclosing_scope(): return self.get_enclosing_scope().is_enclosed_in(scope) - else: - return False - def get_depth_of_scope(self): - """ + return False + + def get_depth_of_scope(self) -> int: + r""" Returns the depth of this scope. :return: the level of encapsulation of this scope. - :rtype: int """ depth = 0 if self.has_enclosing_scope(): depth += 1 + self.get_enclosing_scope().get_depth_of_scope() return depth - def print_scope(self): - """ + def print_scope(self) -> str: + r""" Returns a string representation of symbol table as used for debug purpose. :return: a string representation of the scope and its sub-scope. - :rtype: str """ ret = ('-' * 2 * (self.get_depth_of_scope())) - ret += '<' + self.get_scope_type().name + ',' + str(self.get_source_position()) + '>' + '\n' + ret += '<' + self.get_scope_type().name + ',' + str(self.get_source_location()) + '>' + '\n' for elem in self.declared_elements: if isinstance(elem, Symbol): ret += ('-' * 2 * (self.get_depth_of_scope() + 1)) + elem.print_symbol() + '\n' else: ret += elem.print_scope() return ret - - -class ScopeType(Enum): - """ - This enum is used to distinguish between different types of scopes, namely: - -The global scope (neuron), in which all the sub-scopes are embedded. - -The function scope, as embedded in the global scope. - -The update scope, as embedded in the global scope. - """ - GLOBAL = 1 - UPDATE = 2 - FUNCTION = 3 diff --git a/pynestml/symbol_table/symbol_table.py b/pynestml/symbol_table/symbol_table.py index 1efb329d9..f5a73e3b2 100644 --- a/pynestml/symbol_table/symbol_table.py +++ b/pynestml/symbol_table/symbol_table.py @@ -18,10 +18,13 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Mapping + from pynestml.symbol_table.scope import Scope, ScopeType -class SymbolTable(object): +class SymbolTable: """ This class is used to store a single symbol table, consisting of scope and symbols. @@ -29,7 +32,8 @@ class SymbolTable(object): name2neuron_scope A dict from the name of a neuron to the corresponding scope. Type str->Scope source_position The source position of the overall compilation unit. Type ASTSourceLocation """ - name2neuron_scope = {} + name2neuron_scope = {} # type: Mapping[str, Scope] + name2synapse_scope = {} source_location = None @classmethod @@ -39,6 +43,7 @@ def initialize_symbol_table(cls, source_position): """ cls.source_location = source_position cls.name2neuron_scope = {} + cls.name2synapse_scope = {} @classmethod def add_neuron_scope(cls, name, scope): @@ -68,6 +73,34 @@ def delete_neuron_scope(cls, name): del cls.name2neuron_scope[name] return + @classmethod + def add_synapse_scope(cls, name, scope): + """ + Adds a single synapse scope to the set of stored scopes. + :return: a single scope element. + :rtype: Scope + """ + assert isinstance(scope, Scope), \ + '(PyNestML.SymbolTable.SymbolTable) No or wrong type of scope provided (%s)!' % type(scope) + assert (scope.get_scope_type() == ScopeType.GLOBAL), \ + '(PyNestML.SymbolTable.SymbolTable) Only global scopes can be added!' + assert isinstance(name, str), \ + '(PyNestML.SymbolTable.SymbolTable) No or wrong type of name provided (%s)!' % type(name) + if name not in cls.name2synapse_scope.keys(): + cls.name2synapse_scope[name] = scope + return + + @classmethod + def delete_synapse_scope(cls, name): + """ + Deletes a single synapse scope from the set of stored scopes. + :return: the name of the scope to delete. + :rtype: Scope + """ + if name in cls.name2synapse_scope.keys(): + del cls.name2synapse_scope[name] + return + @classmethod def clean_up_table(cls): """ @@ -75,6 +108,8 @@ def clean_up_table(cls): """ del cls.name2neuron_scope cls.name2neuron_scope = {} + del cls.name2synapse_scope + cls.name2synapse_scope = {} @classmethod def print_symbol_table(cls): @@ -86,4 +121,8 @@ def print_symbol_table(cls): ret += '--------------------------------------------------\n' ret += _name + ':\n' ret += cls.name2neuron_scope[_name].print_scope() + for _name in cls.name2synapse_scope.keys(): + ret += '--------------------------------------------------\n' + ret += _name + ':\n' + ret += cls.name2synapse_scope[_name].print_scope() return ret diff --git a/pynestml/symbols/boolean_type_symbol.py b/pynestml/symbols/boolean_type_symbol.py index a71f8aa76..035b02992 100644 --- a/pynestml/symbols/boolean_type_symbol.py +++ b/pynestml/symbols/boolean_type_symbol.py @@ -45,6 +45,9 @@ def __add__(self, other): return self.binary_operation_not_defined_error('+', other) def is_castable_to(self, _other_type): + if _other_type is None: + return False + if super(BooleanTypeSymbol, self).is_castable_to(_other_type): return True from pynestml.symbols.real_type_symbol import RealTypeSymbol diff --git a/pynestml/symbols/predefined_functions.py b/pynestml/symbols/predefined_functions.py index 271d4e59e..60cad2b2b 100644 --- a/pynestml/symbols/predefined_functions.py +++ b/pynestml/symbols/predefined_functions.py @@ -18,11 +18,13 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Mapping + from pynestml.symbols.function_symbol import FunctionSymbol from pynestml.symbols.predefined_types import PredefinedTypes -class PredefinedFunctions(object): +class PredefinedFunctions: """ This class is used to represent all predefined functions of NESTML. @@ -75,7 +77,8 @@ class PredefinedFunctions(object): ABS = 'abs' INTEGRATE_ODES = 'integrate_odes' CONVOLVE = 'convolve' - name2function = {} # a map dict from function-names to symbols + DELIVER_SPIKE = 'deliver_spike' + name2function = {} # type: Mapping[str, FunctionSymbol] @classmethod def register_functions(cls): @@ -106,8 +109,16 @@ def register_functions(cls): cls.__register_abs_function() cls.__register_integrated_odes_function() cls.__register_convolve() + cls.__register_deliver_spike() return + @classmethod + def register_function(cls, name, params, return_type, element_reference): + symbol = FunctionSymbol(name=name, param_types=params, + return_type=return_type, + element_reference=element_reference, is_predefined=True) + cls.name2function[name] = symbol + @classmethod def __register_time_steps_function(cls): """ @@ -148,7 +159,9 @@ def __register_print_ln_function(cls): """ Registers the print-line function. """ - symbol = FunctionSymbol(name=cls.PRINTLN, param_types=list(), + params = list() + params.append(PredefinedTypes.get_string_type()) + symbol = FunctionSymbol(name=cls.PRINTLN, param_types=params, return_type=PredefinedTypes.get_void_type(), element_reference=None, is_predefined=True) cls.name2function[cls.PRINTLN] = symbol @@ -369,6 +382,19 @@ def __register_integrated_odes_function(cls): element_reference=None, is_predefined=True) cls.name2function[cls.INTEGRATE_ODES] = symbol + @classmethod + def __register_deliver_spike(cls): + """ + Registers the deliver-spike function. + """ + params = list() + params.append(PredefinedTypes.get_real_type()) + params.append(PredefinedTypes.get_type('ms')) + symbol = FunctionSymbol(name=cls.DELIVER_SPIKE, param_types=params, + return_type=PredefinedTypes.get_real_type(), + element_reference=None, is_predefined=True) + cls.name2function[cls.DELIVER_SPIKE] = symbol + @classmethod def __register_convolve(cls): """ diff --git a/pynestml/symbols/predefined_types.py b/pynestml/symbols/predefined_types.py index 0295e28a2..5707abef9 100644 --- a/pynestml/symbols/predefined_types.py +++ b/pynestml/symbols/predefined_types.py @@ -18,21 +18,25 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Mapping + from copy import copy from astropy.units.core import CompositeUnit from astropy.units.quantity import Quantity from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.unit_type_symbol import UnitTypeSymbol from pynestml.symbols.template_type_symbol import TemplateTypeSymbol +from pynestml.symbols.type_symbol import TypeSymbol +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages from pynestml.utils.type_dictionary import TypeDictionary from pynestml.utils.unit_type import UnitType -class PredefinedTypes(object): +class PredefinedTypes: """ This class represents all types which are predefined in the system. @@ -44,7 +48,7 @@ class PredefinedTypes(object): STRING_TYPE The identifier of the type 'string'. Type: str INTEGER_TYPE The identifier of the type 'integer'. Type: str """ - name2type = {} + name2type = {} # type: Mapping[str, TypeSymbol] REAL_TYPE = 'real' VOID_TYPE = 'void' BOOLEAN_TYPE = 'boolean' @@ -138,12 +142,6 @@ def get_types(cls): """ return cls.name2type - @classmethod - def get_buffer_type_if_exists(cls, name): - result = copy(cls.get_type(name)) - result.is_buffer = True - return result - @classmethod def get_type(cls, name): """ @@ -245,9 +243,6 @@ def register_type(cls, symbol): """ if not symbol.is_primitive() and symbol.unit.get_name() not in cls.name2type.keys(): cls.name2type[symbol.unit.get_name()] = symbol - code, message = Messages.get_new_type_registered(symbol.unit.get_name()) - Logger.log_message(code=code, message=message, log_level=LoggingLevel.INFO) - return @classmethod def register_unit(cls, unit): diff --git a/pynestml/symbols/predefined_units.py b/pynestml/symbols/predefined_units.py index 3f9a4ad49..f21ef8639 100644 --- a/pynestml/symbols/predefined_units.py +++ b/pynestml/symbols/predefined_units.py @@ -18,6 +18,9 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Mapping, Sequence + from astropy import units as u from pynestml.utils.logger import Logger, LoggingLevel @@ -25,13 +28,13 @@ from pynestml.utils.unit_type import UnitType -class PredefinedUnits(object): +class PredefinedUnits: """ This class represents a collection of physical units. Units can be retrieved by means of get_unit(name). Attribute: name2unit (dict): Dict of all predefined units, map from name to unit object. """ - name2unit = None + name2unit = {} # type: Mapping[str, UnitType] @classmethod def register_units(cls): @@ -53,13 +56,11 @@ def register_units(cls): cls.name2unit[str(unit_name)] = temp_unit @classmethod - def get_unit(cls, name): + def get_unit(cls, name: str) -> UnitType: """ Returns a single UnitType if the corresponding unit has been predefined. :param name: the name of a unit - :type name: str :return: a single UnitType object, or None - :rtype: UnitType """ if name in cls.name2unit.keys(): return cls.name2unit[name] @@ -69,31 +70,27 @@ def get_unit(cls, name): return None @classmethod - def is_unit(cls, name): + def is_unit(cls, name: str) -> bool: """ Indicates whether the handed over name represents a stored unit. :param name: a single name - :type name: str :return: True if unit name, otherwise False. - :rtype: bool """ return name in cls.name2unit.keys() @classmethod - def register_unit(cls, unit): + def register_unit(cls, unit: UnitType) -> None: """ Registers the handed over unit in the set of the predefined units. :param unit: a single unit type. - :type unit: UnitType """ if unit.get_name() is not cls.name2unit.keys(): cls.name2unit[unit.get_name()] = unit @classmethod - def get_units(cls): + def get_units(cls) -> Sequence[UnitType]: """ Returns the list of all currently defined units. :return: a list of all defined units. - :rtype: list(UnitType) """ return cls.name2unit diff --git a/pynestml/symbols/predefined_variables.py b/pynestml/symbols/predefined_variables.py index 7ec4b8bd1..bdab262d1 100644 --- a/pynestml/symbols/predefined_variables.py +++ b/pynestml/symbols/predefined_variables.py @@ -18,16 +18,19 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import Mapping + from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.variable_symbol import VariableSymbol, BlockType, VariableType -class PredefinedVariables(object): +class PredefinedVariables: """ This class is used to store all predefined variables as generally available. """ - name2variable = {} # type: dict -> VariableSymbol - E_CONSTANT = 'e' # type: str + name2variable = {} # type: Mapping[str, VariableSymbol] + E_CONSTANT = 'e' # type: str TIME_CONSTANT = 't' # type: str @classmethod @@ -86,7 +89,7 @@ def get_time_constant(cls): @classmethod def get_euler_constant(cls): """ - Returns a copy of the variable symbol representing the euler constant t. + Returns a copy of the variable symbol representing the euler constant e. :return: a variable symbol. :rtype: VariableSymbol """ diff --git a/pynestml/symbols/symbol.py b/pynestml/symbols/symbol.py index 760797807..1e294566b 100644 --- a/pynestml/symbols/symbol.py +++ b/pynestml/symbols/symbol.py @@ -23,7 +23,7 @@ from enum import Enum -class Symbol(object): +class Symbol: """ This abstract class represents a super-class for all concrete symbols as stored in a symbol table. Attributes: @@ -69,11 +69,10 @@ def get_corresponding_scope(self): """ return self.scope - def get_symbol_name(self): + def get_symbol_name(self) -> str: """ Returns the name of this symbol. :return: the name of the symbol. - :rtype: str """ return self.name diff --git a/pynestml/symbols/unit_type_symbol.py b/pynestml/symbols/unit_type_symbol.py index 746a910ca..9dc21f9ff 100644 --- a/pynestml/symbols/unit_type_symbol.py +++ b/pynestml/symbols/unit_type_symbol.py @@ -141,7 +141,8 @@ def attempt_magnitude_cast(self, other): code, message = Messages.get_implicit_magnitude_conversion(self, other, factor) Logger.log_message(code=code, message=message, error_position=self.referenced_object.get_source_position(), - log_level=LoggingLevel.WARNING) + log_level=LoggingLevel.INFO) + return self else: return self.binary_operation_not_defined_error('+/-', other) diff --git a/pynestml/symbols/variable_symbol.py b/pynestml/symbols/variable_symbol.py index 9bef9d232..eff243bd1 100644 --- a/pynestml/symbols/variable_symbol.py +++ b/pynestml/symbols/variable_symbol.py @@ -18,8 +18,8 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from copy import copy +from copy import copy from enum import Enum from pynestml.meta_model.ast_expression import ASTExpression @@ -27,15 +27,40 @@ from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.meta_model.ast_ode_equation import ASTOdeEquation +from pynestml.symbol_table.scope import Scope from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.symbol import Symbol -from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.symbol import Symbol, SymbolKind +from pynestml.symbols.type_symbol import TypeSymbol from pynestml.symbols.unit_type_symbol import UnitTypeSymbol from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages -from astropy import units + +class VariableType(Enum): + """ + Indicates to which type of variable this is. + """ + KERNEL = 0 + VARIABLE = 1 + BUFFER = 2 + EQUATION = 3 + TYPE = 4 + + +class BlockType(Enum): + """ + Indicates in which type of block this variable has been declared. + """ + STATE = 1 + PARAMETERS = 2 + COMMON_PARAMETERS = 3 + INTERNALS = 4 + EQUATION = 5 + LOCAL = 6 + INPUT = 7 + OUTPUT = 8 + PREDEFINED = 9 class VariableSymbol(Symbol): @@ -43,61 +68,83 @@ class VariableSymbol(Symbol): This class is used to store a single variable symbol containing all required information. Attributes: - block_type The type of block in which this symbol has been declared. Type: BlockType - vector_parameter The parameter indicating the position in an array. Type: str - declaring_expression The rhs defining the value of this symbol. Type: ASTExpression - is_predefined Indicates whether this symbol is predefined, e.g., t or e. Type: bool - is_function Indicates whether this symbol belongs to a function. Type: bool - is_recordable Indicates whether this symbol belongs to a recordable element. Type: bool - type_symbol The concrete type of this variable. - ode_declaration Used to store the corresponding ode declaration. + block_type The type of block in which this symbol has been declared. Type: BlockType + vector_parameter The parameter indicating the position in an array. Type: str + delay_parameter The parameter indicating the delay value for this variable. Type: str + declaring_expression The rhs defining the value of this symbol. Type: ASTExpression + is_predefined Indicates whether this symbol is predefined, e.g., t or e. Type: bool + is_inline_expression Indicates whether this symbol belongs to an inline expression. Type: bool + is_recordable Indicates whether this symbol belongs to a recordable element. Type: bool + type_symbol The concrete type of this variable. + ode_declaration Used to store the corresponding ode declaration. is_conductance_based Indicates whether this buffer is conductance based. - initial_value Indicates the initial value if such is declared. - variable_type The type of the variable, either a kernel, or buffer or function. Type: VariableType + initial_value Indicates the initial value if such is declared. + variable_type The type of the variable, either a kernel, or buffer or function. Type: VariableType """ - def __init__(self, element_reference=None, scope=None, name=None, block_type=None, vector_parameter=None, - declaring_expression=None, is_predefined=False, is_function=False, is_recordable=False, - type_symbol=None, initial_value=None, variable_type=None): + def __init__(self, element_reference=None, scope: Scope=None, name: str=None, block_type: BlockType=None, + vector_parameter: str=None, delay_parameter: str=None, declaring_expression: ASTExpression=None, + is_predefined: bool=False, is_inline_expression: bool=False, is_recordable: bool=False, + type_symbol: TypeSymbol=None, initial_value: ASTExpression=None, variable_type: VariableType=None, + decorators=None, namespace_decorators=None): """ Standard constructor. :param element_reference: a reference to the first element where this type has been used/defined - :type element_reference: Object (or None, if predefined) :param scope: the scope in which this type is defined in - :type scope: Scope :param name: the name of the type symbol - :type name: str :param block_type: the type of block in which this element has been defined in - :type block_type: BlockType :param vector_parameter: the parameter indicating a position in an array - :type vector_parameter: str :param declaring_expression: a rhs declaring the value of this symbol. - :type declaring_expression: ASTExpression :param is_predefined: indicates whether this element represents a predefined variable, e.g., e or t - :type is_predefined: bool - :param is_function: indicates whether this element represents a function (aka. alias) - :type is_function: bool + :param is_inline_expression: Indicates whether this symbol belongs to an inline expression. :param is_recordable: indicates whether this elements is recordable or not. - :type is_recordable: bool :param type_symbol: a type symbol representing the concrete type of this variable - :type type_symbol: type_symbol :param initial_value: the initial value if such an exists - :type initial_value: ASTExpression :param variable_type: the type of the variable - :type variable_type: VariableType + :param decorators: a list of decorator keywords + :type decorators list + :param namespace_decorators a list of namespace decorators + :type namespace_decorators list """ super(VariableSymbol, self).__init__(element_reference=element_reference, scope=scope, name=name, symbol_kind=SymbolKind.VARIABLE) self.block_type = block_type self.vector_parameter = vector_parameter + self.delay_parameter = delay_parameter self.declaring_expression = declaring_expression self.is_predefined = is_predefined - self.is_function = is_function + self.is_inline_expression = is_inline_expression self.is_recordable = is_recordable self.type_symbol = type_symbol self.initial_value = initial_value self.variable_type = variable_type self.ode_or_kernel = None + if decorators is None: + decorators = [] + if namespace_decorators is None: + namespace_decorators = {} + self.decorators = decorators + self.namespace_decorators = namespace_decorators + + def is_homogeneous(self): + return PyNestMLLexer.DECORATOR_HOMOGENEOUS in self.decorators + + def has_decorators(self): + return len(self.decorators) > 0 + + def get_decorators(self): + """ + Returns PyNESTMLLexer static variable codes + """ + return self.decorators + + def get_namespace_decorators(self): + return self.namespace_decorators + + def get_namespace_decorator(self, namespace): + if namespace in self.namespace_decorators.keys(): + return self.namespace_decorators[namespace] + return '' def has_vector_parameter(self): """ @@ -107,6 +154,13 @@ def has_vector_parameter(self): """ return self.vector_parameter is not None and type(self.vector_parameter) == str + def has_delay_parameter(self): + """ + Returns whether this variable has a delay value associated with it. + :return: bool + """ + return self.delay_parameter is not None and type(self.delay_parameter) == str + def get_block_type(self): """ Returns the block type @@ -123,6 +177,19 @@ def get_vector_parameter(self): """ return self.vector_parameter + def get_delay_parameter(self): + """ + Returns the delay value associated with this variable + :return: the delay parameter + """ + return self.delay_parameter + + def set_delay_parameter(self, delay): + """ + Sets the delay value for this variable + """ + self.delay_parameter = delay + def get_declaring_expression(self): """ Returns the rhs declaring the value of this symbol. @@ -135,40 +202,35 @@ def has_declaring_expression(self) -> bool: """ Indicates whether a declaring rhs is present. :return: True if present, otherwise False. - :rtype: bool """ return self.declaring_expression is not None and (isinstance(self.declaring_expression, ASTSimpleExpression) or isinstance(self.declaring_expression, ASTExpression)) - def is_spike_buffer(self) -> bool: + def is_spike_input_port(self) -> bool: """ - Returns whether this symbol represents a spike buffer. - :return: True if spike buffer, otherwise False. - :rtype: bool + Returns whether this symbol represents a spike input port. + :return: True if spike input port, otherwise False. """ return isinstance(self.get_referenced_object(), ASTInputPort) and self.get_referenced_object().is_spike() - def is_current_buffer(self) -> bool: + def is_continuous_input_port(self) -> bool: """ - Returns whether this symbol represents a current buffer. - :return: True if current buffer, otherwise False. - :rtype: bool + Returns whether this symbol represents a continuous time input port. + :return: True if continuous time input port, otherwise False. """ - return isinstance(self.get_referenced_object(), ASTInputPort) and self.get_referenced_object().is_current() + return isinstance(self.get_referenced_object(), ASTInputPort) and self.get_referenced_object().is_continuous() def is_excitatory(self) -> bool: """ - Returns whether this symbol represents a buffer of type excitatory. + Returns whether this symbol represents an input port with qualifier excitatory. :return: True if is excitatory, otherwise False. - :rtype: bool """ return isinstance(self.get_referenced_object(), ASTInputPort) and self.get_referenced_object().is_excitatory() def is_inhibitory(self) -> bool: """ - Returns whether this symbol represents a buffer of type inhibitory. + Returns whether this symbol represents an input port with qualifier inhibitory. :return: True if is inhibitory, otherwise False. - :rtype: bool """ return isinstance(self.get_referenced_object(), ASTInputPort) and self.get_referenced_object().is_inhibitory() @@ -176,7 +238,6 @@ def is_state(self) -> bool: """ Returns whether this variable symbol has been declared in a state block. :return: True if declared in a state block, otherwise False. - :rtype: bool """ return self.block_type == BlockType.STATE @@ -186,7 +247,7 @@ def is_parameters(self) -> bool: :return: True if declared in a parameters block, otherwise False. :rtype: bool """ - return self.block_type == BlockType.PARAMETERS + return self.block_type in [BlockType.PARAMETERS, BlockType.COMMON_PARAMETERS] def is_internals(self) -> bool: """ @@ -212,35 +273,24 @@ def is_local(self) -> bool: """ return self.block_type == BlockType.LOCAL - def is_input_buffer_current(self) -> bool: - """ - Returns whether this variable symbol has been declared as a input-buffer current element. - :return: True if input-buffer current, otherwise False. - :rtype: bool - """ - return self.block_type == BlockType.INPUT_BUFFER_CURRENT - - def is_input_buffer_spike(self) -> bool: + def is_input(self) -> bool: """ - Returns whether this variable symbol has been declared as a input-buffer spike element. - :return: True if input-buffer spike, otherwise False. - :rtype: bool + Returns whether this variable symbol has been declared as an input port. + :return: True if input port, otherwise False. """ - return self.block_type == BlockType.INPUT_BUFFER_SPIKE + return self.block_type == BlockType.INPUT def is_buffer(self) -> bool: """ Returns whether this variable symbol represents a buffer or not. :return: True if buffer, otherwise False. - :rtype: bool """ return self.variable_type == VariableType.BUFFER def is_output(self) -> bool: """ - Returns whether this variable symbol has been declared as a output-buffer element. + Returns whether this variable symbol has been declared as output block element. :return: True if output element, otherwise False. - :rtype: bool """ return self.block_type == BlockType.OUTPUT @@ -248,18 +298,9 @@ def is_kernel(self) -> bool: """ Returns whether this variable belongs to the definition of a kernel. :return: True if part of a kernel definition, otherwise False. - :rtype: bool """ return self.variable_type == VariableType.KERNEL - def is_init_values(self) -> bool: - """ - Returns whether this variable belongs to the definition of a initial value. - :return: True if part of a initial value, otherwise False. - :rtype: bool - """ - return self.block_type == BlockType.INITIAL_VALUES - def print_symbol(self): if self.get_referenced_object() is not None: source_position = str(self.get_referenced_object().get_source_position()) @@ -268,7 +309,7 @@ def print_symbol(self): vector_value = self.get_vector_parameter() if self.has_vector_parameter() else 'none' typ_e = self.get_type_symbol().print_symbol() recordable = 'recordable, ' if self.is_recordable else '' - func = 'function, ' if self.is_function else '' + func = 'inline, ' if self.is_inline_expression else '' conductance_based = 'conductance based, ' if self.is_conductance_based else '' return 'VariableSymbol[' + self.get_symbol_name() + ', type=' \ + typ_e + ', ' + str(self.block_type) + ', ' + recordable + func + conductance_based \ @@ -319,7 +360,7 @@ def set_ode_or_kernel(self, expression): def is_conductance_based(self) -> bool: """ - Indicates whether this element is conductance based, based on the physical units of the spike buffer. If the unit can be cast to Siemens, the function returns True, otherwise it returns False. + Indicates whether this element is conductance based, based on the physical units of the spike input port. If the unit can be cast to Siemens, the function returns True, otherwise it returns False. :return: True if conductance based, otherwise False. """ @@ -391,7 +432,7 @@ def equals(self, other): and self.get_vector_parameter() == other.get_vector_parameter() and self.declaring_expression == other.declaring_expression and self.is_predefined == other.is_predefined - and self.is_function == other.is_function + and self.is_inline_expression == other.is_inline_expression and self.is_conductance_based == other.is_conductance_based and self.is_recordable == other.is_recordable) @@ -410,30 +451,3 @@ def print_comment(self, prefix=None): ret += (prefix if prefix is not None else '') + comment + \ ('\n' if self.get_comment().index(comment) < len(self.get_comment()) - 1 else '') return ret - - -class VariableType(Enum): - """ - Indicates to which type of variable this is. - """ - KERNEL = 0 - VARIABLE = 1 - BUFFER = 2 - EQUATION = 3 - TYPE = 4 - - -class BlockType(Enum): - """ - Indicates in which type of block this variable has been declared. - """ - STATE = 1 - PARAMETERS = 2 - INTERNALS = 3 - INITIAL_VALUES = 4 - EQUATION = 5 - LOCAL = 6 - INPUT_BUFFER_CURRENT = 7 - INPUT_BUFFER_SPIKE = 8 - OUTPUT = 9 - PREDEFINED = 10 diff --git a/pynestml/transformers/__init__.py b/pynestml/transformers/__init__.py new file mode 100644 index 000000000..f75182c58 --- /dev/null +++ b/pynestml/transformers/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# +# __init__.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +__all__ = [ + 'illegal_variable_name_transformer', + 'synapse_post_neuron_transformer', + 'transformer' +] diff --git a/pynestml/transformers/illegal_variable_name_transformer.py b/pynestml/transformers/illegal_variable_name_transformer.py new file mode 100644 index 000000000..9bf3aa9ae --- /dev/null +++ b/pynestml/transformers/illegal_variable_name_transformer.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +# +# illegal_variable_name_transformer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +from typing import Any, Callable, List, Mapping, Optional, Tuple, Union, Sequence + +from pynestml.meta_model.ast_node import ASTNode +from pynestml.transformers.transformer import Transformer +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor +from pynestml.visitors.ast_visitor import ASTVisitor + + +class IllegalVariableNameTransformer(Transformer): + r"""Perform a model transformation step, for instance, rewriting disallowed variable names like "lambda" because it conflicts with a keyword.""" + + _default_options = { + "forbidden_names": [], + "strategy": "append_underscores" + } + + fix_name_func_: Callable[[str], str] # callable to transform a variable name (string to string) + rewritten_names_: List[Tuple[str, str]] # list of tuples (name, name_orig), one for each rewritten variable + + class VariableNameRewriterVisitor(ASTVisitor): + forbidden_names_: List[str] + fix_name_func_: Callable[[str], str] + + def __init__(self, forbidden_names: List[str], fix_name_func: Callable[[str], str]): + super().__init__() + self.forbidden_names_ = forbidden_names + self.fix_name_func_ = fix_name_func + + def visit_simple_expression(self, node): + if node.is_variable(): + var = node.get_variable() + if var.get_name() in self.forbidden_names_: + var.set_name(self.fix_name_func_(var.get_name())) + + def visit_declaration(self, node): + for var in node.get_variables(): + if var.get_name() in self.forbidden_names_: + var.set_name(self.fix_name_func_(var.get_name())) + + def visit_assignment(self, node): + var = node.get_variable() + if var.get_name() in self.forbidden_names_: + var.set_name(self.fix_name_func_(var.get_name())) + + def visit_expression(self, node): + for var in node.get_variables(): + if var.get_name() in self.forbidden_names_: + var.set_name(self.fix_name_func_(var.get_name())) + + def visit_ode_equation(self, node): + var = node.lhs + if var.get_name() in self.forbidden_names_: + var.set_name(self.fix_name_func_(var.get_name())) + + def __init__(self, options: Optional[Mapping[str, Any]]=None): + super(Transformer, self).__init__(options) + if self.get_option("strategy") == "append_underscores": + self.fix_name_func_ = self.fix_name_append_underscores_ + else: + raise Exception("Unknown strategy: \"" + self.get_option("strategy") + "\"") + self.rewritten_names_ = [] + + def fix_name_append_underscores_(self, name: str) -> str: + name_orig = name + while name in self.get_option("forbidden_names"): + name += "_" + + if not name == name_orig and not (name, name_orig) in self.rewritten_names_: + self.rewritten_names_.append((name, name_orig)) + msg = "Rewrote variable \"" + name_orig + "\" to \"" + name + "\"" + Logger.log_message(None, None, msg, None, LoggingLevel.WARNING) + + return name + + def transform(self, models: Union[ASTNode, Sequence[ASTNode]]) -> Union[ASTNode, Sequence[ASTNode]]: + single = False + if isinstance(models, ASTNode): + single = True + models = [models] + + for model in models: + model.accept(self.VariableNameRewriterVisitor(self.get_option("forbidden_names"), self.fix_name_func_)) + model.accept(ASTSymbolTableVisitor()) + + if single: + return models[0] + + return models diff --git a/pynestml/transformers/synapse_post_neuron_transformer.py b/pynestml/transformers/synapse_post_neuron_transformer.py new file mode 100644 index 000000000..80a45d6dd --- /dev/null +++ b/pynestml/transformers/synapse_post_neuron_transformer.py @@ -0,0 +1,507 @@ +# -*- coding: utf-8 -*- +# +# synapse_post_neuron_transformer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +from typing import Any, Sequence, Mapping, Optional, Union + +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_neuron_or_synapse import ASTNeuronOrSynapse +from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import BlockType +from pynestml.transformers.transformer import Transformer +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger +from pynestml.utils.logger import LoggingLevel +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor +from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor +from pynestml.visitors.ast_visitor import ASTVisitor + + +class SynapsePostNeuronTransformer(Transformer): + r"""In a (pre neuron, synapse, post neuron) tuple, process (synapse, post_neuron) to move all variables that are only triggered by postsynaptic events to the postsynaptic neuron.""" + + _default_options = { + "neuron_synapse_pairs": [] + } + + def __init__(self, options: Optional[Mapping[str, Any]] = None): + super(Transformer, self).__init__(options) + + def is_special_port(self, special_type: str, port_name: str, neuron_name: str, synapse_name: str) -> bool: + """ + Check if a port by the given name is specified as connecting to the postsynaptic neuron. Only makes sense + for synapses. + """ + assert special_type in ["post", "vt"] + if not "neuron_synapse_pairs" in self._options.keys(): + return False + + for neuron_synapse_pair in self._options["neuron_synapse_pairs"]: + if not (neuron_name in [neuron_synapse_pair["neuron"], neuron_synapse_pair["neuron"] + FrontendConfiguration.suffix] + and synapse_name in [neuron_synapse_pair["synapse"], neuron_synapse_pair["synapse"] + FrontendConfiguration.suffix]): + continue + + if not special_type + "_ports" in neuron_synapse_pair.keys(): + return False + + post_ports = neuron_synapse_pair[special_type + "_ports"] + if not isinstance(post_ports, list): + # only one port name given, not a list + return port_name == post_ports + + for post_port in post_ports: + if type(post_port) is not str and len(post_port) == 2: # (syn_port_name, neuron_port_name) tuple + post_port = post_port[0] + if type(post_port) is not str and len(post_port) == 1: # (syn_port_name) + return post_port[0] == port_name + if port_name == post_port: + return True + + return False + + def is_continuous_port(self, port_name: str, parent_node: ASTNeuronOrSynapse): + for port in parent_node.get_input_blocks().get_input_ports(): + if port.is_continuous() and port_name == port.get_name(): + return True + return False + + def is_post_port(self, port_name: str, neuron_name: str, synapse_name: str) -> bool: + return self.is_special_port("post", port_name, neuron_name, synapse_name) + + def is_vt_port(self, port_name: str, neuron_name: str, synapse_name: str) -> bool: + return self.is_special_port("vt", port_name, neuron_name, synapse_name) + + def get_spiking_post_port_names(self, synapse, neuron_name: str, synapse_name: str): + post_port_names = [] + for port in synapse.get_input_blocks().get_input_ports(): + if self.is_post_port(port.name, neuron_name, synapse_name) and port.is_spike(): + post_port_names.append(port.get_name()) + return post_port_names + + def get_post_port_names(self, synapse, neuron_name: str, synapse_name: str): + post_port_names = [] + for port in synapse.get_input_blocks().get_input_ports(): + if self.is_post_port(port.name, neuron_name, synapse_name): + post_port_names.append(port.get_name()) + return post_port_names + + def get_vt_port_names(self, synapse, neuron_name: str, synapse_name: str): + post_port_names = [] + for port in synapse.get_input_blocks().get_input_ports(): + if self.is_vt_port(port.name, neuron_name, synapse_name): + post_port_names.append(port.get_name()) + return post_port_names + + def get_neuron_var_name_from_syn_port_name(self, port_name: str, neuron_name: str, synapse_name: str) -> Optional[str]: + """ + Check if a port by the given name is specified as connecting to the postsynaptic neuron. Only makes sense for synapses. + """ + if not "neuron_synapse_pairs" in self._options.keys(): + return False + + for neuron_synapse_pair in self._options["neuron_synapse_pairs"]: + if not (neuron_name in [neuron_synapse_pair["neuron"], neuron_synapse_pair["neuron"] + FrontendConfiguration.suffix] + and synapse_name in [neuron_synapse_pair["synapse"], neuron_synapse_pair["synapse"] + FrontendConfiguration.suffix]): + continue + + if not "post_ports" in neuron_synapse_pair.keys(): + return None + + post_ports = neuron_synapse_pair["post_ports"] + + for post_port in post_ports: + if type(post_port) is not str and len(post_port) == 2: # (syn_port_name, neuron_var_name) tuple + if port_name == post_port[0]: + return post_port[1] + + return None + + return None + + def get_convolve_with_not_post_vars(self, node, neuron_name, synapse_name, parent_node): + class ASTVariablesUsedInConvolutionVisitor(ASTVisitor): + _variables = [] + + def __init__(self, node: ASTNode, parent_node: ASTNode, codegen_class): + super(ASTVariablesUsedInConvolutionVisitor, self).__init__() + self.node = node + self.parent_node = parent_node + self.codegen_class = codegen_class + + def visit_function_call(self, node): + func_name = node.get_name() + if func_name == "convolve": + symbol_buffer = node.get_scope().resolve_to_symbol(str(node.get_args()[1]), + SymbolKind.VARIABLE) + input_port = ASTUtils.get_input_port_by_name( + self.parent_node.get_input_blocks(), symbol_buffer.name) + if input_port and not self.codegen_class.is_post_port(input_port.name, neuron_name, synapse_name): + kernel_name = node.get_args()[0].get_variable().name + self._variables.append(kernel_name) + + found_parent_assignment = False + node_ = node + while not found_parent_assignment: + node_ = self.parent_node.get_parent(node_) + # XXX TODO also needs to accept normal ASTExpression, ASTAssignment? + if isinstance(node_, ASTInlineExpression): + found_parent_assignment = True + var_name = node_.get_variable_name() + self._variables.append(var_name) + + if node is None: + return [] + + visitor = ASTVariablesUsedInConvolutionVisitor(node, parent_node, self) + node.accept(visitor) + return visitor._variables + + def get_all_variables_assigned_to(self, node): + class ASTAssignedToVariablesFinderVisitor(ASTVisitor): + _variables = [] + + def __init__(self, synapse): + super(ASTAssignedToVariablesFinderVisitor, self).__init__() + self.synapse = synapse + + def visit_assignment(self, node): + symbol = node.get_scope().resolve_to_symbol(node.get_variable().get_complete_name(), SymbolKind.VARIABLE) + assert symbol is not None # should have been checked in a CoCo before + self._variables.append(symbol) + + if node is None: + return [] + + visitor = ASTAssignedToVariablesFinderVisitor(node) + node.accept(visitor) + + return [v.name for v in visitor._variables] + + def transform_neuron_synapse_pair_(self, neuron, synapse): + r""" + "Co-generation" or in-tandem generation of neuron and synapse code. + + Does not modify existing neurons or synapses, but returns lists with additional elements representing new pair neuron and synapse + """ + + new_neuron = neuron.clone() + new_synapse = synapse.clone() + + # + # suffix for variables that will be transferred to neuron + # + + var_name_suffix = "__for_" + synapse.get_name() + + # + # determine which variables and dynamics in synapse can be transferred to neuron + # + + all_state_vars = ASTUtils.all_variables_defined_in_block(synapse.get_state_blocks()) + all_state_vars = [var.get_complete_name() for var in all_state_vars] + + # add names of convolutions + all_state_vars += ASTUtils.get_all_variables_used_in_convolutions(synapse.get_equations_blocks(), synapse) + + # add names of kernels + kernel_buffers = ASTUtils.generate_kernel_buffers_(synapse, synapse.get_equations_blocks()) + all_state_vars += [var.name for k in kernel_buffers for var in k[0].variables] + + # if any variable is assigned to in any block that is not connected to a postsynaptic port + strictly_synaptic_vars = [] + for port in new_synapse.get_input_blocks().get_input_ports(): + if not self.is_post_port(port.name, neuron.name, synapse.name): + strictly_synaptic_vars += self.get_all_variables_assigned_to( + synapse.get_on_receive_block(port.name)) + strictly_synaptic_vars += self.get_all_variables_assigned_to(synapse.get_update_blocks()) + + convolve_with_not_post_vars = self.get_convolve_with_not_post_vars( + synapse.get_equations_blocks(), neuron.name, synapse.name, synapse) + + syn_to_neuron_state_vars = list(set(all_state_vars) - (set(strictly_synaptic_vars) | set(convolve_with_not_post_vars))) + Logger.log_message(None, -1, "State variables that will be moved from synapse to neuron: " + str(syn_to_neuron_state_vars), + None, LoggingLevel.INFO) + + # + # collect all the variable/parameter/kernel/function/etc. names used in defining expressions of `syn_to_neuron_state_vars` + # + + recursive_vars_used = ASTUtils.recursive_dependent_variables_search(syn_to_neuron_state_vars, synapse) + new_neuron.recursive_vars_used = recursive_vars_used + new_neuron._transferred_variables = [neuron_state_var + var_name_suffix + for neuron_state_var in syn_to_neuron_state_vars + if new_synapse.get_kernel_by_name(neuron_state_var) is None] + + # + # collect all the parameters + # + + all_declared_params = [s.get_variables() for s in new_synapse.get_parameter_blocks().get_declarations()] + all_declared_params = sum(all_declared_params, []) + all_declared_params = [var.name for var in all_declared_params] + + syn_to_neuron_params = [v for v in recursive_vars_used if v in all_declared_params] + + # parameters used in the declarations of the state variables + vars_used = [] + for var in syn_to_neuron_state_vars: + decls = ASTUtils.get_declarations_from_block(var, neuron.get_state_blocks()) + for decl in decls: + if decl.has_expression(): + vars_used.extend(ASTUtils.collect_variable_names_in_expression(decl.get_expression())) + + # parameters used in equations + vars_used.extend(ASTUtils.collects_vars_used_in_equation(var, neuron.get_equations_blocks())) + + syn_to_neuron_params.extend([var for var in vars_used if var in all_declared_params]) + + Logger.log_message(None, -1, "Parameters that will be copied from synapse to neuron: " + str(syn_to_neuron_params), + None, LoggingLevel.INFO) + + # + # collect all the internal parameters + # + + # XXX: TODO + + # + # move state variable declarations from synapse to neuron + # + + for state_var in syn_to_neuron_state_vars: + decls = ASTUtils.move_decls(state_var, + neuron.get_state_blocks(), + synapse.get_state_blocks(), + var_name_suffix, + block_type=BlockType.STATE) + ASTUtils.add_suffix_to_variable_names(decls, var_name_suffix) + + # + # move defining equations for variables from synapse to neuron + # + + for state_var in syn_to_neuron_state_vars: + Logger.log_message(None, -1, "Moving state var defining equation(s) " + str(state_var), + None, LoggingLevel.INFO) + decls = ASTUtils.equations_from_block_to_block(state_var, + new_synapse.get_equations_block(), + new_neuron.get_equations_block(), + var_name_suffix, + mode="move") + ASTUtils.add_suffix_to_variable_names(decls, var_name_suffix) + + # + # move initial values for equations + # + + for state_var in syn_to_neuron_state_vars: + Logger.log_message(None, -1, "Moving state variables for equation(s) " + str(state_var), + None, LoggingLevel.INFO) + ASTUtils.move_decls(var_name=state_var, + from_block=new_synapse.get_state_blocks(), + to_block=new_neuron.get_state_blocks(), + var_name_suffix=var_name_suffix, + block_type=BlockType.STATE, + mode="move") + + # + # mark variables in the neuron pertaining to synapse postsynaptic ports + # + # convolutions with them ultimately yield variable updates when post neuron calls emit_spike() + # + + def mark_post_ports(neuron, synapse, mark_node): + post_ports = [] + + def mark_post_port(_expr=None): + var = None + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + elif isinstance(_expr, ASTVariable): + var = _expr + + if var: + var_base_name = var.name[:-len(var_name_suffix)] # prune the suffix + if self.is_post_port(var_base_name, neuron.name, synapse.name): + post_ports.append(var) + var._is_post_port = True + print("Marking " + str(var.name) + " as post port") + + mark_node.accept(ASTHigherOrderVisitor(lambda x: mark_post_port(x))) + return post_ports + + mark_post_ports(new_neuron, new_synapse, new_neuron) + + # + # move statements in post receive block from synapse to ``new_neuron.moved_spike_updates`` + # + + vars_used = [] + + new_neuron.moved_spike_updates = [] + + spiking_post_port_names = self.get_spiking_post_port_names(synapse, neuron.name, synapse.name) + assert len(spiking_post_port_names) <= 1, "Can only handle one spiking \"post\" port" + if len(spiking_post_port_names) > 0: + post_port_name = spiking_post_port_names[0] + post_receive_block = new_synapse.get_on_receive_block(post_port_name) + assert post_receive_block is not None + for state_var in syn_to_neuron_state_vars: + Logger.log_message(None, -1, "Moving onPost updates for " + str(state_var), None, LoggingLevel.INFO) + + stmts = ASTUtils.get_statements_from_block(state_var, post_receive_block) + if stmts: + Logger.log_message(None, -1, "Moving state var updates for " + state_var + + " from synapse to neuron", None, LoggingLevel.INFO) + for stmt in stmts: + vars_used.extend(ASTUtils.collect_variable_names_in_expression(stmt)) + post_receive_block.block.stmts.remove(stmt) + ASTUtils.add_suffix_to_decl_lhs(stmt, suffix=var_name_suffix) + ASTUtils.add_suffix_to_variable_names(stmt, var_name_suffix) + stmt.update_scope(new_neuron.get_update_blocks().get_scope()) + stmt.accept(ASTSymbolTableVisitor()) + new_neuron.moved_spike_updates.append(stmt) + + vars_used = list(set([v.name for v in vars_used])) + syn_to_neuron_params.extend([v for v in vars_used if v in [p + var_name_suffix for p in all_declared_params]]) + + # + # replace ``continuous`` type input ports that are connected to postsynaptic neuron with suffixed external variable references + # + + Logger.log_message( + None, -1, "In synapse: replacing ``continuous`` type input ports that are connected to postsynaptic neuron with suffixed external variable references", None, LoggingLevel.INFO) + post_connected_continuous_input_ports = [] + post_variable_names = [] + for port in synapse.get_input_blocks().get_input_ports(): + if self.is_post_port(port.get_name(), neuron.name, synapse.name) and self.is_continuous_port(port.get_name(), synapse): + post_connected_continuous_input_ports.append(port.get_name()) + post_variable_names.append(self.get_neuron_var_name_from_syn_port_name( + port.get_name(), neuron.name, synapse.name)) + + for state_var, alternate_name in zip(post_connected_continuous_input_ports, post_variable_names): + Logger.log_message(None, -1, "\t• Replacing variable " + str(state_var), None, LoggingLevel.INFO) + ASTUtils.replace_with_external_variable(state_var, new_synapse, "", + new_synapse.get_equations_blocks(), alternate_name) + + # + # copy parameters + # + + Logger.log_message(None, -1, "Copying parameters from synapse to neuron...", None, LoggingLevel.INFO) + for param_var in syn_to_neuron_params: + Logger.log_message(None, -1, "\tCopying parameter with name " + str(param_var) + + " from synapse to neuron", None, LoggingLevel.INFO) + decls = ASTUtils.move_decls(param_var, + new_synapse.get_parameter_blocks(), + new_neuron.get_parameter_blocks(), + var_name_suffix, + block_type=BlockType.PARAMETERS, + mode="copy") + + # + # add suffix to variables in spike updates + # + + Logger.log_message( + None, -1, "Adding suffix to variables in spike updates", None, LoggingLevel.INFO) + + for stmt in new_neuron.moved_spike_updates: + for param_var in syn_to_neuron_params: + param_var = str(param_var) + ASTUtils.add_suffix_to_variable_name(param_var, stmt, var_name_suffix, scope=new_neuron.get_update_blocks().get_scope()) + + # + # replace occurrences of the variables in expressions in the original synapse with calls to the corresponding neuron getters + # + + Logger.log_message( + None, -1, "In synapse: replacing variables with suffixed external variable references", None, LoggingLevel.INFO) + for state_var in syn_to_neuron_state_vars: + Logger.log_message(None, -1, "\t• Replacing variable " + str(state_var), None, LoggingLevel.INFO) + ASTUtils.replace_with_external_variable( + state_var, new_synapse, var_name_suffix, new_neuron.get_equations_blocks()) + + # + # rename neuron + # + + name_separator_str = "__with_" + + new_neuron_name = neuron.get_name() + name_separator_str + synapse.get_name() + new_neuron.set_name(new_neuron_name) + new_neuron.paired_synapse = new_synapse + + # + # rename synapse + # + + new_synapse_name = synapse.get_name() + name_separator_str + neuron.get_name() + new_synapse.set_name(new_synapse_name) + new_synapse.paired_neuron = new_neuron + new_neuron.paired_synapse = new_synapse + + base_neuron_name = neuron.get_name().removesuffix(FrontendConfiguration.suffix) + base_synapse_name = synapse.get_name().removesuffix(FrontendConfiguration.suffix) + + new_synapse.post_port_names = self.get_post_port_names(synapse, base_neuron_name, base_synapse_name) + new_synapse.spiking_post_port_names = self.get_spiking_post_port_names(synapse, base_neuron_name, base_synapse_name) + new_synapse.vt_port_names = self.get_vt_port_names(synapse, base_neuron_name, base_synapse_name) + + # + # add modified versions of neuron and synapse to list + # + + new_neuron.accept(ASTSymbolTableVisitor()) + new_synapse.accept(ASTSymbolTableVisitor()) + + ASTUtils.update_blocktype_for_common_parameters(new_synapse) + + Logger.log_message(None, -1, "Successfully constructed neuron-synapse pair " + + new_neuron.name + ", " + new_synapse.name, None, LoggingLevel.INFO) + + return new_neuron, new_synapse + + def transform(self, models: Union[ASTNode, Sequence[ASTNode]]) -> Union[ASTNode, Sequence[ASTNode]]: + for neuron_synapse_pair in self.get_option("neuron_synapse_pairs"): + neuron_name = neuron_synapse_pair["neuron"] + synapse_name = neuron_synapse_pair["synapse"] + neuron = ASTUtils.find_model_by_name(neuron_name + FrontendConfiguration.suffix, models) + if neuron is None: + raise Exception("Neuron used in pair (\"" + neuron_name + "\") not found") # XXX: log error + + synapse = ASTUtils.find_model_by_name(synapse_name + FrontendConfiguration.suffix, models) + if synapse is None: + raise Exception("Synapse used in pair (\"" + synapse_name + "\") not found") # XXX: log error + + new_neuron, new_synapse = self.transform_neuron_synapse_pair_(neuron, synapse) + + # Replace the original synapse model with the co-generated one + model_idx = models.index(synapse) + models[model_idx] = new_synapse + models.append(new_neuron) + + return models diff --git a/pynestml/transformers/transformer.py b/pynestml/transformers/transformer.py new file mode 100644 index 000000000..7144a9bec --- /dev/null +++ b/pynestml/transformers/transformer.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# +# transformer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import annotations + +from typing import Any, Mapping, Optional, Union, Sequence + +from pynestml.meta_model.ast_node import ASTNode +from pynestml.utils.with_options import WithOptions + +from abc import ABCMeta, abstractmethod + + +class Transformer(WithOptions, metaclass=ABCMeta): + r"""Perform a transformation step on models, for instance, rewriting disallowed variable names like "lambda" because it conflicts with a keyword. + + Some transformers operate on individual models, and some operate on tuples of models (for instance, a pair (neuron, synapse)).""" + + def __init__(self, options: Optional[Mapping[str, Any]]=None): + super(Transformer, self).__init__(options) + + @abstractmethod + def transform(self, model: Union[ASTNode, Sequence[ASTNode]]) -> Union[ASTNode, Sequence[ASTNode]]: + assert False diff --git a/pynestml/utils/__init__.py b/pynestml/utils/__init__.py index 24e76079f..6ccc9dee4 100644 --- a/pynestml/utils/__init__.py +++ b/pynestml/utils/__init__.py @@ -19,6 +19,4 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -__all__ = ['ast_utils', 'cloning_helpers', 'logger', 'stack', 'either', 'error_listener', 'error_strings', - 'logging_helper', 'messages', 'model_parser', 'ode_transformer', 'type_caster', 'type_dictionary', - 'unit_type', 'ast_nestml_printer', 'source_location', 'port_signal_type'] +__all__ = ["ast_nestml_printer", "ast_utils", "cloning_helpers", "either", "error_listener", "error_strings", "logger", "logging_helper", "messages", "model_parser", "port_signal_type", "source_location", "stack", "type_caster", "type_dictionary", "unit_type", "with_options"] diff --git a/pynestml/utils/ast_channel_information_collector.py b/pynestml/utils/ast_channel_information_collector.py new file mode 100644 index 000000000..67f1414b5 --- /dev/null +++ b/pynestml/utils/ast_channel_information_collector.py @@ -0,0 +1,957 @@ +# -*- coding: utf-8 -*- +# +# ast_channel_information_collector.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from collections import defaultdict +import copy + +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor + + +class ASTChannelInformationCollector(object): + """ + This class is used to enforce constraint conditions on a compartmental model neuron + + While checking compartmental model constraints it also builds a nested + data structure (chan_info) that can be used for code generation later + + Constraints: + + It ensures that all variables x as used in the inline expression named {channelType} + (which has no kernels and is inside ASTEquationsBlock) + have the following compartmental model functions defined + + x_inf_{channelType}(v_comp real) real + tau_x_{channelType}(v_comp real) real + + + Example: + equations: + inline Na real = m_Na_**3 * h_Na_**1 + end + + # triggers requirements for functions such as + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + Moreover it checks + -if all expected sates are defined, + -that at least one gating variable exists (which is recognize when variable name ends with _{channel_name} ) + -that no gating variable repeats inside the inline expression that triggers cm mechanism + Example: + inline Na real = m_Na**3 * h_Na**1 + + #causes the requirement for following entries in the state block + + gbar_Na + e_Na + m_Na + h_Na + + Other allowed examples: + # any variable that does not end with _Na is allowed + inline Na real = m_Na**3 * h_Na**1 + x + # gbar and e variables will not be counted as gating variables + inline Na real = gbar_Na * m_Na**3 * h_Na**1 * (e_Na - v_comp) # gating variables detected: m and h + + Not allowed examples: + inline Na real = p_Na **3 + p_Na **1 # same gating variable used twice + inline Na real = x**2 # no gating variables + + """ + + padding_character = "_" + inf_string = "inf" + tau_sring = "tau" + gbar_string = "gbar" + equilibrium_string = "e" + + first_time_run = defaultdict(lambda: True) + chan_info = defaultdict() + + def __init__(self, params): + ''' + Constructor + ''' + + """ + detect_cm_inline_expressions + + analyzes any inline without kernels and returns + + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "gating_variables": [ASTVariable, ASTVariable, ASTVariable, ...], # potential gating variables + + }, + "K": + { + ... + } + } + """ + + @classmethod + def detect_cm_inline_expressions(cls, neuron): + if not FrontendConfiguration.target_is_compartmental(): + return defaultdict() + + # search for inline expressions inside equations block + inline_expressions_inside_equations_block_collector_visitor = ASTInlineExpressionInsideEquationsCollectorVisitor() + neuron.accept( + inline_expressions_inside_equations_block_collector_visitor) + inline_expressions_dict = inline_expressions_inside_equations_block_collector_visitor.inline_expressions_to_variables + + # filter for any inline that has no kernel + relevant_inline_expressions_to_variables = defaultdict(lambda: list()) + for expression, variables in inline_expressions_dict.items(): + inline_expression_name = expression.variable_name + if not inline_expressions_inside_equations_block_collector_visitor.is_synapse_inline( + inline_expression_name): + relevant_inline_expressions_to_variables[expression] = variables + + # create info structure + chan_info = defaultdict() + for inline_expression, inner_variables in relevant_inline_expressions_to_variables.items(): + info = defaultdict() + channel_name = cls.cm_expression_to_channel_name(inline_expression) + info["ASTInlineExpression"] = inline_expression + info["gating_variables"] = inner_variables + chan_info[channel_name] = info + + return chan_info + + # extract channel name from inline expression name + # i.e Na_ -> channel name is Na + @classmethod + def cm_expression_to_channel_name(cls, expr): + assert isinstance(expr, ASTInlineExpression) + return expr.variable_name.strip(cls.padding_character) + + # extract pure variable name from inline expression variable name + # i.e p_Na -> pure variable name is p + @classmethod + def extract_pure_variable_name(cls, varname, ic_name): + varname = varname.strip(cls.padding_character) + assert varname.endswith(ic_name) + return varname[:-len(ic_name)].strip(cls.padding_character) + + # generate gbar variable name from ion channel name + # i.e Na -> gbar_Na + @classmethod + def get_expected_gbar_name(cls, ion_channel_name): + return cls.gbar_string + cls.padding_character + ion_channel_name + + # generate equilibrium variable name from ion channel name + # i.e Na -> e_Na + @classmethod + def get_expected_equilibrium_var_name(cls, ion_channel_name): + return cls.equilibrium_string + cls.padding_character + ion_channel_name + + # generate tau function name from ion channel name + # i.e Na, p -> tau_p_Na + @classmethod + def get_expected_tau_result_var_name( + cls, ion_channel_name, pure_variable_name): + return cls.padding_character + \ + cls.get_expected_tau_function_name(ion_channel_name, pure_variable_name) + + # generate tau variable name (stores return value) + # from ion channel name and pure variable name + # i.e Na, p -> _tau_p_Na + @classmethod + def get_expected_tau_function_name( + cls, ion_channel_name, pure_variable_name): + return cls.tau_sring + cls.padding_character + \ + pure_variable_name + cls.padding_character + ion_channel_name + + # generate inf function name from ion channel name and pure variable name + # i.e Na, p -> p_inf_Na + @classmethod + def get_expected_inf_result_var_name( + cls, ion_channel_name, pure_variable_name): + return cls.padding_character + \ + cls.get_expected_inf_function_name(ion_channel_name, pure_variable_name) + + # generate inf variable name (stores return value) + # from ion channel name and pure variable name + # i.e Na, p -> _p_inf_Na + @classmethod + def get_expected_inf_function_name( + cls, ion_channel_name, pure_variable_name): + return pure_variable_name + cls.padding_character + \ + cls.inf_string + cls.padding_character + ion_channel_name + + # calculate function names that must be implemented + # i.e + # m_Na**3 * h_Na**1 + # expects + # m_inf_Na(v_comp real) real + # tau_m_Na(v_comp real) real + """ + analyzes cm inlines for expected function names + input: + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "gating_variables": [ASTVariable, ASTVariable, ASTVariable, ...] + + }, + "K": + { + ... + } + } + + output: + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": str, + "inf": str + } + }, + "h": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": str, + "inf": str + } + }, + ... + } + }, + "K": + { + ... + } + } + + """ + + @classmethod + def calc_expected_function_names_for_channels(cls, chan_info): + variables_procesed = defaultdict() + + for ion_channel_name, channel_info in chan_info.items(): + cm_expression = channel_info["ASTInlineExpression"] + variables = channel_info["gating_variables"] + variable_names_seen = set() + + variables_info = defaultdict() + channel_parameters_exclude = cls.get_expected_equilibrium_var_name( + ion_channel_name), cls.get_expected_gbar_name(ion_channel_name) + + for variable_used in variables: + variable_name = variable_used.name.strip(cls.padding_character) + if not variable_name.endswith(ion_channel_name): + # not a gating variable + continue + + # exclude expected channel parameters + if variable_name in channel_parameters_exclude: + continue + + # enforce unique variable names per channel, i.e n and m , not + # n and n + if variable_name in variable_names_seen: + code, message = Messages.get_cm_inline_expression_variable_used_mulitple_times( + cm_expression, variable_name, ion_channel_name) + Logger.log_message( + code=code, + message=message, + error_position=variable_used.get_source_position(), + log_level=LoggingLevel.ERROR, + node=variable_used) + continue + else: + variable_names_seen.add(variable_name) + + pure_variable_name = cls.extract_pure_variable_name( + variable_name, ion_channel_name) + expected_inf_function_name = cls.get_expected_inf_function_name( + ion_channel_name, pure_variable_name) + expected_tau_function_name = cls.get_expected_tau_function_name( + ion_channel_name, pure_variable_name) + + variables_info[pure_variable_name] = defaultdict( + lambda: defaultdict()) + variables_info[pure_variable_name]["expected_functions"][cls.inf_string] = expected_inf_function_name + variables_info[pure_variable_name]["expected_functions"][cls.tau_sring] = expected_tau_function_name + variables_info[pure_variable_name]["ASTVariable"] = variable_used + + variables_procesed[ion_channel_name] = copy.copy(variables_info) + + for ion_channel_name, variables_info in variables_procesed.items(): + chan_info[ion_channel_name]["gating_variables"] = variables_info + + return chan_info + + """ + generate Errors on invalid variable names + and add channel_parameters section to each channel + + input: + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + "h": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + ... + } + }, + "K": + { + ... + } + } + + output: + + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "channel_parameters": + { + "gbar":{"expected_name": "gbar_Na"}, + "e":{"expected_name": "e_Na"} + } + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + "h": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + ... + } + }, + "K": + { + ... + } + } + + """ + @classmethod + def add_channel_parameters_section_and_enforce_proper_variable_names( + cls, node, chan_info): + ret = copy.copy(chan_info) + + channel_parameters = defaultdict() + for ion_channel_name, channel_info in chan_info.items(): + channel_parameters[ion_channel_name] = defaultdict() + channel_parameters[ion_channel_name][cls.gbar_string] = defaultdict() + channel_parameters[ion_channel_name][cls.gbar_string]["expected_name"] = cls.get_expected_gbar_name( + ion_channel_name) + channel_parameters[ion_channel_name][cls.equilibrium_string] = defaultdict( + ) + channel_parameters[ion_channel_name][cls.equilibrium_string]["expected_name"] = cls.get_expected_equilibrium_var_name( + ion_channel_name) + + if len(channel_info["gating_variables"]) < 1: + cm_inline_expr = channel_info["ASTInlineExpression"] + code, message = Messages.get_no_gating_variables( + cm_inline_expr, ion_channel_name) + Logger.log_message( + code=code, + message=message, + error_position=cm_inline_expr.get_source_position(), + log_level=LoggingLevel.ERROR, + node=cm_inline_expr) + continue + + for ion_channel_name, channel_info in chan_info.items(): + ret[ion_channel_name]["channel_parameters"] = channel_parameters[ion_channel_name] + + return ret + + """ + checks if all expected functions exist and have the proper naming and signature + also finds their corresponding ASTFunction objects + + input + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": str, + "inf": str + } + }, + "h": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": str, + "inf": str + } + }, + ... + } + }, + "K": + { + ... + } + } + + output + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + "h": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + ... + } + }, + "K": + { + ... + } + } + """ + @classmethod + def check_and_find_functions(cls, neuron, chan_info): + ret = copy.copy(chan_info) + # get functions and collect their names + declared_functions = neuron.get_functions() + + function_name_to_function = {} + for declared_function in declared_functions: + function_name_to_function[declared_function.name] = declared_function + + # check for missing functions + for ion_channel_name, channel_info in chan_info.items(): + for pure_variable_name, variable_info in channel_info["gating_variables"].items( + ): + if "expected_functions" in variable_info.keys(): + for function_type, expected_function_name in variable_info["expected_functions"].items( + ): + if expected_function_name not in function_name_to_function.keys(): + code, message = Messages.get_expected_cm_function_missing( + ion_channel_name, variable_info["ASTVariable"].name, expected_function_name) + Logger.log_message( + code=code, + message=message, + error_position=neuron.get_source_position(), + log_level=LoggingLevel.ERROR, + node=neuron) + else: + ret[ion_channel_name]["gating_variables"][pure_variable_name]["expected_functions"][function_type] = defaultdict() + ret[ion_channel_name]["gating_variables"][pure_variable_name]["expected_functions"][ + function_type]["ASTFunction"] = function_name_to_function[expected_function_name] + ret[ion_channel_name]["gating_variables"][pure_variable_name][ + "expected_functions"][function_type]["function_name"] = expected_function_name + + # function must have exactly one argument + astfun = ret[ion_channel_name]["gating_variables"][pure_variable_name][ + "expected_functions"][function_type]["ASTFunction"] + if len(astfun.parameters) != 1: + code, message = Messages.get_expected_cm_function_wrong_args_count( + ion_channel_name, variable_info["ASTVariable"].name, astfun) + Logger.log_message( + code=code, + message=message, + error_position=astfun.get_source_position(), + log_level=LoggingLevel.ERROR, + node=astfun) + + # function must return real + if not astfun.get_return_type().is_real: + code, message = Messages.get_expected_cm_function_bad_return_type( + ion_channel_name, astfun) + Logger.log_message( + code=code, + message=message, + error_position=astfun.get_source_position(), + log_level=LoggingLevel.ERROR, + node=astfun) + + if function_type == "tau": + ret[ion_channel_name]["gating_variables"][pure_variable_name]["expected_functions"][function_type][ + "result_variable_name"] = cls.get_expected_tau_result_var_name(ion_channel_name, pure_variable_name) + elif function_type == "inf": + ret[ion_channel_name]["gating_variables"][pure_variable_name]["expected_functions"][function_type][ + "result_variable_name"] = cls.get_expected_inf_result_var_name(ion_channel_name, pure_variable_name) + else: + raise RuntimeError( + 'This should never happen! Unsupported function type ' + function_type + ' from variable ' + pure_variable_name) + + return ret + + @classmethod + def get_chan_info(cls, neuron: ASTNeuron): + """ + returns previously generated chan_info + as a deep copy so it can't be changed externally + via object references + :param neuron: a single neuron instance. + :type neuron: ASTNeuron + """ + + # trigger generation via check_co_co + # if it has not been called before + if cls.first_time_run[neuron]: + cls.check_co_co(neuron) + + return copy.deepcopy(cls.chan_info[neuron]) + + @classmethod + def check_co_co(cls, neuron: ASTNeuron): + """ + :param neuron: a single neuron instance. + :type neuron: ASTNeuron + """ + # make sure we only run this a single time + # subsequent calls will be after AST has been transformed + # where kernels have been removed + # and inlines therefore can't be recognized by kernel calls any more + if cls.first_time_run[neuron]: + chan_info = cls.detect_cm_inline_expressions(neuron) + + # further computation not necessary if there were no cm neurons + if not chan_info: + cls.chan_info[neuron] = dict() + # mark as done so we don't enter here again + cls.first_time_run[neuron] = False + return True + + chan_info = cls.calc_expected_function_names_for_channels( + chan_info) + chan_info = cls.check_and_find_functions(neuron, chan_info) + chan_info = cls.add_channel_parameters_section_and_enforce_proper_variable_names( + neuron, chan_info) + + # now check for existence of expected state variables + # and add their ASTVariable objects to chan_info + missing_states_visitor = VariableMissingVisitor(chan_info) + neuron.accept(missing_states_visitor) + + cls.chan_info[neuron] = chan_info + cls.first_time_run[neuron] = False + + return True + + +# ------------------- Helper classes +""" + Finds the actual ASTVariables in state block + For each expected variable extract their right hand side expression + which contains the desired state value + + + chan_info input + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "channel_parameters": + { + "gbar":{"expected_name": "gbar_Na"}, + "e":{"expected_name": "e_Na"} + } + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + "h": + { + "ASTVariable": ASTVariable, + "expected_functions": + { + "tau": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str}, + "inf": {"ASTFunction": ASTFunction, "function_name": str, "result_variable_name": str} + } + }, + ... + } + }, + "K": + { + ... + } + } + + chan_info output + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "channel_parameters": + { + "gbar": { + "expected_name": "gbar_Na", + "parameter_block_variable": ASTVariable, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "e": { + "expected_name": "e_Na", + "parameter_block_variable": ASTVariable, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "state_variable": ASTVariable, + "expected_functions": + { + "tau": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "inf": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + }, + "h": + { + "ASTVariable": ASTVariable, + "state_variable": ASTVariable, + "expected_functions": + { + "tau": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "inf": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + }, + ... + } + }, + "K": + { + ... + } + } + +""" + + +class VariableMissingVisitor(ASTVisitor): + + def __init__(self, chan_info): + super(VariableMissingVisitor, self).__init__() + self.chan_info = chan_info + + # store ASTElement that causes the expecation of existence of state value + # needed to generate sufficiently informative error message + self.expected_to_object = defaultdict() + + self.values_expected_from_channel = set() + for ion_channel_name, channel_info in self.chan_info.items(): + for channel_variable_type, channel_variable_info in channel_info["channel_parameters"].items( + ): + self.values_expected_from_channel.add( + channel_variable_info["expected_name"]) + self.expected_to_object[channel_variable_info["expected_name"] + ] = channel_info["ASTInlineExpression"] + + self.values_expected_from_variables = set() + for ion_channel_name, channel_info in self.chan_info.items(): + for pure_variable_type, variable_info in channel_info["gating_variables"].items( + ): + self.values_expected_from_variables.add( + variable_info["ASTVariable"].name) + self.expected_to_object[variable_info["ASTVariable"] + .name] = variable_info["ASTVariable"] + + self.not_yet_found_variables = set( + self.values_expected_from_channel).union( + self.values_expected_from_variables) + + self.inside_state_block = False + self.inside_parameter_block = False + self.inside_declaration = False + self.current_block_with_variables = None + self.current_declaration = None + + def visit_declaration(self, node): + self.inside_declaration = True + self.current_declaration = node + + def endvisit_declaration(self, node): + self.inside_declaration = False + self.current_declaration = None + + def visit_variable(self, node): + if self.inside_state_block and self.inside_declaration: + varname = node.name + if varname in self.not_yet_found_variables: + Logger.log_message(message="Expected state variable '" + varname + "' found inside state block", log_level=LoggingLevel.INFO) + self.not_yet_found_variables.difference_update({varname}) + + # make a copy because we can't write into the structure directly + # while iterating over it + chan_info_updated = copy.copy(self.chan_info) + + # now that we found the satate defintion, extract information + # into chan_info + + # state variables + if varname in self.values_expected_from_variables: + for ion_channel_name, channel_info in self.chan_info.items(): + for pure_variable_name, variable_info in channel_info["gating_variables"].items( + ): + if variable_info["ASTVariable"].name == varname: + chan_info_updated[ion_channel_name]["gating_variables"][pure_variable_name]["state_variable"] = node + rhs_expression = self.current_declaration.get_expression() + if rhs_expression is None: + code, message = Messages.get_cm_variable_value_missing( + varname) + Logger.log_message( + code=code, + message=message, + error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR, + node=node) + + chan_info_updated[ion_channel_name]["gating_variables"][ + pure_variable_name]["rhs_expression"] = rhs_expression + self.chan_info = chan_info_updated + + if self.inside_parameter_block and self.inside_declaration: + varname = node.name + if varname in self.not_yet_found_variables: + Logger.log_message(message="Expected variable '" + varname + "' found inside parameter block", log_level=LoggingLevel.INFO) + self.not_yet_found_variables.difference_update({varname}) + + # make a copy because we can't write into the structure directly + # while iterating over it + chan_info_updated = copy.copy(self.chan_info) + # now that we found the defintion, extract information into + # chan_info + + # channel parameters + if varname in self.values_expected_from_channel: + for ion_channel_name, channel_info in self.chan_info.items(): + for variable_type, variable_info in channel_info["channel_parameters"].items( + ): + if variable_info["expected_name"] == varname: + chan_info_updated[ion_channel_name]["channel_parameters"][ + variable_type]["parameter_block_variable"] = node + rhs_expression = self.current_declaration.get_expression() + if rhs_expression is None: + code, message = Messages.get_cm_variable_value_missing( + varname) + Logger.log_message( + code=code, + message=message, + error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR, + node=node) + + chan_info_updated[ion_channel_name]["channel_parameters"][ + variable_type]["rhs_expression"] = rhs_expression + self.chan_info = chan_info_updated + + def endvisit_neuron(self, node): + missing_variable_to_proper_block = {} + for variable in self.not_yet_found_variables: + if variable in self.values_expected_from_channel: + missing_variable_to_proper_block[variable] = "parameters block" + elif variable in self.values_expected_from_variables: + missing_variable_to_proper_block[variable] = "state block" + + if self.not_yet_found_variables: + code, message = Messages.get_expected_cm_variables_missing_in_blocks( + missing_variable_to_proper_block, self.expected_to_object) + Logger.log_message( + code=code, + message=message, + error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR, + node=node) + + def visit_block_with_variables(self, node): + if node.is_state: + self.inside_state_block = True + if node.is_parameters: + self.inside_parameter_block = True + self.current_block_with_variables = node + + def endvisit_block_with_variables(self, node): + if node.is_state: + self.inside_state_block = False + if node.is_parameters: + self.inside_parameter_block = False + self.current_block_with_variables = None + + +""" +for each inline expression inside the equations block, +collect all ASTVariables that are present inside +""" + + +class ASTInlineExpressionInsideEquationsCollectorVisitor(ASTVisitor): + + def __init__(self): + super(ASTInlineExpressionInsideEquationsCollectorVisitor, self).__init__() + self.inline_expressions_to_variables = defaultdict(lambda: list()) + self.inline_expressions_with_kernels = set() + self.inside_equations_block = False + self.inside_inline_expression = False + self.inside_kernel_call = False + self.inside_simple_expression = False + self.current_inline_expression = None + + def is_synapse_inline(self, inline_name): + return inline_name in self.inline_expressions_with_kernels + + def visit_variable(self, node): + if self.inside_equations_block and self.inside_inline_expression and self.current_inline_expression is not None: + self.inline_expressions_to_variables[self.current_inline_expression].append( + node) + + def visit_inline_expression(self, node): + self.inside_inline_expression = True + self.current_inline_expression = node + + def endvisit_inline_expression(self, node): + self.inside_inline_expression = False + self.current_inline_expression = None + + def visit_equations_block(self, node): + self.inside_equations_block = True + + def endvisit_equations_block(self, node): + self.inside_equations_block = False + + def visit_function_call(self, node): + if self.inside_equations_block: + if self.inside_inline_expression and self.inside_simple_expression: + if node.get_name() == "convolve": + inline_name = self.current_inline_expression.variable_name + self.inline_expressions_with_kernels.add(inline_name) + + def visit_simple_expression(self, node): + self.inside_simple_expression = True + + def endvisit_simple_expression(self, node): + self.inside_simple_expression = False diff --git a/pynestml/utils/ast_synapse_information_collector.py b/pynestml/utils/ast_synapse_information_collector.py new file mode 100644 index 000000000..66012f667 --- /dev/null +++ b/pynestml/utils/ast_synapse_information_collector.py @@ -0,0 +1,351 @@ +# -*- coding: utf-8 -*- +# +# ast_synapse_information_collector.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from _collections import defaultdict +import copy + +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_kernel import ASTKernel +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.visitors.ast_visitor import ASTVisitor + + +class ASTSynapseInformationCollector(ASTVisitor): + """ + for each inline expression inside the equations block, + collect all synapse relevant information + + """ + + def __init__(self): + super(ASTSynapseInformationCollector, self).__init__() + + # various dicts to store collected information + self.kernel_name_to_kernel = defaultdict() + self.inline_expression_to_kernel_args = defaultdict(lambda: set()) + self.inline_expression_to_function_calls = defaultdict(lambda: set()) + self.kernel_to_function_calls = defaultdict(lambda: set()) + self.parameter_name_to_declaration = defaultdict(lambda: None) + self.state_name_to_declaration = defaultdict(lambda: None) + self.variable_name_to_declaration = defaultdict(lambda: None) + self.internal_var_name_to_declaration = defaultdict(lambda: None) + self.inline_expression_to_variables = defaultdict(lambda: set()) + self.kernel_to_rhs_variables = defaultdict(lambda: set()) + self.declaration_to_rhs_variables = defaultdict(lambda: set()) + self.input_port_name_to_input_port = defaultdict() + + # traversal states and nodes + self.inside_parameter_block = False + self.inside_state_block = False + self.inside_internals_block = False + self.inside_equations_block = False + self.inside_input_block = False + self.inside_inline_expression = False + self.inside_kernel = False + self.inside_kernel_call = False + self.inside_declaration = False + # self.inside_variable = False + self.inside_simple_expression = False + self.inside_expression = False + # self.inside_function_call = False + + self.current_inline_expression = None + self.current_kernel = None + self.current_expression = None + self.current_simple_expression = None + self.current_declaration = None + # self.current_variable = None + + self.current_synapse_name = None + + def get_state_declaration(self, variable_name): + return self.state_name_to_declaration[variable_name] + + def get_variable_declaration(self, variable_name): + return self.variable_name_to_declaration[variable_name] + + def get_kernel_by_name(self, name: str): + return self.kernel_name_to_kernel[name] + + def get_inline_expressions_with_kernels(self): + return self.inline_expression_to_kernel_args.keys() + + def get_kernel_function_calls(self, kernel: ASTKernel): + return self.kernel_to_function_calls[kernel] + + def get_inline_function_calls(self, inline: ASTInlineExpression): + return self.inline_expression_to_function_calls[inline] + + # extracts all variables specific to a single synapse + # (which is defined by the inline expression containing kernels) + # independently from what block they are declared in + # it also cascades over all right hand side variables until all + # variables are included + + def get_variable_names_of_synapse(self, synapse_inline: ASTInlineExpression, exclude_names: set = set(), exclude_ignorable=True) -> set: + if exclude_ignorable: + exclude_names.update(self.get_variable_names_to_ignore()) + + # find all variables used in the inline + potential_variables = self.inline_expression_to_variables[synapse_inline] + + # find all kernels referenced by the inline + # and collect variables used by those kernels + kernel_arg_pairs = self.get_extracted_kernel_args(synapse_inline) + for kernel_var, spikes_var in kernel_arg_pairs: + kernel = self.get_kernel_by_name(kernel_var.get_name()) + potential_variables.update(self.kernel_to_rhs_variables[kernel]) + + # find declarations for all variables and check + # what variables their rhs expressions use + # for example if we have + # a = b * c + # then check if b and c are already in potential_variables + # if not, add those as well + potential_variables_copy = copy.copy(potential_variables) + + potential_variables_prev_count = len(potential_variables) + while True: + for potential_variable in potential_variables_copy: + var_name = potential_variable.get_name() + if var_name in exclude_names: + continue + declaration = self.get_variable_declaration(var_name) + if declaration is None: + continue + variables_referenced = self.declaration_to_rhs_variables[var_name] + potential_variables.update(variables_referenced) + if potential_variables_prev_count == len(potential_variables): + break + potential_variables_prev_count = len(potential_variables) + + # transform variables into their names and filter + # out anything form exclude_names + result = set() + for potential_variable in potential_variables: + var_name = potential_variable.get_name() + if var_name not in exclude_names: + result.add(var_name) + + return result + + @classmethod + def get_variable_names_to_ignore(cls): + return set(PredefinedVariables.get_variables().keys()).union({"v_comp"}) + + def get_synapse_specific_internal_declarations(self, synapse_inline: ASTInlineExpression) -> defaultdict: + synapse_variable_names = self.get_variable_names_of_synapse( + synapse_inline) + + # now match those variable names with + # variable declarations from the internals block + dereferenced = defaultdict() + for potential_internals_name in synapse_variable_names: + if potential_internals_name in self.internal_var_name_to_declaration: + dereferenced[potential_internals_name] = self.internal_var_name_to_declaration[potential_internals_name] + return dereferenced + + def get_synapse_specific_state_declarations(self, synapse_inline: ASTInlineExpression) -> defaultdict: + synapse_variable_names = self.get_variable_names_of_synapse( + synapse_inline) + + # now match those variable names with + # variable declarations from the state block + dereferenced = defaultdict() + for potential_state_name in synapse_variable_names: + if potential_state_name in self.state_name_to_declaration: + dereferenced[potential_state_name] = self.state_name_to_declaration[potential_state_name] + return dereferenced + + def get_synapse_specific_parameter_declarations(self, synapse_inline: ASTInlineExpression) -> defaultdict: + synapse_variable_names = self.get_variable_names_of_synapse( + synapse_inline) + + # now match those variable names with + # variable declarations from the parameter block + dereferenced = defaultdict() + for potential_param_name in synapse_variable_names: + if potential_param_name in self.parameter_name_to_declaration: + dereferenced[potential_param_name] = self.parameter_name_to_declaration[potential_param_name] + return dereferenced + + def get_extracted_kernel_args(self, inline_expression: ASTInlineExpression) -> set: + return self.inline_expression_to_kernel_args[inline_expression] + + """ + for every occurence of convolve(port, spikes) generate "port__X__spikes" variable + gather those variables for this synapse inline and return their list + + note that those variables will occur as substring in other kernel variables + i.e "port__X__spikes__d" or "__P__port__X__spikes__port__X__spikes" + + so we can use the result to identify all the other kernel variables related to the + specific synapse inline declaration + """ + + def get_basic_kernel_variable_names(self, synapse_inline): + order = 0 + results = [] + for syn_inline, args in self.inline_expression_to_kernel_args.items(): + if synapse_inline.variable_name == syn_inline.variable_name: + for kernel_var, spike_var in args: + kernel_name = kernel_var.get_name() + spike_input_port = self.input_port_name_to_input_port[spike_var.get_name( + )] + kernel_variable_name = self.construct_kernel_X_spike_buf_name( + kernel_name, spike_input_port, order) + results.append(kernel_variable_name) + + return results + + def get_used_kernel_names(self, inline_expression: ASTInlineExpression): + return [kernel_var.get_name() for kernel_var, _ in self.get_extracted_kernel_args(inline_expression)] + + def get_input_port_by_name(self, name): + return self.input_port_name_to_input_port[name] + + def get_used_spike_names(self, inline_expression: ASTInlineExpression): + return [spikes_var.get_name() for _, spikes_var in self.get_extracted_kernel_args(inline_expression)] + + def visit_kernel(self, node): + self.current_kernel = node + self.inside_kernel = True + if self.inside_equations_block: + kernel_name = node.get_variables()[0].get_name_of_lhs() + self.kernel_name_to_kernel[kernel_name] = node + + def visit_function_call(self, node): + if self.inside_equations_block: + if self.inside_inline_expression and self.inside_simple_expression: + if node.get_name() == "convolve": + self.inside_kernel_call = True + kernel, spikes = node.get_args() + kernel_var = kernel.get_variables()[0] + spikes_var = spikes.get_variables()[0] + self.inline_expression_to_kernel_args[self.current_inline_expression].add( + (kernel_var, spikes_var)) + else: + self.inline_expression_to_function_calls[self.current_inline_expression].add( + node) + if self.inside_kernel and self.inside_simple_expression: + self.kernel_to_function_calls[self.current_kernel].add(node) + + def endvisit_function_call(self, node): + self.inside_kernel_call = False + + def endvisit_kernel(self, node): + self.current_kernel = None + self.inside_kernel = False + + def visit_variable(self, node): + if self.inside_inline_expression and not self.inside_kernel_call: + self.inline_expression_to_variables[self.current_inline_expression].add( + node) + elif self.inside_kernel and (self.inside_expression or self.inside_simple_expression): + self.kernel_to_rhs_variables[self.current_kernel].add(node) + elif self.inside_declaration and self.inside_expression: + declared_variable = self.current_declaration.get_variables()[ + 0].get_name() + self.declaration_to_rhs_variables[declared_variable].add(node) + + def visit_inline_expression(self, node): + self.inside_inline_expression = True + self.current_inline_expression = node + + def endvisit_inline_expression(self, node): + self.inside_inline_expression = False + self.current_inline_expression = None + + def visit_equations_block(self, node): + self.inside_equations_block = True + + def endvisit_equations_block(self, node): + self.inside_equations_block = False + + def visit_input_block(self, node): + self.inside_input_block = True + + def visit_input_port(self, node): + self.input_port_name_to_input_port[node.get_name()] = node + + def endvisit_input_block(self, node): + self.inside_input_block = False + + def visit_block_with_variables(self, node): + if node.is_state: + self.inside_state_block = True + if node.is_parameters: + self.inside_parameter_block = True + if node.is_internals: + self.inside_internals_block = True + + def endvisit_block_with_variables(self, node): + if node.is_state: + self.inside_state_block = False + if node.is_parameters: + self.inside_parameter_block = False + if node.is_internals: + self.inside_internals_block = False + + def visit_simple_expression(self, node): + self.inside_simple_expression = True + self.current_simple_expression = node + + def endvisit_simple_expression(self, node): + self.inside_simple_expression = False + self.current_simple_expression = None + + def visit_declaration(self, node): + self.inside_declaration = True + self.current_declaration = node + + # collect decalarations generally + variable_name = node.get_variables()[0].get_name() + self.variable_name_to_declaration[variable_name] = node + + # collect declarations per block + if self.inside_parameter_block: + self.parameter_name_to_declaration[variable_name] = node + elif self.inside_state_block: + self.state_name_to_declaration[variable_name] = node + elif self.inside_internals_block: + self.internal_var_name_to_declaration[variable_name] = node + + def endvisit_declaration(self, node): + self.inside_declaration = False + self.current_declaration = None + + def visit_expression(self, node): + self.inside_expression = True + self.current_expression = node + + def endvisit_expression(self, node): + self.inside_expression = False + self.current_expression = None + + # this method was copied over from ast_transformer + # in order to avoid a circular dependency + @staticmethod + def construct_kernel_X_spike_buf_name(kernel_var_name: str, spike_input_port, order: int, diff_order_symbol="__d"): + assert type(kernel_var_name) is str + assert type(order) is int + assert type(diff_order_symbol) is str + return kernel_var_name.replace("$", "__DOLLAR") + "__X__" + str(spike_input_port) + diff_order_symbol * order diff --git a/pynestml/utils/ast_utils.py b/pynestml/utils/ast_utils.py index a0f0cf393..2bfec45e3 100644 --- a/pynestml/utils/ast_utils.py +++ b/pynestml/utils/ast_utils.py @@ -19,21 +19,49 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import List, Optional +from typing import Iterable, List, Mapping, Optional, Sequence, Union +import re +import sympy + +from pynestml.codegeneration.printers.printer import Printer +from pynestml.generated.PyNestMLLexer import PyNestMLLexer +from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_external_variable import ASTExternalVariable from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_input_block import ASTInputBlock +from pynestml.meta_model.ast_input_port import ASTInputPort +from pynestml.meta_model.ast_kernel import ASTKernel +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_node_factory import ASTNodeFactory +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody +from pynestml.meta_model.ast_ode_equation import ASTOdeEquation +from pynestml.meta_model.ast_return_stmt import ASTReturnStmt +from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression +from pynestml.meta_model.ast_stmt import ASTStmt +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_variable import ASTVariable -from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import VariableSymbol, VariableType +from pynestml.symbols.variable_symbol import BlockType +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor +from pynestml.visitors.ast_visitor import ASTVisitor -class ASTUtils(object): +class ASTUtils: """ - A collection of helpful methods. + A collection of helpful methods for AST manipulation. """ @classmethod @@ -51,6 +79,41 @@ def get_all_neurons(cls, list_of_compilation_units): ret.extend(compilationUnit.get_neuron_list()) return ret + @classmethod + def get_all_synapses(cls, list_of_compilation_units): + """ + For a list of compilation units, it returns a list containing all synapses defined in all compilation + units. + :param list_of_compilation_units: a list of compilation units. + :type list_of_compilation_units: list(ASTNestMLCompilationUnit) + :return: a list of synapses + :rtype: list(ASTSynapse) + """ + ret = list() + for compilationUnit in list_of_compilation_units: + ret.extend(compilationUnit.get_synapse_list()) + return ret + + @classmethod + def get_all_nodes(cls, list_of_compilation_units): + """ + For a list of compilation units, it returns a list containing all nodes defined in all compilation + units. + :param list_of_compilation_units: a list of compilation units. + :type list_of_compilation_units: list(ASTNestMLCompilationUnit) + :return: a list of nodes + :rtype: list(ASTNode) + """ + from pynestml.meta_model.ast_neuron import ASTNeuron + from pynestml.meta_model.ast_synapse import ASTSynapse + ret = list() + for compilationUnit in list_of_compilation_units: + if isinstance(compilationUnit, ASTNeuron): + ret.extend(compilationUnit.get_neuron_list()) + elif isinstance(compilationUnit, ASTSynapse): + ret.extend(compilationUnit.get_synapse_list()) + return ret + @classmethod def is_small_stmt(cls, ast): """ @@ -87,34 +150,28 @@ def is_integrate(cls, function_call): return function_call.get_name() == PredefinedFunctions.INTEGRATE_ODES @classmethod - def is_spike_input(cls, body): - # type: (ASTBody) -> bool + def has_spike_input(cls, body: ASTNeuronOrSynapseBody) -> bool: """ - Checks if the handed over neuron contains a spike input buffer. + Checks if the handed over neuron contains a spike input port. :param body: a single body element. - :type body: ast_body - :return: True if spike buffer is contained, otherwise false. - :rtype: bool + :return: True if spike input port is contained, otherwise False. """ - from pynestml.meta_model.ast_body import ASTBody inputs = (inputL for block in body.get_input_blocks() for inputL in block.get_input_ports()) - for inputL in inputs: - if inputL.is_spike(): + for port in inputs: + if port.is_spike(): return True return False @classmethod - def is_current_input(cls, body): + def has_continuous_input(cls, body: ASTNeuronOrSynapseBody) -> bool: """ - Checks if the handed over neuron contains a current input buffer. + Checks if the handed over neuron contains a continuous time input port. :param body: a single body element. - :type body: ast_body - :return: True if current buffer is contained, otherwise false. - :rtype: bool + :return: True if continuous time input port is contained, otherwise False. """ inputs = (inputL for block in body.get_input_blocks() for inputL in block.get_input_ports()) for inputL in inputs: - if inputL.is_current(): + if inputL.is_continuous(): return True return False @@ -195,16 +252,14 @@ def deconstruct_assignment(cls, lhs=None, is_plus=False, is_minus=False, is_time return expr @classmethod - def get_alias_symbols(cls, ast): + def get_inline_expression_symbols(cls, ast: ASTNode) -> List[VariableSymbol]: """ - For the handed over meta_model, this method collects all functions aka. aliases in it. - :param ast: a single meta_model node - :type ast: AST_ - :return: a list of all alias variable symbols - :rtype: list(VariableSymbol) + For the handed over AST node, this method collects all inline expression variable symbols in it. + :param ast: a single AST node + :return: a list of all inline expression variable symbols """ - ret = list() from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor + from pynestml.meta_model.ast_variable import ASTVariable res = list() def loc_get_vars(node): @@ -213,10 +268,11 @@ def loc_get_vars(node): ast.accept(ASTHigherOrderVisitor(visit_funcs=loc_get_vars)) + ret = list() for var in res: if '\'' not in var.get_complete_name(): symbol = ast.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.VARIABLE) - if symbol is not None and symbol.is_function: + if symbol is not None and symbol.is_inline_expression: ret.append(symbol) return ret @@ -279,6 +335,7 @@ def get_vectorized_variable(cls, ast, scope): :return: the first element with the size parameter :rtype: variable_symbol """ + from pynestml.meta_model.ast_variable import ASTVariable from pynestml.symbols.symbol import SymbolKind variables = (var for var in cls.get_all(ast, ASTVariable) if scope.resolve_to_symbol(var.get_complete_name(), SymbolKind.VARIABLE)) @@ -288,6 +345,21 @@ def get_vectorized_variable(cls, ast, scope): return symbol return None + @classmethod + def get_numeric_vector_size(cls, variable: VariableSymbol) -> int: + """ + Returns the numerical size of the vector by resolving any variable used as a size parameter in declaration + :param variable: vector variable + :return: the size of the vector as a numerical value + """ + vector_parameter = variable.get_vector_parameter() + vector_variable = ASTVariable(vector_parameter, scope=variable.get_corresponding_scope()) + symbol = vector_variable.get_scope().resolve_to_symbol(vector_variable.get_complete_name(), SymbolKind.VARIABLE) + if symbol is not None: + # vector size is a variable. Get the value from RHS + return symbol.get_declaring_expression().get_numeric_literal() + return int(vector_parameter) + @classmethod def get_function_call(cls, ast, function_name): """ @@ -300,7 +372,6 @@ def get_function_call(cls, ast, function_name): :rtype: list(ASTFunctionCall) """ from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor - from pynestml.meta_model.ast_function_call import ASTFunctionCall ret = list() def loc_get_function(node): @@ -350,7 +421,7 @@ def create_internal_block(cls, neuron): """ from pynestml.meta_model.ast_node_factory import ASTNodeFactory if neuron.get_internals_blocks() is None: - internal = ASTNodeFactory.create_ast_block_with_variables(False, False, True, False, list(), + internal = ASTNodeFactory.create_ast_block_with_variables(False, False, True, list(), ASTSourceLocation.get_added_source_position()) internal.update_scope(neuron.get_scope()) neuron.get_body().get_body_elements().append(internal) @@ -368,35 +439,16 @@ def create_state_block(cls, neuron): # local import since otherwise circular dependency from pynestml.meta_model.ast_node_factory import ASTNodeFactory if neuron.get_internals_blocks() is None: - state = ASTNodeFactory.create_ast_block_with_variables(True, False, False, False, list(), + state = ASTNodeFactory.create_ast_block_with_variables(True, False, False, list(), ASTSourceLocation.get_added_source_position()) neuron.get_body().get_body_elements().append(state) return neuron @classmethod - def create_initial_values_block(cls, neuron): - """ - Creates a single initial values block in the handed over neuron. - :param neuron: a single neuron - :type neuron: ast_neuron - :return: the modified neuron - :rtype: ast_neuron - """ - # local import since otherwise circular dependency - from pynestml.meta_model.ast_node_factory import ASTNodeFactory - if neuron.get_initial_blocks() is None: - initial_values = ASTNodeFactory. \ - create_ast_block_with_variables(False, False, False, True, list(), - ASTSourceLocation.get_added_source_position()) - neuron.get_body().get_body_elements().append(initial_values) - return neuron - - @classmethod - def contains_sum_call(cls, variable): + def contains_convolve_call(cls, variable: VariableSymbol) -> bool: """ - Indicates whether the declaring rhs of this variable symbol has a x_sum or convolve in it. + Indicates whether the declaring rhs of this variable symbol has a convolve() in it. :return: True if contained, otherwise False. - :rtype: bool """ if not variable.get_declaring_expression(): return False @@ -435,7 +487,8 @@ def get_declaration_by_name(cls, block: ASTBlock, var_name: str) -> Optional[AST return None @classmethod - def all_variables_defined_in_block(cls, block: ASTBlock) -> List[ASTVariable]: + def all_variables_defined_in_block(cls, block: Optional[ASTBlock]) -> List[ASTVariable]: + """return a list of all variable declarations in a block""" if block is None: return [] vars = [] @@ -443,3 +496,1424 @@ def all_variables_defined_in_block(cls, block: ASTBlock) -> List[ASTVariable]: for var in decl.get_variables(): vars.append(var) return vars + + @classmethod + def inline_aliases_convolution(cls, inline_expr: ASTInlineExpression) -> bool: + """ + Returns True if and only if the inline expression is of the form ``var type = convolve(...)``. + """ + if isinstance(inline_expr.get_expression(), ASTSimpleExpression) \ + and inline_expr.get_expression().is_function_call() \ + and inline_expr.get_expression().get_function_call().get_name() == PredefinedFunctions.CONVOLVE: + return True + return False + + @classmethod + def add_suffix_to_variable_name(cls, var_name: str, astnode: ASTNode, suffix: str, scope=None): + """add suffix to variable by given name recursively throughout astnode""" + + def replace_var(_expr=None): + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + elif isinstance(_expr, ASTVariable): + var = _expr + else: + return + + if not suffix in var.get_name() \ + and not var.get_name() == "t" \ + and var.get_name() == var_name: + var.set_name(var.get_name() + suffix) + + astnode.accept(ASTHigherOrderVisitor(lambda x: replace_var(x))) + + @classmethod + def add_suffix_to_variable_names(cls, astnode: Union[ASTNode, List], suffix: str): + """add suffix to variable names recursively throughout astnode""" + + if not isinstance(astnode, ASTNode): + for node in astnode: + ASTUtils.add_suffix_to_variable_names(node, suffix) + return + + def replace_var(_expr=None): + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + elif isinstance(_expr, ASTVariable): + var = _expr + else: + return + + if not suffix in var.get_name() \ + and not var.get_name() == "t": + var.set_name(var.get_name() + suffix) + + astnode.accept(ASTHigherOrderVisitor(lambda x: replace_var(x))) + + @classmethod + def get_inline_expression_by_name(cls, node, name: str) -> Optional[ASTInlineExpression]: + if not node.get_equations_block(): + return None + for inline_expr in node.get_equations_block().get_inline_expressions(): + if name == inline_expr.variable_name: + return inline_expr + return None + + @classmethod + def replace_with_external_variable(cls, var_name, node: ASTNode, suffix, new_scope, alternate_name=None): + """ + Replace all occurrences of variables (``ASTVariable``s) (e.g. ``post_trace'``) in the node with ``ASTExternalVariable``s, indicating that they are moved to the postsynaptic neuron. + """ + + def replace_var(_expr=None): + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + elif isinstance(_expr, ASTVariable): + var = _expr + else: + return + + if var.get_name() != var_name: + return + + ast_ext_var = ASTExternalVariable(var.get_name() + suffix, + differential_order=var.get_differential_order(), + source_position=var.get_source_position()) + if alternate_name: + ast_ext_var.set_alternate_name(alternate_name) + + ast_ext_var.update_alt_scope(new_scope) + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + ast_ext_var.accept(ASTSymbolTableVisitor()) + + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + Logger.log_message(None, -1, "ASTSimpleExpression replacement made (var = " + str( + ast_ext_var.get_name()) + ") in expression: " + str(node.get_parent(_expr)), None, LoggingLevel.INFO) + _expr.set_variable(ast_ext_var) + return + + if isinstance(_expr, ASTVariable): + if isinstance(node.get_parent(_expr), ASTAssignment): + node.get_parent(_expr).lhs = ast_ext_var + Logger.log_message(None, -1, "ASTVariable replacement made in expression: " + + str(node.get_parent(_expr)), None, LoggingLevel.INFO) + elif isinstance(node.get_parent(_expr), ASTSimpleExpression) and node.get_parent(_expr).is_variable(): + node.get_parent(_expr).set_variable(ast_ext_var) + elif isinstance(node.get_parent(_expr), ASTDeclaration): + # variable could occur on the left-hand side; ignore. Only replace if it occurs on the right-hand side. + pass + else: + Logger.log_message(None, -1, "Error: unhandled use of variable " + + var_name + " in expression " + str(_expr), None, LoggingLevel.INFO) + raise Exception() + return + + p = node.get_parent(var) + Logger.log_message(None, -1, "Error: unhandled use of variable " + + var_name + " in expression " + str(p), None, LoggingLevel.INFO) + raise Exception() + + node.accept(ASTHigherOrderVisitor(lambda x: replace_var(x))) + + @classmethod + def add_suffix_to_decl_lhs(cls, decl, suffix: str): + """add suffix to the left-hand side of a declaration""" + if isinstance(decl, ASTInlineExpression): + decl.set_variable_name(decl.get_variable_name() + suffix) + elif isinstance(decl, ASTOdeEquation): + decl.get_lhs().set_name(decl.get_lhs().get_name() + suffix) + elif isinstance(decl, ASTStmt): + assert decl.small_stmt.is_assignment() + decl.small_stmt.get_assignment().lhs.set_name(decl.small_stmt.get_assignment().lhs.get_name() + suffix) + else: + for var in decl.get_variables(): + var.set_name(var.get_name() + suffix) + + @classmethod + def get_all_variables(cls, node: ASTNode) -> List[str]: + """Make a list of all variable symbol names that are in ``node``""" + if node is None: + return [] + + class ASTVariablesFinderVisitor(ASTVisitor): + _variables = [] + + def __init__(self): + super(ASTVariablesFinderVisitor, self).__init__() + + def visit_declaration(self, node): + symbol = node.get_scope().resolve_to_symbol(node.get_variables()[0].get_complete_name(), + SymbolKind.VARIABLE) + if symbol is None: + code, message = Messages.get_variable_not_defined(node.get_variable().get_complete_name()) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR, astnode=node) + return + + self._variables.append(symbol) + + visitor = ASTVariablesFinderVisitor() + node.accept(visitor) + all_variables = [v.name for v in visitor._variables] + return all_variables + + @classmethod + def get_all_variables_used_in_convolutions(cls, node: ASTNode, parent_node: ASTNode) -> List[str]: + """Make a list of all variable symbol names that are in ``node`` and used in a convolution""" + if node is None: + return [] + + class ASTAllVariablesUsedInConvolutionVisitor(ASTVisitor): + _variables = [] + parent_node = None + + def __init__(self, node, parent_node): + super(ASTAllVariablesUsedInConvolutionVisitor, self).__init__() + self.node = node + self.parent_node = parent_node + + def visit_function_call(self, node): + func_name = node.get_name() + if func_name == 'convolve': + symbol_buffer = node.get_scope().resolve_to_symbol(str(node.get_args()[1]), + SymbolKind.VARIABLE) + input_port = ASTUtils.get_input_port_by_name( + self.parent_node.get_input_blocks(), symbol_buffer.name) + if input_port: + found_parent_assignment = False + node_ = node + while not found_parent_assignment: + node_ = self.parent_node.get_parent(node_) + # XXX TODO also needs to accept normal ASTExpression, ASTAssignment? + if isinstance(node_, ASTInlineExpression): + found_parent_assignment = True + var_name = node_.get_variable_name() + self._variables.append(var_name) + + visitor = ASTAllVariablesUsedInConvolutionVisitor(node, parent_node) + node.accept(visitor) + return visitor._variables + + @classmethod + def move_decls(cls, var_name, from_block, to_block, var_name_suffix, block_type: BlockType, mode="move", scope=None) -> List[ASTDeclaration]: + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + assert mode in ["move", "copy"] + + if not from_block \ + or not to_block: + return [] + + decls = ASTUtils.get_declarations_from_block(var_name, from_block) + if var_name.endswith(var_name_suffix): + decls.extend(ASTUtils.get_declarations_from_block(var_name.removesuffix(var_name_suffix), from_block)) + + if decls: + Logger.log_message(None, -1, "Moving definition of " + var_name + " from synapse to neuron", + None, LoggingLevel.INFO) + for decl in decls: + if mode == "move": + from_block.declarations.remove(decl) + if mode == "copy": + decl = decl.clone() + assert len(decl.get_variables()) <= 1 + if not decl.get_variables()[0].name.endswith(var_name_suffix): + ASTUtils.add_suffix_to_decl_lhs(decl, suffix=var_name_suffix) + to_block.get_declarations().append(decl) + decl.update_scope(to_block.get_scope()) + + ast_symbol_table_visitor = ASTSymbolTableVisitor() + ast_symbol_table_visitor.block_type_stack.push(block_type) + decl.accept(ast_symbol_table_visitor) + ast_symbol_table_visitor.block_type_stack.pop() + + return decls + + @classmethod + def equations_from_block_to_block(cls, state_var, from_block, to_block, var_name_suffix, mode) -> List[ASTDeclaration]: + assert mode in ["move", "copy"] + + if not to_block or not from_block: + return [] + + decls = ASTUtils.get_declarations_from_block(state_var, from_block) + + for decl in decls: + if mode == "move": + from_block.declarations.remove(decl) + ASTUtils.add_suffix_to_decl_lhs(decl, suffix=var_name_suffix) + to_block.get_declarations().append(decl) + decl.update_scope(to_block.get_scope()) + + return decls + + @classmethod + def collects_vars_used_in_equation(cls, state_var, from_block): + if not from_block: + return + + decls = ASTUtils.get_declarations_from_block(state_var, from_block) + vars_used = [] + if decls: + for decl in decls: + if (type(decl) in [ASTDeclaration, ASTReturnStmt] and decl.has_expression()) \ + or type(decl) is ASTInlineExpression: + vars_used.extend( + ASTUtils.collect_variable_names_in_expression(decl.get_expression())) + elif type(decl) is ASTOdeEquation: + vars_used.extend(ASTUtils.collect_variable_names_in_expression(decl.get_rhs())) + elif type(decl) is ASTKernel: + for expr in decl.get_expressions(): + vars_used.extend(ASTUtils.collect_variable_names_in_expression(expr)) + else: + raise Exception("Tried to move unknown type " + str(type(decl))) + + return vars_used + + @classmethod + def add_kernel_to_variable(cls, kernel: ASTKernel): + r""" + Adds the kernel as the defining equation. + + If the definition of the kernel is e.g. `g'' = ...` then variable symbols `g` and `g'` will have their kernel definition and variable type set. + + :param kernel: a single kernel object. + """ + if len(kernel.get_variables()) == 1 \ + and kernel.get_variables()[0].get_differential_order() == 0: + # we only update those which define an ODE; skip "direct function of time" specifications + return + + for var, expr in zip(kernel.get_variables(), kernel.get_expressions()): + for diff_order in range(var.get_differential_order()): + var_name = var.get_name() + "'" * diff_order + existing_symbol = kernel.get_scope().resolve_to_symbol(var_name, SymbolKind.VARIABLE) + + if existing_symbol is None: + code, message = Messages.get_no_variable_found(var.get_name_of_lhs()) + Logger.log_message(code=code, message=message, error_position=kernel.get_source_position(), log_level=LoggingLevel.ERROR) + return + + existing_symbol.set_ode_or_kernel(expr) + existing_symbol.set_variable_type(VariableType.KERNEL) + kernel.get_scope().update_variable_symbol(existing_symbol) + + @classmethod + def assign_ode_to_variables(cls, ode_block: ASTEquationsBlock): + r""" + Adds for each variable symbol the corresponding ode declaration if present. + + :param ode_block: a single block of ode declarations. + """ + from pynestml.meta_model.ast_ode_equation import ASTOdeEquation + from pynestml.meta_model.ast_kernel import ASTKernel + for decl in ode_block.get_declarations(): + if isinstance(decl, ASTOdeEquation): + ASTUtils.add_ode_to_variable(decl) + elif isinstance(decl, ASTKernel): + ASTUtils.add_kernel_to_variable(decl) + + @classmethod + def add_ode_to_variable(cls, ode_equation: ASTOdeEquation): + r""" + Resolves to the corresponding symbol and updates the corresponding ode-declaration. + + :param ode_equation: a single ode-equation + """ + for diff_order in range(ode_equation.get_lhs().get_differential_order()): + var_name = ode_equation.get_lhs().get_name() + "'" * diff_order + existing_symbol = ode_equation.get_scope().resolve_to_symbol(var_name, SymbolKind.VARIABLE) + + if existing_symbol is None: + code, message = Messages.get_no_variable_found(ode_equation.get_lhs().get_name_of_lhs()) + Logger.log_message(code=code, message=message, error_position=ode_equation.get_source_position(), + log_level=LoggingLevel.ERROR) + return + + existing_symbol.set_ode_or_kernel(ode_equation) + + ode_equation.get_scope().update_variable_symbol(existing_symbol) + + @classmethod + def get_statements_from_block(cls, var_name, block): + """XXX: only simple statements such as assignments are supported for now. if..then..else compound statements and so are not yet supported.""" + block = block.get_block() + all_stmts = block.get_stmts() + stmts = [] + for node in all_stmts: + if node.is_small_stmt() \ + and node.small_stmt.is_assignment() \ + and node.small_stmt.get_assignment().lhs.get_name() == var_name: + stmts.append(node) + return stmts + + @classmethod + def is_function_delay_variable(cls, node: ASTFunctionCall) -> bool: + """ + Checks if the given function call is actually a delayed variable. For a function call to be a delayed + variable, the function name should be resolved to a state symbol, with one function argument which is an + expression. + :param node: The function call + """ + # Check if the function name is a state variable + symbol = cls.get_delay_variable_symbol(node) + args = node.get_args() + # Check if the length of arg list is 1 + if symbol and len(args) == 1 and isinstance(args[0], ASTExpression): + return True + return False + + @classmethod + def get_delay_variable_symbol(cls, node: ASTFunctionCall): + """ + Returns the variable symbol for the corresponding delayed variable + :param node: The delayed variable parsed as a function call + """ + symbol = node.get_scope().resolve_to_symbol(node.get_name(), SymbolKind.VARIABLE) + if symbol and symbol.block_type == BlockType.STATE: + return symbol + return None + + @classmethod + def extract_delay_parameter(cls, node: ASTFunctionCall) -> str: + """ + Extracts the delay parameter from the delayed variable + :param node: The delayed variable parsed as a function call + """ + args = node.get_args() + delay_parameter = args[0].get_rhs().get_variable() + return delay_parameter.get_name() + + @classmethod + def update_delay_parameter_in_state_vars(cls, neuron: ASTNeuron, state_vars_before_update: List[VariableSymbol]) -> None: + """ + Updates the delay parameter in state variables after the symbol table update + :param neuron: AST neuron + :param state_vars_before_update: State variables before the symbol table update + """ + for state_var in state_vars_before_update: + if state_var.has_delay_parameter(): + symbol = neuron.get_scope().resolve_to_symbol(state_var.get_symbol_name(), SymbolKind.VARIABLE) + if symbol is not None: + symbol.set_delay_parameter(state_var.get_delay_parameter()) + + @classmethod + def has_equation_with_delay_variable(cls, equations_with_delay_vars: ASTOdeEquation, sym: str) -> bool: + """ + Returns true if the given variable has an equation defined with a delayed variable, false otherwise. + :param equations_with_delay_vars: a list of equations containing delayed variables + :param sym: symbol denoting the lhs of + """ + for equation in equations_with_delay_vars: + if equation.get_lhs().get_name() == sym: + return True + return False + + _variable_matching_template = r'(\b)({})(\b)' + + @classmethod + def add_declarations_to_internals(cls, neuron: ASTNeuron, declarations: Mapping[str, str]) -> ASTNeuron: + """ + Adds the variables as stored in the declaration tuples to the neuron. + :param neuron: a single neuron instance + :param declarations: a map of variable names to declarations + :return: a modified neuron + """ + for variable in declarations: + cls.add_declaration_to_internals(neuron, variable, declarations[variable]) + return neuron + + @classmethod + def add_declaration_to_internals(cls, neuron: ASTNeuron, variable_name: str, init_expression: str) -> ASTNeuron: + """ + Adds the variable as stored in the declaration tuple to the neuron. The declared variable is of type real. + :param neuron: a single neuron instance + :param variable_name: the name of the variable to add + :param init_expression: initialization expression + :return: the neuron extended by the variable + """ + from pynestml.utils.model_parser import ModelParser + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + + tmp = ModelParser.parse_expression(init_expression) + vector_variable = ASTUtils.get_vectorized_variable(tmp, neuron.get_scope()) + + declaration_string = variable_name + ' real' + ( + '[' + vector_variable.get_vector_parameter() + ']' + if vector_variable is not None and vector_variable.has_vector_parameter() else '') + ' = ' + init_expression + ast_declaration = ModelParser.parse_declaration(declaration_string) + if vector_variable is not None: + ast_declaration.set_size_parameter(vector_variable.get_vector_parameter()) + neuron.add_to_internal_block(ast_declaration) + ast_declaration.update_scope(neuron.get_internals_blocks().get_scope()) + symtable_visitor = ASTSymbolTableVisitor() + symtable_visitor.block_type_stack.push(BlockType.INTERNALS) + ast_declaration.accept(symtable_visitor) + symtable_visitor.block_type_stack.pop() + return neuron + + @classmethod + def add_declarations_to_state_block(cls, neuron: ASTNeuron, variables: List, initial_values: List) -> ASTNeuron: + """ + Adds a single declaration to the state block of the neuron. + :param neuron: a neuron + :param variables: list of variables + :param initial_values: list of initial values + :return: a modified neuron + """ + for variable, initial_value in zip(variables, initial_values): + cls.add_declaration_to_state_block(neuron, variable, initial_value) + return neuron + + @classmethod + def add_declaration_to_state_block(cls, neuron: ASTNeuron, variable: str, initial_value: str) -> ASTNeuron: + """ + Adds a single declaration to the state block of the neuron. The declared variable is of type real. + :param neuron: a neuron + :param variable: state variable to add + :param initial_value: corresponding initial value + :return: a modified neuron + """ + from pynestml.utils.model_parser import ModelParser + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + + tmp = ModelParser.parse_expression(initial_value) + vector_variable = ASTUtils.get_vectorized_variable(tmp, neuron.get_scope()) + declaration_string = variable + ' real' + ( + '[' + vector_variable.get_vector_parameter() + ']' + if vector_variable is not None and vector_variable.has_vector_parameter() else '') + ' = ' + initial_value + ast_declaration = ModelParser.parse_declaration(declaration_string) + if vector_variable is not None: + ast_declaration.set_size_parameter(vector_variable.get_vector_parameter()) + neuron.add_to_state_block(ast_declaration) + ast_declaration.update_scope(neuron.get_state_blocks().get_scope()) + + symtable_visitor = ASTSymbolTableVisitor() + symtable_visitor.block_type_stack.push(BlockType.STATE) + ast_declaration.accept(symtable_visitor) + symtable_visitor.block_type_stack.pop() + + return neuron + + @classmethod + def declaration_in_state_block(cls, neuron: ASTNeuron, variable_name: str) -> bool: + """ + Checks if the variable is declared in the state block + :param neuron: + :param variable_name: + :return: + """ + assert type(variable_name) is str + + if neuron.get_state_blocks() is None: + return False + + for decl in neuron.get_state_blocks().get_declarations(): + for var in decl.get_variables(): + if var.get_complete_name() == variable_name: + return True + + return False + + @classmethod + def add_assignment_to_update_block(cls, assignment: ASTAssignment, neuron: ASTNeuron) -> ASTNeuron: + """ + Adds a single assignment to the end of the update block of the handed over neuron. + :param assignment: a single assignment + :param neuron: a single neuron instance + :return: the modified neuron + """ + small_stmt = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, + source_position=ASTSourceLocation.get_added_source_position()) + stmt = ASTNodeFactory.create_ast_stmt(small_stmt=small_stmt, + source_position=ASTSourceLocation.get_added_source_position()) + if not neuron.get_update_blocks(): + neuron.create_empty_update_block() + neuron.get_update_blocks().get_block().get_stmts().append(stmt) + small_stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) + stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) + return neuron + + @classmethod + def add_declaration_to_update_block(cls, declaration: ASTDeclaration, neuron: ASTNeuron) -> ASTNeuron: + """ + Adds a single declaration to the end of the update block of the handed over neuron. + :param declaration: ASTDeclaration node to add + :param neuron: a single neuron instance + :return: a modified neuron + """ + small_stmt = ASTNodeFactory.create_ast_small_stmt(declaration=declaration, + source_position=ASTSourceLocation.get_added_source_position()) + stmt = ASTNodeFactory.create_ast_stmt(small_stmt=small_stmt, + source_position=ASTSourceLocation.get_added_source_position()) + if not neuron.get_update_blocks(): + neuron.create_empty_update_block() + neuron.get_update_blocks().get_block().get_stmts().append(stmt) + small_stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) + stmt.update_scope(neuron.get_update_blocks().get_block().get_scope()) + return neuron + + @classmethod + def add_state_updates(cls, neuron: ASTNeuron, update_expressions: Mapping[str, str]) -> ASTNeuron: + """ + Adds all update instructions as contained in the solver output to the update block of the neuron. + :param neuron: a single neuron + :param update_expressions: map of variables to corresponding updates during the update step. + :return: a modified version of the neuron + """ + from pynestml.utils.model_parser import ModelParser + for variable, update_expression in update_expressions.items(): + declaration_statement = variable + '__tmp real = ' + update_expression + cls.add_declaration_to_update_block(ModelParser.parse_declaration(declaration_statement), neuron) + for variable, update_expression in update_expressions.items(): + cls.add_assignment_to_update_block(ModelParser.parse_assignment(variable + ' = ' + variable + '__tmp'), + neuron) + return neuron + + @classmethod + def variable_in_solver(cls, kernel_var: str, solver_dicts: List[dict]) -> bool: + """ + Check if a variable by this name is defined in the ode-toolbox solver results, + """ + + for solver_dict in solver_dicts: + if solver_dict is None: + continue + + for var_name in solver_dict["state_variables"]: + var_name_base = var_name.split("__X__")[0] + if var_name_base == kernel_var: + return True + + return False + + @classmethod + def is_ode_variable(cls, var_base_name: str, neuron: ASTNeuron) -> bool: + """ + Checks if the variable is present in an ODE + """ + equations_block = neuron.get_equations_blocks() + for ode_eq in equations_block.get_ode_equations(): + var = ode_eq.get_lhs() + if var.get_name() == var_base_name: + return True + return False + + @classmethod + def variable_in_kernels(cls, var_name: str, kernels: List[ASTKernel]) -> bool: + """ + Check if a variable by this name (in ode-toolbox style) is defined in the ode-toolbox solver results + """ + + var_name_base = var_name.split("__X__")[0] + var_name_base = var_name_base.split("__d")[0] + var_name_base = var_name_base.replace("__DOLLAR", "$") + + for kernel in kernels: + for kernel_var in kernel.get_variables(): + if var_name_base == kernel_var.get_name(): + return True + + return False + + @classmethod + def get_initial_value_from_ode_toolbox_result(cls, var_name: str, solver_dicts: List[dict]) -> str: + """ + Get the initial value of the variable with the given name from the ode-toolbox results JSON. + + N.B. the variable name is given in ode-toolbox notation. + """ + + for solver_dict in solver_dicts: + if solver_dict is None: + continue + + if var_name in solver_dict["state_variables"]: + return solver_dict["initial_values"][var_name] + + assert False, "Initial value not found for ODE with name \"" + var_name + "\"" + + @classmethod + def get_kernel_var_order_from_ode_toolbox_result(cls, kernel_var: str, solver_dicts: List[dict]) -> int: + """ + Get the differential order of the variable with the given name from the ode-toolbox results JSON. + + N.B. the variable name is given in NESTML notation, e.g. "g_in$"; convert to ode-toolbox export format notation (e.g. "g_in__DOLLAR"). + """ + + kernel_var = kernel_var.replace("$", "__DOLLAR") + + order = -1 + for solver_dict in solver_dicts: + if solver_dict is None: + continue + + for var_name in solver_dict["state_variables"]: + var_name_base = var_name.split("__X__")[0] + var_name_base = var_name_base.split("__d")[0] + if var_name_base == kernel_var: + order = max(order, var_name.count("__d") + 1) + + assert order >= 0, "Variable of name \"" + kernel_var + "\" not found in ode-toolbox result" + return order + + @classmethod + def to_ode_toolbox_processed_name(cls, name: str) -> str: + """ + Convert name in the same way as ode-toolbox does from input to output, i.e. returned names are compatible with ode-toolbox output + """ + return name.replace("$", "__DOLLAR").replace("'", "__d") + + @classmethod + def to_ode_toolbox_name(cls, name: str) -> str: + """ + Convert to a name suitable for ode-toolbox input + """ + return name.replace("$", "__DOLLAR") + + @classmethod + def get_expr_from_kernel_var(cls, kernel: ASTKernel, var_name: str) -> Union[ASTExpression, ASTSimpleExpression]: + """ + Get the expression using the kernel variable + """ + assert type(var_name) == str + for var, expr in zip(kernel.get_variables(), kernel.get_expressions()): + if var.get_complete_name() == var_name: + return expr + assert False, "variable name not found in kernel" + + @classmethod + def construct_kernel_X_spike_buf_name(cls, kernel_var_name: str, spike_input_port: ASTInputPort, order: int, + diff_order_symbol="__d"): + """ + Construct a kernel-buffer name as + + For example, if the kernel is + .. code-block:: + kernel I_kernel = exp(-t / tau_x) + + and the input port is + .. code-block:: + pre_spikes nS <- spike + + then the constructed variable will be 'I_kernel__X__pre_pikes' + """ + assert type(kernel_var_name) is str + assert type(order) is int + assert type(diff_order_symbol) is str + return kernel_var_name.replace("$", "__DOLLAR") + "__X__" + str(spike_input_port) + diff_order_symbol * order + + @classmethod + def replace_rhs_variable(cls, expr: ASTExpression, variable_name_to_replace: str, kernel_var: ASTVariable, + spike_buf: ASTInputPort): + """ + Replace variable names in definitions of kernel dynamics + :param expr: expression in which to replace the variables + :param variable_name_to_replace: variable name to replace in the expression + :param kernel_var: kernel variable instance + :param spike_buf: input port instance + :return: + """ + def replace_kernel_var(node): + if type(node) is ASTSimpleExpression \ + and node.is_variable() \ + and node.get_variable().get_name() == variable_name_to_replace: + var_order = node.get_variable().get_differential_order() + new_variable_name = cls.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_buf, var_order - 1, diff_order_symbol="'") + new_variable = ASTVariable(new_variable_name, var_order) + new_variable.set_source_position(node.get_variable().get_source_position()) + node.set_variable(new_variable) + + expr.accept(ASTHigherOrderVisitor(visit_funcs=replace_kernel_var)) + + @classmethod + def replace_rhs_variables(cls, expr: ASTExpression, kernel_buffers: Mapping[ASTKernel, ASTInputPort]): + """ + Replace variable names in definitions of kernel dynamics. + + Say that the kernel is + + .. code-block:: + + G = -G / tau + + Its variable symbol might be replaced by "G__X__spikesEx": + + .. code-block:: + + G__X__spikesEx = -G / tau + + This function updates the right-hand side of `expr` so that it would also read (in this example): + + .. code-block:: + + G__X__spikesEx = -G__X__spikesEx / tau + + These equations will later on be fed to ode-toolbox, so we use the symbol "'" to indicate differential order. + + Note that for kernels/systems of ODE of dimension > 1, all variable orders and all variables for this kernel will already be present in `kernel_buffers`. + """ + for kernel, spike_buf in kernel_buffers: + for kernel_var in kernel.get_variables(): + variable_name_to_replace = kernel_var.get_name() + cls.replace_rhs_variable(expr, variable_name_to_replace=variable_name_to_replace, + kernel_var=kernel_var, spike_buf=spike_buf) + + @classmethod + def is_delta_kernel(cls, kernel: ASTKernel) -> bool: + """ + Catches definition of kernel, or reference (function call or variable name) of a delta kernel function. + """ + if type(kernel) is ASTKernel: + if not len(kernel.get_variables()) == 1: + # delta kernel not allowed if more than one variable is defined in this kernel + return False + expr = kernel.get_expressions()[0] + else: + expr = kernel + + rhs_is_delta_kernel = type(expr) is ASTSimpleExpression \ + and expr.is_function_call() \ + and expr.get_function_call().get_scope().resolve_to_symbol( + expr.get_function_call().get_name(), SymbolKind.FUNCTION) == PredefinedFunctions.name2function["delta"] + rhs_is_multiplied_delta_kernel = type(expr) is ASTExpression \ + and type(expr.get_rhs()) is ASTSimpleExpression \ + and expr.get_rhs().is_function_call() \ + and expr.get_rhs().get_function_call().get_scope().resolve_to_symbol( + expr.get_rhs().get_function_call().get_name(), SymbolKind.FUNCTION) == PredefinedFunctions.name2function[ + "delta"] + return rhs_is_delta_kernel or rhs_is_multiplied_delta_kernel + + @classmethod + def get_input_port_by_name(cls, input_block: ASTInputBlock, port_name: str) -> ASTInputPort: + """ + Get the input port given the port name + :param input_block: block to be searched + :param port_name: name of the input port + :return: input port object + """ + for input_port in input_block.get_input_ports(): + if input_port.name == port_name: + return input_port + return None + + @classmethod + def get_parameter_by_name(cls, parameters_block: ASTBlockWithVariables, var_name: str) -> ASTDeclaration: + """ + Get the declaration based on the name of the parameter + :param parameters_block: the parameter block + :param var_name: variable name to be searched + :return: declaration containing the variable + """ + for decl in parameters_block.get_declarations(): + for var in decl.get_variables(): + if var.get_name() == var_name: + return decl + return None + + @classmethod + def collect_variable_names_in_expression(cls, expr: ASTNode) -> List[ASTVariable]: + """ + Collect all occurrences of variables (`ASTVariable`), kernels (`ASTKernel`) XXX ... + :param expr: expression to collect the variables from + :return: a list of variables + """ + vars_used_ = [] + + def collect_vars(_expr=None): + var = None + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + elif isinstance(_expr, ASTVariable): + var = _expr + + if var: + vars_used_.append(var) + + expr.accept(ASTHigherOrderVisitor(lambda x: collect_vars(x))) + + return vars_used_ + + @classmethod + def get_declarations_from_block(cls, var_name: str, block: ASTBlock) -> List[ASTDeclaration]: + """ + Get declarations from the given block containing the given variable. + :param var_name: variable name + :param block: block to collect the variable declarations + :return: a list of declarations + """ + if block is None: + return [] + + if not type(var_name) is str: + var_name = str(var_name) + + decls = [] + + for decl in block.get_declarations(): + if isinstance(decl, ASTInlineExpression): + var_names = [decl.get_variable_name()] + elif isinstance(decl, ASTOdeEquation): + var_names = [decl.get_lhs().get_name()] + else: + var_names = [var.get_name() for var in decl.get_variables()] + + for _var_name in var_names: + if _var_name == var_name: + decls.append(decl) + break + + return decls + + @classmethod + def recursive_dependent_variables_search(cls, vars: List[str], node: ASTNode) -> List[str]: + """ + Collect all the variable names used in the defining expressions of a list of variables. + :param vars: list of variable names moved from synapse to neuron + :param node: ASTNode to perform the recursive search + :return: list of variable names from the recursive search + """ + for var in vars: + assert type(var) is str + vars_used = [] + vars_to_check = set([var for var in vars]) + vars_checked = set() + while vars_to_check: + var = None + for _var in vars_to_check: + if not _var in vars_checked: + var = _var + break + if not var: + # all variables checked + break + decls = cls.get_declarations_from_block(var, node.get_equations_blocks()) + + if decls: + assert len(decls) == 1 + decl = decls[0] + if (type(decl) in [ASTDeclaration, ASTReturnStmt] and decl.has_expression()) \ + or type(decl) is ASTInlineExpression: + vars_used.extend(cls.collect_variable_names_in_expression(decl.get_expression())) + elif type(decl) is ASTOdeEquation: + vars_used.extend(cls.collect_variable_names_in_expression(decl.get_rhs())) + elif type(decl) is ASTKernel: + for expr in decl.get_expressions(): + vars_used.extend(cls.collect_variable_names_in_expression(expr)) + else: + raise Exception("Unknown type " + str(type(decl))) + vars_used = [str(var) for var in vars_used] + vars_to_check = vars_to_check.union(set(vars_used)) + vars_checked.add(var) + + return list(set(vars_checked)) + + @classmethod + def remove_initial_values_for_kernels(cls, neuron: ASTNeuron) -> None: + """ + Remove initial values for original declarations (e.g. g_in, g_in', V_m); these might conflict with the initial value expressions returned from ODE-toolbox. + """ + assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "only one equation block should be present" + + equations_block = neuron.get_equations_block() + symbols_to_remove = set() + for kernel in equations_block.get_kernels(): + for kernel_var in kernel.get_variables(): + kernel_var_order = kernel_var.get_differential_order() + for order in range(kernel_var_order): + symbol_name = kernel_var.get_name() + "'" * order + symbols_to_remove.add(symbol_name) + + decl_to_remove = set() + for symbol_name in symbols_to_remove: + for decl in neuron.get_state_blocks().get_declarations(): + if len(decl.get_variables()) == 1: + if decl.get_variables()[0].get_name() == symbol_name: + decl_to_remove.add(decl) + else: + for var in decl.get_variables(): + if var.get_name() == symbol_name: + decl.variables.remove(var) + + for decl in decl_to_remove: + neuron.get_state_blocks().get_declarations().remove(decl) + + @classmethod + def update_initial_values_for_odes(cls, neuron: ASTNeuron, solver_dicts: List[dict]) -> None: + """ + Update initial values for original ODE declarations (e.g. V_m', g_ahp'') that are present in the model + before ODE-toolbox processing, with the formatted variable names and initial values returned by ODE-toolbox. + """ + from pynestml.utils.model_parser import ModelParser + assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "only one equation block should be present" + + if neuron.get_state_blocks() is None: + return + + for iv_decl in neuron.get_state_blocks().get_declarations(): + for var in iv_decl.get_variables(): + var_name = var.get_complete_name() + if cls.is_ode_variable(var.get_name(), neuron): + assert cls.variable_in_solver(cls.to_ode_toolbox_processed_name(var_name), solver_dicts) + + # replace the left-hand side variable name by the ode-toolbox format + var.set_name(cls.to_ode_toolbox_processed_name(var.get_complete_name())) + var.set_differential_order(0) + + # replace the defining expression by the ode-toolbox result + iv_expr = cls.get_initial_value_from_ode_toolbox_result( + cls.to_ode_toolbox_processed_name(var_name), solver_dicts) + assert iv_expr is not None + iv_expr = ModelParser.parse_expression(iv_expr) + iv_expr.update_scope(neuron.get_state_blocks().get_scope()) + iv_decl.set_expression(iv_expr) + + @classmethod + def create_initial_values_for_kernels(cls, neuron: ASTNeuron, solver_dicts: List[dict], kernels: List[ASTKernel]) -> None: + """ + Add the variables used in kernels from the ode-toolbox result dictionary as ODEs in NESTML AST + """ + for solver_dict in solver_dicts: + if solver_dict is None: + continue + for var_name in solver_dict["initial_values"].keys(): + if cls.variable_in_kernels(var_name, kernels): + # original initial value expressions should have been removed to make place for ode-toolbox results + assert not cls.declaration_in_state_block(neuron, var_name) + + for solver_dict in solver_dicts: + if solver_dict is None: + continue + + for var_name, expr in solver_dict["initial_values"].items(): + # overwrite is allowed because initial values might be repeated between numeric and analytic solver + if cls.variable_in_kernels(var_name, kernels): + expr = "0" # for kernels, "initial value" returned by ode-toolbox is actually the increment value; the actual initial value is assumed to be 0 + if not cls.declaration_in_state_block(neuron, var_name): + cls.add_declaration_to_state_block(neuron, var_name, expr) + + @classmethod + def transform_ode_and_kernels_to_json(cls, neuron: ASTNeuron, parameters_block: ASTBlockWithVariables, + kernel_buffers: Mapping[ASTKernel, ASTInputPort], printer: Printer) -> dict: + """ + Converts AST node to a JSON representation suitable for passing to ode-toolbox. + + Each kernel has to be generated for each spike buffer convolve in which it occurs, e.g. if the NESTML model code contains the statements + + .. code-block:: + + convolve(G, exc_spikes) + convolve(G, inh_spikes) + + then `kernel_buffers` will contain the pairs `(G, exc_spikes)` and `(G, inh_spikes)`, from which two ODEs will be generated, with dynamical state (variable) names `G__X__exc_spikes` and `G__X__inh_spikes`. + + :param parameters_block: + :param kernel_buffers: + :param neuron: + :return: Dict + """ + odetoolbox_indict = {} + + odetoolbox_indict["dynamics"] = [] + equations_block = neuron.get_equations_block() + for equation in equations_block.get_ode_equations(): + # n.b. includes single quotation marks to indicate differential order + lhs = cls.to_ode_toolbox_name(equation.get_lhs().get_complete_name()) + rhs = printer.print_expression(equation.get_rhs()) + entry = {"expression": lhs + " = " + rhs} + symbol_name = equation.get_lhs().get_name() + symbol = equations_block.get_scope().resolve_to_symbol(symbol_name, SymbolKind.VARIABLE) + + entry["initial_values"] = {} + symbol_order = equation.get_lhs().get_differential_order() + for order in range(symbol_order): + iv_symbol_name = symbol_name + "'" * order + initial_value_expr = neuron.get_initial_value(iv_symbol_name) + if initial_value_expr: + expr = printer.print_expression(initial_value_expr) + entry["initial_values"][cls.to_ode_toolbox_name(iv_symbol_name)] = expr + odetoolbox_indict["dynamics"].append(entry) + + # write a copy for each (kernel, spike buffer) combination + for kernel, spike_input_port in kernel_buffers: + + if cls.is_delta_kernel(kernel): + # delta function -- skip passing this to ode-toolbox + continue + + for kernel_var in kernel.get_variables(): + expr = cls.get_expr_from_kernel_var(kernel, kernel_var.get_complete_name()) + kernel_order = kernel_var.get_differential_order() + kernel_X_spike_buf_name_ticks = cls.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_input_port, kernel_order, diff_order_symbol="'") + + cls.replace_rhs_variables(expr, kernel_buffers) + + entry = {"expression": kernel_X_spike_buf_name_ticks + " = " + str(expr), "initial_values": {}} + + # initial values need to be declared for order 1 up to kernel order (e.g. none for kernel function + # f(t) = ...; 1 for kernel ODE f'(t) = ...; 2 for f''(t) = ... and so on) + for order in range(kernel_order): + iv_sym_name_ode_toolbox = cls.construct_kernel_X_spike_buf_name( + kernel_var.get_name(), spike_input_port, order, diff_order_symbol="'") + symbol_name_ = kernel_var.get_name() + "'" * order + symbol = equations_block.get_scope().resolve_to_symbol(symbol_name_, SymbolKind.VARIABLE) + assert symbol is not None, "Could not find initial value for variable " + symbol_name_ + initial_value_expr = symbol.get_declaring_expression() + assert initial_value_expr is not None, "No initial value found for variable name " + symbol_name_ + entry["initial_values"][iv_sym_name_ode_toolbox] = printer.print_expression(initial_value_expr) + + odetoolbox_indict["dynamics"].append(entry) + + odetoolbox_indict["parameters"] = {} + if parameters_block is not None: + for decl in parameters_block.get_declarations(): + for var in decl.variables: + odetoolbox_indict["parameters"][var.get_complete_name( + )] = printer.print_expression(decl.get_expression()) + + return odetoolbox_indict + + @classmethod + def remove_ode_definitions_from_equations_block(cls, neuron: ASTNeuron) -> None: + """ + Removes all ODEs in this block. + """ + equations_block = neuron.get_equations_block() + + decl_to_remove = set() + for decl in equations_block.get_ode_equations(): + decl_to_remove.add(decl) + + for decl in decl_to_remove: + equations_block.get_declarations().remove(decl) + + @classmethod + def make_inline_expressions_self_contained(cls, inline_expressions: List[ASTInlineExpression]) -> List[ASTInlineExpression]: + """ + Make inline_expressions self contained, i.e. without any references to other inline_expressions. + + TODO: it should be a method inside of the ASTInlineExpression + TODO: this should be done by means of a visitor + + :param inline_expressions: A sorted list with entries ASTInlineExpression. + :return: A list with ASTInlineExpressions. Defining expressions don't depend on each other. + """ + from pynestml.utils.model_parser import ModelParser + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + + for source in inline_expressions: + source_position = source.get_source_position() + for target in inline_expressions: + matcher = re.compile(cls._variable_matching_template.format(source.get_variable_name())) + target_definition = str(target.get_expression()) + target_definition = re.sub(matcher, "(" + str(source.get_expression()) + ")", target_definition) + target.expression = ModelParser.parse_expression(target_definition) + target.expression.update_scope(source.get_scope()) + target.expression.accept(ASTSymbolTableVisitor()) + + def log_set_source_position(node): + if node.get_source_position().is_added_source_position(): + node.set_source_position(source_position) + + target.expression.accept(ASTHigherOrderVisitor(visit_funcs=log_set_source_position)) + + return inline_expressions + + @classmethod + def replace_inline_expressions_through_defining_expressions(cls, definitions: Sequence[ASTOdeEquation], + inline_expressions: Sequence[ASTInlineExpression]) -> Sequence[ASTOdeEquation]: + """ + Replaces symbols from `inline_expressions` in `definitions` with corresponding defining expressions from `inline_expressions`. + + :param definitions: A list of ODE definitions (**updated in-place**). + :param inline_expressions: A list of inline expression definitions. + :return: A list of updated ODE definitions (same as the ``definitions`` parameter). + """ + from pynestml.utils.model_parser import ModelParser + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + + for m in inline_expressions: + source_position = m.get_source_position() + for target in definitions: + matcher = re.compile(cls._variable_matching_template.format(m.get_variable_name())) + target_definition = str(target.get_rhs()) + target_definition = re.sub(matcher, "(" + str(m.get_expression()) + ")", target_definition) + target.rhs = ModelParser.parse_expression(target_definition) + target.update_scope(m.get_scope()) + target.accept(ASTSymbolTableVisitor()) + + def log_set_source_position(node): + if node.get_source_position().is_added_source_position(): + node.set_source_position(source_position) + + target.accept(ASTHigherOrderVisitor(visit_funcs=log_set_source_position)) + + return definitions + + @classmethod + def get_delta_factors_(cls, neuron: ASTNeuron, equations_block: ASTEquationsBlock) -> dict: + r""" + For every occurrence of a convolution of the form `x^(n) = a * convolve(kernel, inport) + ...` where `kernel` is a delta function, add the element `(x^(n), inport) --> a` to the set. + """ + delta_factors = {} + for ode_eq in equations_block.get_ode_equations(): + var = ode_eq.get_lhs() + expr = ode_eq.get_rhs() + conv_calls = ASTUtils.get_convolve_function_calls(expr) + for conv_call in conv_calls: + assert len( + conv_call.args) == 2, "convolve() function call should have precisely two arguments: kernel and spike input port" + kernel = conv_call.args[0] + if cls.is_delta_kernel(neuron.get_kernel_by_name(kernel.get_variable().get_name())): + inport = conv_call.args[1].get_variable() + expr_str = str(expr) + sympy_expr = sympy.parsing.sympy_parser.parse_expr(expr_str) + sympy_expr = sympy.expand(sympy_expr) + sympy_conv_expr = sympy.parsing.sympy_parser.parse_expr(str(conv_call)) + factor_str = [] + for term in sympy.Add.make_args(sympy_expr): + if term.find(sympy_conv_expr): + factor_str.append(str(term.replace(sympy_conv_expr, 1))) + factor_str = " + ".join(factor_str) + delta_factors[(var, inport)] = factor_str + + return delta_factors + + @classmethod + def remove_kernel_definitions_from_equations_block(cls, neuron: ASTNeuron) -> ASTDeclaration: + """ + Removes all kernels in this block. + """ + equations_block = neuron.get_equations_block() + + decl_to_remove = set() + for decl in equations_block.get_declarations(): + if type(decl) is ASTKernel: + decl_to_remove.add(decl) + + for decl in decl_to_remove: + equations_block.get_declarations().remove(decl) + + return decl_to_remove + + @classmethod + def add_timestep_symbol(cls, neuron: ASTNeuron) -> None: + """ + Add timestep variable to the internals block + """ + from pynestml.utils.model_parser import ModelParser + assert neuron.get_initial_value( + "__h") is None, "\"__h\" is a reserved name, please do not use variables by this name in your NESTML file" + assert not "__h" in [sym.name for sym in neuron.get_internal_symbols( + )], "\"__h\" is a reserved name, please do not use variables by this name in your NESTML file" + neuron.add_to_internal_block(ModelParser.parse_declaration('__h ms = resolution()'), index=0) + + @classmethod + def generate_kernel_buffers_(cls, neuron: ASTNeuron, equations_block: ASTEquationsBlock) -> Mapping[ASTKernel, ASTInputPort]: + """ + For every occurrence of a convolution of the form `convolve(var, spike_buf)`: add the element `(kernel, spike_buf)` to the set, with `kernel` being the kernel that contains variable `var`. + """ + + kernel_buffers = set() + convolve_calls = ASTUtils.get_convolve_function_calls(equations_block) + for convolve in convolve_calls: + el = (convolve.get_args()[0], convolve.get_args()[1]) + sym = convolve.get_args()[0].get_scope().resolve_to_symbol( + convolve.get_args()[0].get_variable().name, SymbolKind.VARIABLE) + if sym is None: + raise Exception("No initial value(s) defined for kernel with variable \"" + + convolve.get_args()[0].get_variable().get_complete_name() + "\"") + if sym.block_type == BlockType.INPUT: + # swap the order + el = (el[1], el[0]) + + # find the corresponding kernel object + var = el[0].get_variable() + assert var is not None + kernel = neuron.get_kernel_by_name(var.get_name()) + assert kernel is not None, "In convolution \"convolve(" + str(var.name) + ", " + str( + el[1]) + ")\": no kernel by name \"" + var.get_name() + "\" found in neuron." + + el = (kernel, el[1]) + kernel_buffers.add(el) + + return kernel_buffers + + @classmethod + def replace_convolution_aliasing_inlines(cls, neuron: ASTNeuron) -> None: + """ + Replace all occurrences of kernel names (e.g. ``I_dend`` and ``I_dend'`` for a definition involving a second-order kernel ``inline kernel I_dend = convolve(kern_name, spike_buf)``) with the ODE-toolbox generated variable ``kern_name__X__spike_buf``. + """ + def replace_var(_expr, replace_var_name: str, replace_with_var_name: str): + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + if var.get_name() == replace_var_name: + ast_variable = ASTVariable(replace_with_var_name + '__d' * var.get_differential_order(), + differential_order=0) + ast_variable.set_source_position(var.get_source_position()) + _expr.set_variable(ast_variable) + + elif isinstance(_expr, ASTVariable): + var = _expr + if var.get_name() == replace_var_name: + var.set_name(replace_with_var_name + '__d' * var.get_differential_order()) + var.set_differential_order(0) + + for decl in neuron.get_equations_block().get_declarations(): + if isinstance(decl, ASTInlineExpression) \ + and isinstance(decl.get_expression(), ASTSimpleExpression) \ + and '__X__' in str(decl.get_expression()): + replace_with_var_name = decl.get_expression().get_variable().get_name() + neuron.accept(ASTHigherOrderVisitor(lambda x: replace_var( + x, decl.get_variable_name(), replace_with_var_name))) + + @classmethod + def replace_variable_names_in_expressions(cls, neuron: ASTNeuron, solver_dicts: List[dict]) -> None: + """ + Replace all occurrences of variables names in NESTML format (e.g. `g_ex$''`)` with the ode-toolbox formatted + variable name (e.g. `g_ex__DOLLAR__d__d`). + + Variables aliasing convolutions should already have been covered by replace_convolution_aliasing_inlines(). + """ + def replace_var(_expr=None): + if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable(): + var = _expr.get_variable() + if cls.variable_in_solver(cls.to_ode_toolbox_processed_name(var.get_complete_name()), solver_dicts): + ast_variable = ASTVariable(cls.to_ode_toolbox_processed_name( + var.get_complete_name()), differential_order=0) + ast_variable.set_source_position(var.get_source_position()) + _expr.set_variable(ast_variable) + + elif isinstance(_expr, ASTVariable): + var = _expr + if cls.variable_in_solver(cls.to_ode_toolbox_processed_name(var.get_complete_name()), solver_dicts): + var.set_name(cls.to_ode_toolbox_processed_name(var.get_complete_name())) + var.set_differential_order(0) + + def func(x): + return replace_var(x) + + neuron.accept(ASTHigherOrderVisitor(func)) + + @classmethod + def replace_convolve_calls_with_buffers_(cls, neuron: ASTNeuron, equations_block: ASTEquationsBlock) -> None: + r""" + Replace all occurrences of `convolve(kernel[']^n, spike_input_port)` with the corresponding buffer variable, e.g. `g_E__X__spikes_exc[__d]^n` for a kernel named `g_E` and a spike input port named `spikes_exc`. + """ + + def replace_function_call_through_var(_expr=None): + if _expr.is_function_call() and _expr.get_function_call().get_name() == "convolve": + convolve = _expr.get_function_call() + el = (convolve.get_args()[0], convolve.get_args()[1]) + sym = convolve.get_args()[0].get_scope().resolve_to_symbol( + convolve.get_args()[0].get_variable().name, SymbolKind.VARIABLE) + if sym.block_type == BlockType.INPUT: + # swap elements + el = (el[1], el[0]) + var = el[0].get_variable() + spike_input_port = el[1].get_variable() + kernel = neuron.get_kernel_by_name(var.get_name()) + + _expr.set_function_call(None) + buffer_var = cls.construct_kernel_X_spike_buf_name( + var.get_name(), spike_input_port, var.get_differential_order() - 1) + if cls.is_delta_kernel(kernel): + # delta kernels are treated separately, and should be kept out of the dynamics (computing derivates etc.) --> set to zero + _expr.set_variable(None) + _expr.set_numeric_literal(0) + else: + ast_variable = ASTVariable(buffer_var) + ast_variable.set_source_position(_expr.get_source_position()) + _expr.set_variable(ast_variable) + + def func(x): + return replace_function_call_through_var(x) if isinstance(x, ASTSimpleExpression) else True + + equations_block.accept(ASTHigherOrderVisitor(func)) + + @classmethod + def update_blocktype_for_common_parameters(cls, node): + """Change the BlockType for all homogeneous parameters to BlockType.COMMON_PARAMETER""" + if node is None: + return + + # get all homogeneous parameters + all_homogeneous_parameters = [] + for parameter in node.get_parameter_symbols(): + is_homogeneous = PyNestMLLexer.DECORATOR_HOMOGENEOUS in parameter.get_decorators() + if is_homogeneous: + all_homogeneous_parameters.append(parameter.name) + + # change the block type + class ASTHomogeneousParametersBlockTypeChangeVisitor(ASTVisitor): + def __init__(self, all_homogeneous_parameters): + super(ASTHomogeneousParametersBlockTypeChangeVisitor, self).__init__() + self._all_homogeneous_parameters = all_homogeneous_parameters + + def visit_variable(self, node: ASTNode): + if node.get_name() in self._all_homogeneous_parameters: + symbol = node.get_scope().resolve_to_symbol(node.get_complete_name(), + SymbolKind.VARIABLE) + if symbol is None: + code, message = Messages.get_variable_not_defined(node.get_variable().get_complete_name()) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR, astnode=node) + return + + assert symbol.block_type in [BlockType.PARAMETERS, BlockType.COMMON_PARAMETERS] + symbol.block_type = BlockType.COMMON_PARAMETERS + Logger.log_message(None, -1, "Changing block type of variable " + str(node.get_complete_name()), + None, LoggingLevel.INFO) + + visitor = ASTHomogeneousParametersBlockTypeChangeVisitor(all_homogeneous_parameters) + node.accept(visitor) + + @classmethod + def find_model_by_name(cls, model_name: str, models: Iterable[Union[ASTNeuron, ASTSynapse]]) -> Optional[Union[ASTNeuron, ASTSynapse]]: + for model in models: + if model.get_name() == model_name: + return model + + return None + + @classmethod + def get_convolve_function_calls(cls, ast): + """ + Returns all sum function calls in the handed over meta_model node or one of its children. + :param ast: a single meta_model node. + :type ast: ASTNode + """ + return cls.get_function_calls(ast, PredefinedFunctions.CONVOLVE) + + @classmethod + def contains_convolve_function_call(cls, ast): + """ + Indicates whether _ast or one of its child nodes contains a sum call. + :param ast: a single meta_model + :type ast: ASTNode + :return: True if sum is contained, otherwise False. + :rtype: bool + """ + return len(cls.get_function_calls(ast, PredefinedFunctions.CONVOLVE)) > 0 + + @classmethod + def get_function_calls(cls, ast_node, function_list): + """ + For a handed over list of function names, this method retrieves all functions in the meta_model. + :param ast_node: a single meta_model node + :type ast_node: ASTNode + :param function_list: a list of function names + :type function_list: list(str) + :return: a list of all functions in the meta_model + :rtype: list(ASTFunctionCall) + """ + res = list() + if ast_node is None: + return res + from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor + from pynestml.meta_model.ast_function_call import ASTFunctionCall + fun = (lambda x: res.append(x) if isinstance(x, ASTFunctionCall) and x.get_name() in function_list else True) + vis = ASTHigherOrderVisitor(visit_funcs=fun) + ast_node.accept(vis) + return res diff --git a/pynestml/utils/chan_info_enricher.py b/pynestml/utils/chan_info_enricher.py new file mode 100644 index 000000000..63c1ded7b --- /dev/null +++ b/pynestml/utils/chan_info_enricher.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# +# chan_info_enricher.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import copy +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor +import sympy + + +class ChanInfoEnricher(): + + """ + Adds derivative of inline expression to chan_info + This needs to be done used from within nest_codegenerator + because the import of ModelParser will otherwise cause + a circular dependency when this is used + inside CmProcessing + + input: + + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "channel_parameters": + { + "gbar": { + "expected_name": "gbar_Na", + "parameter_block_variable": ASTVariable, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "e": { + "expected_name": "e_Na", + "parameter_block_variable": ASTVariable, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "state_variable": ASTVariable, + "expected_functions": + { + "tau": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "inf": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + }, + "h": + { + "ASTVariable": ASTVariable, + "state_variable": ASTVariable, + "expected_functions": + { + "tau": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "inf": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + }, + ... + } + }, + "K": + { + ... + } + } + + output: + + { + "Na": + { + "ASTInlineExpression": ASTInlineExpression, + "inline_derivative": ASTInlineExpression, + "channel_parameters": + { + "gbar": { + "expected_name": "gbar_Na", + "parameter_block_variable": ASTVariable, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "e": { + "expected_name": "e_Na", + "parameter_block_variable": ASTVariable, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + "gating_variables": + { + "m": + { + "ASTVariable": ASTVariable, + "state_variable": ASTVariable, + "expected_functions": + { + "tau": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "inf": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + }, + "h": + { + "ASTVariable": ASTVariable, + "state_variable": ASTVariable, + "expected_functions": + { + "tau": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + }, + "inf": { + "ASTFunction": ASTFunction, + "function_name": str, + "result_variable_name": str, + "rhs_expression": ASTSimpleExpression or ASTExpression + } + } + }, + ... + } + }, + "K": + { + ... + } + } + +""" + + @classmethod + def enrich_with_additional_info(cls, neuron: ASTNeuron, chan_info: dict): + chan_info_copy = copy.copy(chan_info) + for ion_channel_name, ion_channel_info in chan_info_copy.items(): + chan_info[ion_channel_name]["inline_derivative"] = cls.computeExpressionDerivative( + chan_info[ion_channel_name]["ASTInlineExpression"]) + return chan_info + + @classmethod + def computeExpressionDerivative( + cls, inline_expression: ASTInlineExpression) -> ASTExpression: + expr_str = str(inline_expression.get_expression()) + sympy_expr = sympy.parsing.sympy_parser.parse_expr(expr_str) + sympy_expr = sympy.diff(sympy_expr, "v_comp") + + ast_expression_d = ModelParser.parse_expression(str(sympy_expr)) + # copy scope of the original inline_expression into the the derivative + ast_expression_d.update_scope(inline_expression.get_scope()) + ast_expression_d.accept(ASTSymbolTableVisitor()) + + return ast_expression_d diff --git a/pynestml/utils/either.py b/pynestml/utils/either.py index 471bc28b5..d60b82f7f 100644 --- a/pynestml/utils/either.py +++ b/pynestml/utils/either.py @@ -20,7 +20,7 @@ # along with NEST. If not, see . -class Either(object): +class Either: """ Objects of these class are either values or error messages. Attributes: diff --git a/pynestml/utils/error_strings.py b/pynestml/utils/error_strings.py index 437ec9af4..bbddd8990 100644 --- a/pynestml/utils/error_strings.py +++ b/pynestml/utils/error_strings.py @@ -21,7 +21,7 @@ from pynestml.utils.ast_source_location import ASTSourceLocation -class ErrorStrings(object): +class ErrorStrings: """ These error strings are part of the type calculation system and are kept separated from the message class for the sake of a clear and direct maintenance of type system as an individual component. diff --git a/pynestml/utils/logger.py b/pynestml/utils/logger.py index a4ee3a96d..c02d664b1 100644 --- a/pynestml/utils/logger.py +++ b/pynestml/utils/logger.py @@ -19,38 +19,46 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import List, Mapping, Tuple +from typing import List, Mapping, Optional, Tuple from collections import OrderedDict from enum import Enum import json + from pynestml.meta_model.ast_node import ASTNode from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.messages import MessageCode +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_input_port import ASTInputPort class LoggingLevel(Enum): """ Different types of logging levels, this part can be extended. """ - INFO = 0 - WARNING = 1 - ERROR = 2 - NO = 3 + DEBUG = 0 + INFO = 1 + WARNING = 2 + ERROR = 3 + NO = 4 class Logger: """ This class represents a logger which can be used to print messages to the screen depending on the logging level. + LEVELS: - INFO Print all received messages. - WARNING Print all received warning. + DEBUG Print all received messages. + INFO Print all received information messages, warnings and errors. + WARNING Print all received warnings and errors. ERROR Print all received errors. - NO Print no messages + NO Print no messages. + Hereby, errors are the most specific level, thus no warnings and non critical messages are shown. If logging - level is set to WARNING, only warnings and errors are printed. Only if level is set to ALL, all messages + level is set to WARNING, only warnings and errors are printed. Only if level is set to DEBUG, all messages are printed. + Attributes: log Stores all messages as received during the execution. Map from id (int) to node,type,message curr_message A counter indicating the current message, this enables a sorting by the number of message @@ -59,6 +67,7 @@ class Logger: """ log = {} curr_message = None + log_frozen = False logging_level = None current_node = None no_print = False @@ -68,12 +77,15 @@ def init_logger(cls, logging_level: LoggingLevel): """ Initializes the logger. :param logging_level: the logging level as required + :type logging_level: LoggingLevel """ cls.logging_level = logging_level cls.curr_message = 0 cls.log = {} cls.log_frozen = False + return + @classmethod def freeze_log(cls, do_freeze: bool = True): """ Freeze the log: while log is frozen, all logging requests will be ignored. @@ -101,13 +113,16 @@ def set_log(cls, log, counter): @classmethod def log_message(cls, node: ASTNode = None, code: MessageCode = None, message: str = None, error_position: ASTSourceLocation = None, log_level: LoggingLevel = None): """ - Logs the handed over message on the handed over. If the current logging is appropriate, the - message is also printed. + Logs the handed over message on the handed over node. If the current logging is appropriate, the message is also printed. :param node: the node in which the error occurred :param code: a single error code + :type code: ErrorCode :param error_position: the position on which the error occurred. + :type error_position: SourcePosition :param message: a message. + :type message: str :param log_level: the corresponding log level. + :type log_level: LoggingLevel """ if cls.log_frozen: return @@ -130,47 +145,87 @@ def log_message(cls, node: ASTNode = None, code: MessageCode = None, message: st if cls.no_print: return if cls.logging_level.value <= log_level.value: + node_name = '' + if isinstance(node, ASTInlineExpression): + node_name = node.variable_name + # elif isinstance (node, ASTInputPort): + # node_name = "" + elif node is None: + node_name = "unknown node" + else: + node_name = node.get_name() + to_print = '[' + str(cls.curr_message) + ',' - to_print = (to_print + (node.get_name() + ', ' if node is not None else + to_print = (to_print + (node_name + ', ' if node is not None else cls.current_node.get_name() + ', ' if cls.current_node is not None else 'GLOBAL, ')) to_print = to_print + str(log_level.name) to_print = to_print + (', ' + str(error_position) if error_position is not None else '') + ']: ' to_print = to_print + str(message) print(to_print) - return @classmethod def string_to_level(cls, string: str) -> LoggingLevel: """ Returns the logging level corresponding to the handed over string. If no such exits, returns None. :param string: a single string representing the level. + :type string: str :return: a single logging level. + :rtype: LoggingLevel """ - if type(string) != str: - return LoggingLevel.ERROR - elif string == 'INFO': + if string == 'DEBUG': + return LoggingLevel.DEBUG + + if string == 'INFO': return LoggingLevel.INFO - elif string == 'WARNING' or string == 'WARNINGS': + + if string == 'WARNING' or string == 'WARNINGS': return LoggingLevel.WARNING - elif string == 'ERROR' or string == 'ERRORS': + + if string == 'ERROR' or string == 'ERRORS': return LoggingLevel.ERROR - elif string == 'NO' or string == 'NONE': + + if string == 'NO' or string == 'NONE': return LoggingLevel.NO - else: - return LoggingLevel.ERROR + + raise Exception('Tried to convert unknown string \"' + string + '\" to logging level') + + @classmethod + def level_to_string(cls, level: LoggingLevel) -> str: + """ + Returns a string representation of the handed over logging level. + :param level: LoggingLevel to convert. + :return: a string representing the logging level. + """ + if level == LoggingLevel.DEBUG: + return 'DEBUG' + + if level == LoggingLevel.INFO: + return 'INFO' + + if level == LoggingLevel.WARNING: + return 'WARNING' + + if level == LoggingLevel.ERROR: + return 'ERROR' + + if level == LoggingLevel.NO: + return 'NO' + + raise Exception('Tried to convert unknown logging level \"' + str(level) + '\" to string') @classmethod def set_logging_level(cls, level: LoggingLevel) -> None: """ Updates the logging level to the handed over one. :param level: a new logging level. + :type level: LoggingLevel """ if cls.log_frozen: return cls.logging_level = level @classmethod - def set_current_node(cls, node: ASTNode) -> None: + def set_current_node(cls, node: Optional[ASTNode]) -> None: """ Sets the handed over node as the currently processed one. This enables a retrieval of messages for a specific node. @@ -185,7 +240,9 @@ def get_all_messages_of_level_and_or_node(cls, node: ASTNode, level: LoggingLeve both. :param node: a single node instance :param level: a logging level + :type level: LoggingLevel :return: a list of messages with their levels. + :rtype: list((str,Logging_Level) """ if level is None and node is None: return cls.get_log() @@ -202,7 +259,9 @@ def get_all_messages_of_level(cls, level: LoggingLevel) -> List[Tuple[ASTNode, L """ Returns all messages which have a certain logging level. :param level: a logging level + :type level: LoggingLevel :return: a list of messages with their levels. + :rtype: list((str,Logging_Level) """ if level is None: return cls.get_log() @@ -218,6 +277,7 @@ def get_all_messages_of_node(cls, node: ASTNode) -> List[Tuple[ASTNode, LoggingL Returns all messages which have been reported for a certain node. :param node: a single node instance :return: a list of messages with their levels. + :rtype: list((str,Logging_Level) """ if node is None: return cls.get_log() @@ -234,6 +294,7 @@ def has_errors(cls, node: ASTNode) -> bool: Indicates whether the handed over node, thus the corresponding model, has errors. :param node: a single node instance. :return: True if errors detected, otherwise False + :rtype: bool """ return len(cls.get_all_messages_of_level_and_or_node(node, LoggingLevel.ERROR)) > 0 diff --git a/pynestml/utils/logging_helper.py b/pynestml/utils/logging_helper.py index 52d37e04c..b98279702 100644 --- a/pynestml/utils/logging_helper.py +++ b/pynestml/utils/logging_helper.py @@ -26,7 +26,7 @@ from pynestml.utils.messages import Messages -class LoggingHelper(object): +class LoggingHelper: @staticmethod def drop_missing_type_error(_assignment): code, message = Messages.get_type_could_not_be_derived(_assignment.get_expression()) diff --git a/pynestml/utils/messages.py b/pynestml/utils/messages.py index c4e54548c..7a27197e2 100644 --- a/pynestml/utils/messages.py +++ b/pynestml/utils/messages.py @@ -21,91 +21,112 @@ from enum import Enum from typing import Tuple +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from collections.abc import Iterable +from pynestml.meta_model.ast_function import ASTFunction + class MessageCode(Enum): """ A mapping between codes and the corresponding messages. """ START_PROCESSING_FILE = 0 - TYPE_REGISTERED = 1 - START_SYMBOL_TABLE_BUILDING = 2 - FUNCTION_CALL_TYPE_ERROR = 3 - TYPE_NOT_DERIVABLE = 4 - IMPLICIT_CAST = 5 - CAST_NOT_POSSIBLE = 6 - TYPE_DIFFERENT_FROM_EXPECTED = 7 - ADD_SUB_TYPE_MISMATCH = 8 - BUFFER_SET_TO_CONDUCTANCE_BASED = 9 - ODE_UPDATED = 10 - NO_VARIABLE_FOUND = 11 - SPIKE_BUFFER_TYPE_NOT_DEFINED = 12 - NEURON_CONTAINS_ERRORS = 13 - START_PROCESSING_NEURON = 14 - CODE_SUCCESSFULLY_GENERATED = 15 - MODULE_SUCCESSFULLY_GENERATED = 16 - NO_CODE_GENERATED = 17 - VARIABLE_USED_BEFORE_DECLARATION = 18 - VARIABLE_DEFINED_RECURSIVELY = 19 - VALUE_ASSIGNED_TO_BUFFER = 20 - ARG_NOT_KERNEL_OR_EQUATION = 21 - ARG_NOT_BUFFER = 22 - NUMERATOR_NOT_ONE = 23 - ORDER_NOT_DECLARED = 24 - CURRENT_BUFFER_SPECIFIED = 25 - BLOCK_NOT_CORRECT = 26 - VARIABLE_NOT_IN_INIT = 27 - WRONG_NUMBER_OF_ARGS = 28 - NO_RHS = 29 - SEVERAL_LHS = 30 - FUNCTION_REDECLARED = 31 - FUNCTION_NOT_DECLARED = 52 - NO_ODE = 32 - NO_INIT_VALUE = 33 - NEURON_REDECLARED = 34 - NEST_COLLISION = 35 - KERNEL_OUTSIDE_CONVOLVE = 36 - NAME_COLLISION = 37 - TYPE_NOT_SPECIFIED = 38 - NO_TYPE_ALLOWED = 39 - NO_ASSIGNMENT_ALLOWED = 40 - NOT_A_VARIABLE = 41 - MULTIPLE_KEYWORDS = 42 - VECTOR_IN_NON_VECTOR = 43 - VARIABLE_REDECLARED = 44 - SOFT_INCOMPATIBILITY = 45 - HARD_INCOMPATIBILITY = 46 - NO_RETURN = 47 - NOT_LAST_STATEMENT = 48 - SYMBOL_NOT_RESOLVED = 49 + START_SYMBOL_TABLE_BUILDING = 1 + FUNCTION_CALL_TYPE_ERROR = 2 + TYPE_NOT_DERIVABLE = 3 + IMPLICIT_CAST = 4 + CAST_NOT_POSSIBLE = 5 + TYPE_DIFFERENT_FROM_EXPECTED = 6 + ADD_SUB_TYPE_MISMATCH = 7 + BUFFER_SET_TO_CONDUCTANCE_BASED = 8 + NO_VARIABLE_FOUND = 9 + SPIKE_INPUT_PORT_TYPE_NOT_DEFINED = 10 + MODEL_CONTAINS_ERRORS = 11 + START_PROCESSING_MODEL = 12 + CODE_SUCCESSFULLY_GENERATED = 13 + MODULE_SUCCESSFULLY_GENERATED = 14 + NO_CODE_GENERATED = 15 + VARIABLE_USED_BEFORE_DECLARATION = 16 + VARIABLE_DEFINED_RECURSIVELY = 17 + VALUE_ASSIGNED_TO_BUFFER = 18 + ARG_NOT_KERNEL_OR_EQUATION = 19 + ARG_NOT_SPIKE_INPUT = 20 + NUMERATOR_NOT_ONE = 21 + ORDER_NOT_DECLARED = 22 + CONTINUOUS_INPUT_PORT_WITH_QUALIFIERS = 23 + BLOCK_NOT_CORRECT = 24 + VARIABLE_NOT_IN_STATE_BLOCK = 25 + WRONG_NUMBER_OF_ARGS = 26 + NO_RHS = 27 + SEVERAL_LHS = 28 + FUNCTION_REDECLARED = 29 + FUNCTION_NOT_DECLARED = 30 + NO_ODE = 31 + NO_INIT_VALUE = 32 + MODEL_REDECLARED = 33 + NEST_COLLISION = 34 + KERNEL_OUTSIDE_CONVOLVE = 35 + NAME_COLLISION = 36 + TYPE_NOT_SPECIFIED = 37 + NO_TYPE_ALLOWED = 38 + NO_ASSIGNMENT_ALLOWED = 39 + NOT_A_VARIABLE = 40 + MULTIPLE_KEYWORDS = 41 + VECTOR_IN_NON_VECTOR = 42 + VARIABLE_REDECLARED = 43 + SOFT_INCOMPATIBILITY = 44 + HARD_INCOMPATIBILITY = 45 + NO_RETURN = 46 + NOT_LAST_STATEMENT = 47 + SYMBOL_NOT_RESOLVED = 48 + SYNAPSE_SOLVED_BY_GSL = 49 TYPE_MISMATCH = 50 NO_SEMANTICS = 51 NEURON_SOLVED_BY_GSL = 52 - NEURON_ANALYZED = 53 - NO_UNIT = 54 - NOT_NEUROSCIENCE_UNIT = 55 - INTERNAL_WARNING = 56 - OPERATION_NOT_DEFINED = 57 - CONVOLVE_NEEDS_BUFFER_PARAMETER = 58 - INPUT_PATH_NOT_FOUND = 59 - LEXER_ERROR = 60 - PARSER_ERROR = 61 - UNKNOWN_TARGET = 62 - VARIABLE_WITH_SAME_NAME_AS_UNIT = 63 - ANALYSING_TRANSFORMING_NEURON = 64 - ODE_NEEDS_CONSISTENT_UNITS = 65 - TEMPLATED_ARG_TYPES_INCONSISTENT = 66 - MODULE_NAME_INFO = 67 - TARGET_PATH_INFO = 68 - ODE_FUNCTION_NEEDS_CONSISTENT_UNITS = 69 - DELTA_FUNCTION_CANNOT_BE_MIXED = 70 - UNKNOWN_TYPE = 71 - ASTDATATYPE_TYPE_SYMBOL_COULD_NOT_BE_DERIVED = 72 - KERNEL_WRONG_TYPE = 73 - KERNEL_IV_WRONG_TYPE = 74 - EMIT_SPIKE_FUNCTION_BUT_NO_OUTPUT_PORT = 75 - - -class Messages(object): + NO_UNIT = 53 + NOT_NEUROSCIENCE_UNIT = 54 + INTERNAL_WARNING = 55 + OPERATION_NOT_DEFINED = 56 + CONVOLVE_NEEDS_BUFFER_PARAMETER = 57 + INPUT_PATH_NOT_FOUND = 58 + LEXER_ERROR = 59 + PARSER_ERROR = 60 + UNKNOWN_TARGET = 61 + VARIABLE_WITH_SAME_NAME_AS_UNIT = 62 + ANALYSING_TRANSFORMING_NEURON = 63 + ODE_NEEDS_CONSISTENT_UNITS = 64 + TEMPLATED_ARG_TYPES_INCONSISTENT = 65 + MODULE_NAME_INFO = 66 + TARGET_PATH_INFO = 67 + ODE_FUNCTION_NEEDS_CONSISTENT_UNITS = 68 + DELTA_FUNCTION_CANNOT_BE_MIXED = 69 + UNKNOWN_TYPE = 70 + ASTDATATYPE_TYPE_SYMBOL_COULD_NOT_BE_DERIVED = 71 + KERNEL_WRONG_TYPE = 72 + KERNEL_IV_WRONG_TYPE = 73 + EMIT_SPIKE_FUNCTION_BUT_NO_OUTPUT_PORT = 74 + NO_FILES_IN_INPUT_PATH = 75 + STATE_VARIABLES_NOT_INITIALZED = 76 + EQUATIONS_DEFINED_BUT_INTEGRATE_ODES_NOT_CALLED = 77 + TEMPLATE_ROOT_PATH_CREATED = 78 + VECTOR_PARAMETER_WRONG_BLOCK = 79 + VECTOR_PARAMETER_WRONG_TYPE = 80 + VECTOR_PARAMETER_WRONG_SIZE = 81 + PRIORITY_DEFINED_FOR_ONLY_ONE_EVENT_HANDLER = 82 + REPEATED_PRIORITY_VALUE = 83 + DELAY_VARIABLE = 84 + CM_NO_GATING_VARIABLES = 100 + CM_FUNCTION_MISSING = 101 + CM_VARIABLES_NOT_DECLARED = 102 + CM_FUNCTION_BAD_NUMBER_ARGS = 103 + CM_FUNCTION_BAD_RETURN_TYPE = 104 + CM_VARIABLE_NAME_MULTI_USE = 105 + CM_NO_VALUE_ASSIGNMENT = 106 + SYNS_BAD_BUFFER_COUNT = 107 + CM_NO_V_COMP = 108 + + +class Messages: """ This class contains a collection of error messages which enables a centralized maintaining and modifications of those. @@ -123,18 +144,6 @@ def get_start_processing_file(cls, file_path): message = 'Start processing \'' + file_path + '\'!' return MessageCode.START_PROCESSING_FILE, message - @classmethod - def get_new_type_registered(cls, type_name): - """ - Returns a message which indicates that a new type has been registered. - :param type_name: a type name - :type type_name: str - :return: message code tuple - :rtype: (MessageCode,str) - """ - message = 'New type registered \'%s\'!' % type_name - return MessageCode.TYPE_REGISTERED, message - @classmethod def get_input_path_not_found(cls, path): message = 'Input path ("%s") not found!' % (path) @@ -160,6 +169,11 @@ def get_lexer_error(cls): message = 'Error occurred during lexing: abort' return MessageCode.LEXER_ERROR, message + # @classmethod + # def get_could_not_determine_cond_based(cls, type_str, name): + # message = "Unable to determine based on type '" + type_str + "' of variable '" + name + "' whether conductance-based or current-based" + # return MessageCode.LEXER_ERROR, message + @classmethod def get_parser_error(cls): message = 'Error occurred during parsing: abort' @@ -171,7 +185,8 @@ def get_binary_operation_not_defined(cls, lhs, operator, rhs): return MessageCode.OPERATION_NOT_DEFINED, message @classmethod - def get_binary_operation_type_could_not_be_derived(cls, lhs, operator, rhs, lhs_type, rhs_type): + def get_binary_operation_type_could_not_be_derived( + cls, lhs, operator, rhs, lhs_type, rhs_type): message = 'The type of the expression (left-hand side = \'%s\'; binary operator = \'%s\'; right-hand side = \'%s\') could not be derived: left-hand side has type \'%s\' whereas right-hand side has type \'%s\'!' % ( lhs, operator, rhs, lhs_type, rhs_type) return MessageCode.TYPE_MISMATCH, message @@ -188,10 +203,8 @@ def get_convolve_needs_buffer_parameter(cls): @classmethod def get_implicit_magnitude_conversion(cls, lhs, rhs, conversion_factor): - message = 'Non-matching unit types at %s +/- %s! ' \ - 'Implicitly replaced by %s +/- %s * %s.' % ( - lhs.print_symbol(), rhs.print_symbol(), lhs.print_symbol(), conversion_factor, - rhs.print_symbol()) + message = 'Implicit magnitude conversion from %s to %s with factor %s ' % ( + lhs.print_symbol(), rhs.print_symbol(), conversion_factor) return MessageCode.IMPLICIT_CAST, message @classmethod @@ -204,7 +217,13 @@ def get_start_building_symbol_table(cls): return MessageCode.START_SYMBOL_TABLE_BUILDING, 'Start building symbol table!' @classmethod - def get_function_call_implicit_cast(cls, arg_nr, function_call, expected_type, got_type, castable=False): + def get_function_call_implicit_cast( + cls, + arg_nr, + function_call, + expected_type, + got_type, + castable=False): """ Returns a message indicating that an implicit cast has been performed. :param arg_nr: the number of the argument which is cast @@ -256,11 +275,17 @@ def get_implicit_cast_rhs_to_lhs(cls, rhs_type, lhs_type): :return: a message :rtype:(MessageCode,str) """ - message = 'Implicit casting from (compatible) type \'%s\' to \'%s\'.' % (rhs_type, lhs_type) + message = 'Implicit casting from (compatible) type \'%s\' to \'%s\'.' % ( + rhs_type, lhs_type) return MessageCode.IMPLICIT_CAST, message @classmethod - def get_different_type_rhs_lhs(cls, rhs_expression, lhs_expression, rhs_type, lhs_type): + def get_different_type_rhs_lhs( + cls, + rhs_expression, + lhs_expression, + rhs_type, + lhs_type): """ Returns a message indicating that the type of the lhs does not correspond to the one of the rhs and can not be cast down to a common type. @@ -276,10 +301,7 @@ def get_different_type_rhs_lhs(cls, rhs_expression, lhs_expression, rhs_type, lh :rtype:(MessageCode,str) """ message = 'Type of lhs \'%s\' does not correspond to rhs \'%s\'! LHS: \'%s\', RHS: \'%s\'!' % ( - lhs_expression, - rhs_expression, - lhs_type.print_symbol(), - rhs_type.print_symbol()) + lhs_expression, rhs_expression, lhs_type.print_symbol(), rhs_type.print_symbol()) return MessageCode.CAST_NOT_POSSIBLE, message @classmethod @@ -295,7 +317,8 @@ def get_type_different_from_expected(cls, expected_type, got_type): """ from pynestml.symbols.type_symbol import TypeSymbol assert (expected_type is not None and isinstance(expected_type, TypeSymbol)), \ - '(PyNestML.Utils.Message) Not a type symbol provided (%s)!' % type(expected_type) + '(PyNestML.Utils.Message) Not a type symbol provided (%s)!' % type( + expected_type) assert (got_type is not None and isinstance(got_type, TypeSymbol)), \ '(PyNestML.Utils.Message) Not a type symbol provided (%s)!' % type(got_type) message = 'Actual type different from expected. Expected: \'%s\', got: \'%s\'!' % ( @@ -316,20 +339,6 @@ def get_buffer_set_to_conductance_based(cls, buffer): message = 'Buffer \'%s\' set to conductance based!' % buffer return MessageCode.BUFFER_SET_TO_CONDUCTANCE_BASED, message - @classmethod - def get_ode_updated(cls, variable_name): - """ - Returns a message indicating that the ode of a variable has been updated. - :param variable_name: the name of the variable - :type variable_name: str - :return: a message - :rtype: (MessageCode,str) - """ - assert (variable_name is not None and isinstance(variable_name, str)), \ - '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(variable_name) - message = 'Ode of \'%s\' updated!' % variable_name - return MessageCode.ODE_UPDATED, message - @classmethod def get_no_variable_found(cls, variable_name): """ @@ -345,64 +354,63 @@ def get_no_variable_found(cls, variable_name): return MessageCode.NO_VARIABLE_FOUND, message @classmethod - def get_buffer_type_not_defined(cls, buffer_name): + def get_input_port_type_not_defined(cls, input_port_name: str): """ - Returns a message indicating that a buffer type has not been defined, thus nS is assumed. - :param buffer_name: a buffer name - :type buffer_name: str + Returns a message indicating that a input_port type has not been defined, thus nS is assumed. + :param input_port_name: a input_port name :return: a message :rtype: (MessageCode,str) """ - assert (buffer_name is not None and isinstance(buffer_name, str)), \ - '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(buffer_name) + assert (input_port_name is not None and isinstance(input_port_name, str)), \ + '(PyNestML.Utils.Message) Not a string provided (%s)!' % type( + input_port_name) from pynestml.symbols.predefined_types import PredefinedTypes - message = 'No buffer type declared of \'%s\'!' % buffer_name - return MessageCode.SPIKE_BUFFER_TYPE_NOT_DEFINED, message + message = 'No type declared for spiking input port \'%s\'!' % input_port_name + return MessageCode.SPIKE_INPUT_PORT_TYPE_NOT_DEFINED, message @classmethod - def get_neuron_contains_errors(cls, neuron_name): + def get_model_contains_errors( + cls, model_name: str) -> Tuple[MessageCode, str]: """ - Returns a message indicating that a neuron contains errors thus no code is generated. - :param neuron_name: the name of the neuron - :type neuron_name: str + Returns a message indicating that a model contains errors thus no code is generated. + :param model_name: the name of the model :return: a message - :rtype: (MessageCode,str) """ - assert (neuron_name is not None and isinstance(neuron_name, str)), \ - '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(neuron_name) - message = 'Neuron \'' + neuron_name + '\' contains errors. No code generated!' - return MessageCode.NEURON_CONTAINS_ERRORS, message + assert (model_name is not None and isinstance(model_name, str)), \ + '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(model_name) + message = 'Model \'' + model_name + '\' contains errors. No code generated!' + return MessageCode.MODEL_CONTAINS_ERRORS, message @classmethod - def get_start_processing_neuron(cls, neuron_name): + def get_start_processing_model( + cls, model_name: str) -> Tuple[MessageCode, str]: """ - Returns a message indicating that the processing of a neuron is started. - :param neuron_name: the name of the neuron - :type neuron_name: str + Returns a message indicating that the processing of a model is started. + :param model_name: the name of the model :return: a message - :rtype: (MessageCode,str) """ - assert (neuron_name is not None and isinstance(neuron_name, str)), \ - '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(neuron_name) - message = 'Starts processing of the neuron \'' + neuron_name + '\'' - return MessageCode.START_PROCESSING_NEURON, message + assert (model_name is not None and isinstance(model_name, str)), \ + '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(model_name) + message = 'Starts processing of the model \'' + model_name + '\'' + return MessageCode.START_PROCESSING_MODEL, message @classmethod - def get_code_generated(cls, neuron_name, path): + def get_code_generated(cls, model_name, path): """ Returns a message indicating that code has been successfully generated for a neuron in a certain path. - :param neuron_name: the name of the neuron. - :type neuron_name: str + :param model_name: the name of the neuron. + :type model_name: str :param path: the path to the file :type path: str :return: a message :rtype: (MessageCode,str) """ - assert (neuron_name is not None and isinstance(neuron_name, str)), \ - '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(neuron_name) + assert (model_name is not None and isinstance(model_name, str)), \ + '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(model_name) assert (path is not None and isinstance(path, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(path) - message = 'Successfully generated code for the neuron: \'' + neuron_name + '\' in: \'' + path + '\' !' + message = 'Successfully generated code for the model: \'' + \ + model_name + '\' in: \'' + path + '\' !' return MessageCode.CODE_SUCCESSFULLY_GENERATED, message @classmethod @@ -490,18 +498,17 @@ def get_first_arg_not_kernel_or_equation(cls, func_name): return MessageCode.ARG_NOT_KERNEL_OR_EQUATION, message @classmethod - def get_second_arg_not_a_buffer(cls, func_name): + def get_second_arg_not_a_spike_port( + cls, func_name: str) -> Tuple[MessageCode, str]: """ - Indicates that the second argument of an rhs is not a buffer. + Indicates that the second argument of the NESTML convolve() call is not a spiking input port. :param func_name: the name of the function - :type func_name: str :return: a message - :rtype: (MessageCode,str) """ assert (func_name is not None and isinstance(func_name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(func_name) - message = 'Second argument of \'%s\' not a buffer!' % func_name - return MessageCode.ARG_NOT_BUFFER, message + message = 'Second argument of \'%s\' not a spiking input port!' % func_name + return MessageCode.ARG_NOT_SPIKE_INPUT, message @classmethod def get_wrong_numerator(cls, unit): @@ -532,9 +539,9 @@ def get_order_not_declared(cls, lhs): return MessageCode.ORDER_NOT_DECLARED, message @classmethod - def get_current_buffer_specified(cls, name, keyword): + def get_continuous_input_port_specified(cls, name, keyword): """ - Indicates that the current buffer has been specified with a type keyword. + Indicates that the continuous time input port has been specified with an `inputQualifier` keyword. :param name: the name of the buffer :type name: str :param keyword: the keyword @@ -544,8 +551,9 @@ def get_current_buffer_specified(cls, name, keyword): """ assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % name - message = 'Current buffer \'%s\' specified with type keywords (%s)!' % (name, keyword) - return MessageCode.CURRENT_BUFFER_SPECIFIED, message + message = 'Continuous time input port \'%s\' specified with type keywords (%s)!' % ( + name, keyword) + return MessageCode.CONTINUOUS_INPUT_PORT_WITH_QUALIFIERS, message @classmethod def get_block_not_defined_correctly(cls, block, missing): @@ -569,9 +577,9 @@ def get_block_not_defined_correctly(cls, block, missing): return MessageCode.BLOCK_NOT_CORRECT, message @classmethod - def get_equation_var_not_in_init_values_block(cls, variable_name): + def get_equation_var_not_in_state_block(cls, variable_name): """ - Indicates that a variable in the equations block is not defined in the initial values block. + Indicates that a variable in the equations block is not defined in the state block. :param variable_name: the name of the variable of an equation which is not defined in an equations block :type variable_name: str :return: a message @@ -579,8 +587,8 @@ def get_equation_var_not_in_init_values_block(cls, variable_name): """ assert (variable_name is not None and isinstance(variable_name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(variable_name) - message = 'Ode equation lhs-variable \'%s\' not defined in initial-values block!' % variable_name - return MessageCode.VARIABLE_NOT_IN_INIT, message + message = 'Ode equation lhs-variable \'%s\' not defined in state block!' % variable_name + return MessageCode.VARIABLE_NOT_IN_STATE_BLOCK, message @classmethod def get_wrong_number_of_args(cls, function_call, expected, got): @@ -655,7 +663,7 @@ def get_function_redeclared(cls, name, predefined): @classmethod def get_no_ode(cls, name): """ - Indicates that no ODE has been defined for a variable inside the initial values block. + Indicates that no ODE has been defined for a variable inside the state block. :param name: the name of the variable which does not have a defined ode :type name: str :return: a message @@ -681,20 +689,18 @@ def get_no_init_value(cls, name): return MessageCode.NO_INIT_VALUE, message @classmethod - def get_neuron_redeclared(cls, name): + def get_model_redeclared(cls, name: str) -> Tuple[MessageCode, str]: """ - Indicates that a neuron has been redeclared. - :param name: the name of the neuron which has been redeclared. - :type name: str + Indicates that a model has been redeclared. + :param name: the name of the model which has been redeclared. :return: a message - :rtype: (MessageCode,str) """ assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) - message = 'Neuron \'%s\' redeclared!' % name - return MessageCode.NEURON_REDECLARED, message + message = 'model \'%s\' redeclared!' % name + return MessageCode.MODEL_REDECLARED, message @classmethod def get_nest_collision(cls, name): @@ -743,7 +749,8 @@ def get_compilation_unit_name_collision(cls, name, art1, art2): '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(art1) assert (art2 is not None and isinstance(art2, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(art2) - message = 'Name collision of \'%s\' in \'%s\' and \'%s\'!' % (name, art1, art2) + message = 'Name collision of \'%s\' in \'%s\' and \'%s\'!' % ( + name, art1, art2) return MessageCode.NAME_COLLISION, message @classmethod @@ -831,7 +838,8 @@ def get_vector_in_non_vector(cls, vector, non_vector): '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(vector) assert (non_vector is not None and isinstance(non_vector, list)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(non_vector) - message = 'Vector value \'%s\' used in a non-vector declaration of variables \'%s\'!' % (vector, non_vector) + message = 'Vector value \'%s\' used in a non-vector declaration of variables \'%s\'!' % ( + vector, non_vector) return MessageCode.VECTOR_IN_NON_VECTOR, message @classmethod @@ -925,18 +933,19 @@ def get_neuron_solved_by_solver(cls, name): return MessageCode.NEURON_SOLVED_BY_GSL, message @classmethod - def get_neuron_analyzed(cls, name): + def get_synapse_solved_by_solver(cls, name): """ - Indicates that the analysis of a neuron will start. - :param name: the name of the neuron which will be analyzed. + Indicates that a synapse will be solved by the GSL solver inside the model printing process without any + modifications to the initial model. + :param name: the name of the synapse :type name: str :return: a message :rtype: (MessageCode,str) """ assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) - message = 'The neuron \'%s\' will be analysed!' % name - return MessageCode.NEURON_ANALYZED, message + message = 'The synapse \'%s\' will be solved numerically with GSL solver without modification!' % name + return MessageCode.SYNAPSE_SOLVED_BY_GSL, message @classmethod def get_could_not_be_solved(cls): @@ -1008,22 +1017,29 @@ def get_not_neuroscience_unit_used(cls, name): return MessageCode.NOT_NEUROSCIENCE_UNIT, message @classmethod - def get_ode_needs_consistent_units(cls, name, differential_order, lhs_type, rhs_type): + def get_ode_needs_consistent_units( + cls, + name, + differential_order, + lhs_type, + rhs_type): assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) message = 'ODE definition for \'' if differential_order > 1: - message += 'd^' + str(differential_order) + ' ' + name + ' / dt^' + str(differential_order) + '\'' + message += 'd^' + str(differential_order) + ' ' + \ + name + ' / dt^' + str(differential_order) + '\'' if differential_order > 0: message += 'd ' + name + ' / dt\'' else: message += '\'' + str(name) + '\'' - message += ' has inconsistent units: expected \'' + lhs_type.print_symbol() + '\', got \'' + \ - rhs_type.print_symbol() + '\'' + message += ' has inconsistent units: expected \'' + \ + lhs_type.print_symbol() + '\', got \'' + rhs_type.print_symbol() + '\'' return MessageCode.ODE_NEEDS_CONSISTENT_UNITS, message @classmethod - def get_ode_function_needs_consistent_units(cls, name, declared_type, expression_type): + def get_ode_function_needs_consistent_units( + cls, name, declared_type, expression_type): assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) message = 'ODE function definition for \'' + name + '\' has inconsistent units: expected \'' + \ @@ -1059,7 +1075,13 @@ def get_analysing_transforming_neuron(cls, name): return MessageCode.ANALYSING_TRANSFORMING_NEURON, message @classmethod - def templated_arg_types_inconsistent(cls, function_name, failing_arg_idx, other_args_idx, failing_arg_type_str, other_type_str): + def templated_arg_types_inconsistent( + cls, + function_name, + failing_arg_idx, + other_args_idx, + failing_arg_type_str, + other_type_str): """ For templated function arguments, indicates inconsistency between (formal) template argument types and actual derived types. :param name: the name of the neuron model @@ -1069,7 +1091,8 @@ def templated_arg_types_inconsistent(cls, function_name, failing_arg_idx, other_ """ message = 'In function \'' + function_name + '\': actual derived type of templated parameter ' + \ str(failing_arg_idx + 1) + ' is \'' + failing_arg_type_str + '\', which is inconsistent with that of parameter(s) ' + \ - ', '.join([str(_ + 1) for _ in other_args_idx]) + ', which have type \'' + other_type_str + '\'' + ', '.join([str(_ + 1) for _ in other_args_idx]) + \ + ', which have type \'' + other_type_str + '\'' return MessageCode.TEMPLATED_ARG_TYPES_INCONSISTENT, message @classmethod @@ -1122,7 +1145,11 @@ def get_emit_spike_function_but_no_output_port(cls): return MessageCode.EMIT_SPIKE_FUNCTION_BUT_NO_OUTPUT_PORT, message @classmethod - def get_kernel_wrong_type(cls, kernel_name: str, differential_order: int, actual_type: str) -> Tuple[MessageCode, str]: + def get_kernel_wrong_type(cls, + kernel_name: str, + differential_order: int, + actual_type: str) -> Tuple[MessageCode, + str]: """ Returns a message indicating that the type of a kernel is wrong. :param kernel_name: the name of the kernel @@ -1141,19 +1168,174 @@ def get_kernel_wrong_type(cls, kernel_name: str, differential_order: int, actual return MessageCode.KERNEL_WRONG_TYPE, message @classmethod - def get_kernel_iv_wrong_type(cls, iv_name: str, actual_type: str, expected_type: str) -> Tuple[MessageCode, str]: + def get_kernel_iv_wrong_type(cls, + iv_name: str, + actual_type: str, + expected_type: str) -> Tuple[MessageCode, + str]: """ Returns a message indicating that the type of a kernel initial value is wrong. - :param iv_name: the name of the initial value variable + :param iv_name: the name of the state variable with an initial value :param actual_type: the name of the actual type that was found in the model :param expected_type: the name of the type that was expected """ - message = 'Initial value \'%s\' was found to be of type \'%s\' (should be %s)!' % (iv_name, actual_type, expected_type) + message = 'Initial value \'%s\' was found to be of type \'%s\' (should be %s)!' % ( + iv_name, actual_type, expected_type) return MessageCode.KERNEL_IV_WRONG_TYPE, message + @classmethod + def get_no_files_in_input_path(cls, path: str): + message = "No files found matching '*.nestml' in provided input path '" + path + "'" + return MessageCode.NO_FILES_IN_INPUT_PATH, message @classmethod - def get_could_not_determine_cond_based(cls, type_str, name): - message = "Unable to determine based on type '" + type_str + \ - "' of variable '" + name + "' whether conductance-based or current-based" - return MessageCode.LEXER_ERROR, message + def get_state_variables_not_initialized(cls, var_name: str): + message = "The variable \'%s\' is not initialized." % var_name + return MessageCode.STATE_VARIABLES_NOT_INITIALZED, message + + @classmethod + def get_equations_defined_but_integrate_odes_not_called(cls): + message = "Equations defined but integrate_odes() not called" + return MessageCode.EQUATIONS_DEFINED_BUT_INTEGRATE_ODES_NOT_CALLED, message + + @classmethod + def get_template_root_path_created(cls, templates_root_dir: str): + message = "Given template root path is not an absolute path. " \ + "Creating the absolute path with default templates directory '" + \ + templates_root_dir + "'" + return MessageCode.TEMPLATE_ROOT_PATH_CREATED, message + + @classmethod + def get_vector_parameter_wrong_block(cls, var, block): + message = "The vector parameter '" + var + "' is declared in the wrong block '" + block + \ + "'. " "The vector parameter can only be declared in parameters or internals block." + return MessageCode.VECTOR_PARAMETER_WRONG_BLOCK, message + + @classmethod + def get_vector_parameter_wrong_type(cls, var): + message = "The vector parameter '" + var + "' is of the wrong type." \ + "The vector parameter can be only of type integer." + return MessageCode.VECTOR_PARAMETER_WRONG_TYPE, message + + @classmethod + def get_vector_parameter_wrong_size(cls, var, value): + message = "The vector parameter '" + var + "' has value '" + \ + value + "' " "which is less than or equal to 0." + return MessageCode.VECTOR_PARAMETER_WRONG_SIZE, message + + @classmethod + def get_priority_defined_for_only_one_receive_block( + cls, event_handler_port_name: str): + message = "Priority defined for only one event handler (" + \ + event_handler_port_name + ")" + return MessageCode.PRIORITY_DEFINED_FOR_ONLY_ONE_EVENT_HANDLER, message + + @classmethod + def get_repeated_priorty_value(cls): + message = "Priority values for event handlers need to be unique" + return MessageCode.REPEATED_PRIORITY_VALUE, message + + @classmethod + def get_function_is_delay_variable(cls, func): + message = "Function '" + func + "' is not a function but a delay variable." + return MessageCode.DELAY_VARIABLE, message + + @classmethod + def get_no_gating_variables( + cls, + cm_inline_expr: ASTInlineExpression, + ion_channel_name: str): + """ + Indicates that if you defined an inline expression inside the equations block + that uses no kernels / has no convolution calls + then then there must be at least one variable name that ends with _{x} + For example an inline "Na" must have at least one variable ending with "_Na" + :return: a message + :rtype: (MessageCode,str) + """ + + message = "No gating variables found inside declaration of '" + \ + cm_inline_expr.variable_name + "', " + message += "\nmeaning no variable ends with the suffix '_" + \ + ion_channel_name + "' here. " + message += "This suffix indicates that a variable is a gating variable. " + message += "At least one gating variable is expected to exist." + + return MessageCode.CM_NO_GATING_VARIABLES, message + + @classmethod + def get_cm_inline_expression_variable_used_mulitple_times( + cls, + cm_inline_expr: ASTInlineExpression, + bad_variable_name: str, + ion_channel_name: str): + message = "Variable name '" + bad_variable_name + \ + "' seems to be used multiple times" + message += "' inside inline expression '" + cm_inline_expr.variable_name + "'. " + message += "\nVariables are not allowed to occur multiple times here." + + return MessageCode.CM_VARIABLE_NAME_MULTI_USE, message + + @classmethod + def get_expected_cm_function_missing( + cls, + ion_channel_name: str, + variable_name: str, + function_name: str): + message = "Implementation of a function called '" + function_name + "' not found. " + message += "It is expected because of variable '" + \ + variable_name + "' in the ion channel '" + ion_channel_name + "'" + return MessageCode.CM_FUNCTION_MISSING, message + + @classmethod + def get_expected_cm_function_wrong_args_count( + cls, ion_channel_name: str, variable_name, astfun: ASTFunction): + message = "Function '" + astfun.name + \ + "' is expected to have exactly one Argument. " + message += "It is related to variable '" + variable_name + \ + "' in the ion channel '" + ion_channel_name + "'" + return MessageCode.CM_FUNCTION_BAD_NUMBER_ARGS, message + + @classmethod + def get_expected_cm_function_bad_return_type( + cls, ion_channel_name: str, astfun: ASTFunction): + message = "'" + ion_channel_name + "' channel function '" + \ + astfun.name + "' must return real. " + return MessageCode.CM_FUNCTION_BAD_RETURN_TYPE, message + + @classmethod + def get_expected_cm_variables_missing_in_blocks( + cls, + missing_variable_to_proper_block: Iterable, + expected_variables_to_reason: dict): + message = "The following variables not found:\n" + for missing_var, proper_location in missing_variable_to_proper_block.items(): + message += "Variable with name '" + missing_var + message += "' not found but expected to exist inside of " + \ + proper_location + " because of position " + message += str( + expected_variables_to_reason[missing_var].get_source_position()) + "\n" + return MessageCode.CM_VARIABLES_NOT_DECLARED, message + + @classmethod + def get_cm_variable_value_missing(cls, varname: str): + message = "The following variable has no value assinged: " + varname + "\n" + return MessageCode.CM_NO_VALUE_ASSIGNMENT, message + + @classmethod + def get_v_comp_variable_value_missing( + cls, neuron_name: str, missing_variable_name): + message = "Missing state variable '" + missing_variable_name + message += "' in side of neuron +'" + neuron_name + "'+. " + message += "You have passed NEST_COMPARTMENTAL flag to the generator, thereby activating compartmental mode." + message += "In this mode, such variable must be declared in the state block.\n" + message += "This variable represents the dynamically calculated value of membrane potential " + message += "and should be utilized in your equations for voltage activated ion channels." + return MessageCode.CM_NO_V_COMP, message + + @classmethod + def get_syns_bad_buffer_count(cls, buffers: set, synapse_name: str): + message = "Synapse `\'%s\' uses the following input buffers: %s" % ( + synapse_name, buffers) + message += " However exaxtly one spike input buffer per synapse is allowed." + return MessageCode.SYNS_BAD_BUFFER_COUNT, message diff --git a/pynestml/utils/model_installer.py b/pynestml/utils/model_installer.py deleted file mode 100644 index 3b1ec8028..000000000 --- a/pynestml/utils/model_installer.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -# -# model_installer.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -import os -import subprocess -import sys - - -def install_nest(models_path, nest_path): - """ - This method can be used to install all models located in the ${models} dir into NEST. For the simulator, - the path to the installation has to be provided (a.k.a. the -Dwith-nest argument of the make command). - Caution: The nest_path should only point to the install dir, the suffix /bin/nest-config is automatically attached. - """ - if not os.path.isdir(models_path): - print('PyNestML: Models path not a directory (%s)! abort installation...' % models_path) - return - if not os.path.isdir(nest_path): - print('PyNestML: NEST path not a directory (%s)! abort installation...' % nest_path) - return - - cmake_cmd = ['cmake', '-Dwith-nest=' + str(nest_path) + '/bin/nest-config', '.'] - make_all_cmd = ['make', 'all'] - make_install_cmd = ['make', 'install'] - # check if we run on win - if sys.platform.startswith('win'): - shell = True - else: - shell = False - - # first call cmake with all the arguments - try: - result = subprocess.check_call(cmake_cmd, stderr=subprocess.STDOUT, shell=shell, - cwd=str(os.path.join(models_path))) - except subprocess.CalledProcessError as e: - print('PyNestML: Something went wrong in \'cmake\', see error above!') - print('abort installation...') - return - - # now execute make all - try: - subprocess.check_call(make_all_cmd, stderr=subprocess.STDOUT, shell=shell, - cwd=str(os.path.join(models_path))) - except subprocess.CalledProcessError as e: - print('PyNestML: Something went wrong in \'make all\', see error above!') - print('abort installation...') - return - - # finally execute make install - try: - subprocess.check_call(make_install_cmd, stderr=subprocess.STDOUT, shell=shell, - cwd=str(os.path.join(models_path))) - except subprocess.CalledProcessError as e: - print('PyNestML: Something went wrong in \'make install\', see error above!') - print('abort installation...') - return diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 50b4299bf..856903612 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -18,9 +18,10 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -import copy -from antlr4 import * +from typing import Tuple + +from antlr4 import CommonTokenStream, FileStream, InputStream from antlr4.error.ErrorStrategy import BailErrorStrategy, DefaultErrorStrategy from antlr4.error.ErrorListener import ConsoleErrorListener @@ -30,7 +31,6 @@ from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables -from pynestml.meta_model.ast_body import ASTBody from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_data_type import ASTDataType @@ -44,21 +44,22 @@ from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.meta_model.ast_if_clause import ASTIfClause from pynestml.meta_model.ast_if_stmt import ASTIfStmt +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_port import ASTInputPort from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier +from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody from pynestml.meta_model.ast_ode_equation import ASTOdeEquation -from pynestml.meta_model.ast_inline_expression import ASTInlineExpression -from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_output_block import ASTOutputBlock from pynestml.meta_model.ast_parameter import ASTParameter from pynestml.meta_model.ast_return_stmt import ASTReturnStmt from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.meta_model.ast_small_stmt import ASTSmallStmt -from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator from pynestml.meta_model.ast_unit_type import ASTUnitType @@ -66,17 +67,17 @@ from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_while_stmt import ASTWhileStmt from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.error_listener import NestMLErrorListener from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages from pynestml.visitors.ast_builder_visitor import ASTBuilderVisitor from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor -from pynestml.utils.error_listener import NestMLErrorListener - -class ModelParser(object): +class ModelParser: @classmethod def parse_model(cls, file_path=None): """ @@ -135,13 +136,12 @@ def parse_model(cls, file_path=None): # create and update the corresponding symbol tables SymbolTable.initialize_symbol_table(ast.get_source_position()) - log_to_restore = copy.deepcopy(Logger.get_log()) - counter = Logger.curr_message - - Logger.set_log(log_to_restore, counter) for neuron in ast.get_neuron_list(): neuron.accept(ASTSymbolTableVisitor()) SymbolTable.add_neuron_scope(neuron.get_name(), neuron.get_scope()) + for synapse in ast.get_synapse_list(): + synapse.accept(ASTSymbolTableVisitor()) + SymbolTable.add_synapse_scope(synapse.get_name(), synapse.get_scope()) # store source paths for neuron in ast.get_neuron_list(): @@ -207,8 +207,7 @@ def parse_block_with_variables(cls, string): return ret @classmethod - def parse_body(cls, string): - # type: (str) -> ASTBody + def parse_neuron_or_synapse_body(cls, string: str) -> ASTNeuronOrSynapseBody: (builder, parser) = tokenize(string) ret = builder.visit(parser.body()) ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) @@ -350,6 +349,14 @@ def parse_neuron(cls, string): ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret + @classmethod + def parse_synapse(cls, string): + # type: (str) -> ASTSynapse + (builder, parser) = tokenize(string) + ret = builder.visit(parser.synapse()) + ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret + @classmethod def parse_ode_equation(cls, string): # type: (str) -> ASTOdeEquation @@ -455,8 +462,7 @@ def parse_while_stmt(cls, string): return ret -def tokenize(string): - # type: (str) -> (ASTBuilderVisitor,PyNestMLParser) +def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: lexer = PyNestMLLexer(InputStream(string)) # create a token stream stream = CommonTokenStream(lexer) diff --git a/pynestml/utils/ode_transformer.py b/pynestml/utils/ode_transformer.py deleted file mode 100644 index fa6916ae7..000000000 --- a/pynestml/utils/ode_transformer.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -# -# ode_transformer.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -from copy import copy - -from pynestml.meta_model.ast_function_call import ASTFunctionCall -from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor - - -class OdeTransformer(object): - """ - This class contains several methods as used to transform ODEs. - """ - - @classmethod - def get_convolve_function_calls(cls, ast): - """ - Returns all sum function calls in the handed over meta_model node or one of its children. - :param ast: a single meta_model node. - :type ast: ASTNode - """ - return cls.get_function_calls(ast, PredefinedFunctions.CONVOLVE) - - @classmethod - def contains_convolve_function_call(cls, ast): - """ - Indicates whether _ast or one of its child nodes contains a sum call. - :param ast: a single meta_model - :type ast: ASTNode - :return: True if sum is contained, otherwise False. - :rtype: bool - """ - return len(cls.get_function_calls(ast, PredefinedFunctions.CONVOLVE)) > 0 - - @classmethod - def get_function_calls(cls, ast_node, function_list): - """ - For a handed over list of function names, this method retrieves all functions in the meta_model. - :param ast_node: a single meta_model node - :type ast_node: ASTNode - :param function_list: a list of function names - :type function_list: list(str) - :return: a list of all functions in the meta_model - :rtype: list(ASTFunctionCall) - """ - res = list() - from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor - from pynestml.meta_model.ast_function_call import ASTFunctionCall - fun = (lambda x: res.append(x) if isinstance(x, ASTFunctionCall) and x.get_name() in function_list else True) - vis = ASTHigherOrderVisitor(visit_funcs=fun) - ast_node.accept(vis) - return res diff --git a/pynestml/utils/port_signal_type.py b/pynestml/utils/port_signal_type.py index 778b73208..0d230e30f 100644 --- a/pynestml/utils/port_signal_type.py +++ b/pynestml/utils/port_signal_type.py @@ -27,4 +27,4 @@ class PortSignalType(Enum): This enum is used to describe the type of the received or emitted signal. """ SPIKE = 1 - CURRENT = 2 + CONTINUOUS = 2 diff --git a/pynestml/utils/stack.py b/pynestml/utils/stack.py index f4bac5fab..4cad97c3c 100644 --- a/pynestml/utils/stack.py +++ b/pynestml/utils/stack.py @@ -20,7 +20,7 @@ # along with NEST. If not, see . -class Stack(object): +class Stack: """ This class represents a simple version of a stack. """ @@ -66,6 +66,8 @@ def is_empty(self): return len(self.list) == 0 def top(self): + if self.currentIndex < 0: + return None return self.list[self.currentIndex] def pop_n_to_list(self, n): diff --git a/pynestml/utils/syns_info_enricher.py b/pynestml/utils/syns_info_enricher.py new file mode 100644 index 000000000..4eb0d78d4 --- /dev/null +++ b/pynestml/utils/syns_info_enricher.py @@ -0,0 +1,804 @@ +# -*- coding: utf-8 -*- +# +# syns_info_enricher.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from _collections import defaultdict +import copy + +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor +from pynestml.visitors.ast_visitor import ASTVisitor +import sympy + + +class SynsInfoEnricher(ASTVisitor): + """ + input: a neuron after ODE-toolbox transformations + + the kernel analysis solves all kernels at the same time + this splits the variables on per kernel basis + + """ + variables_to_internal_declarations = {} + internal_variable_name_to_variable = {} + inline_name_to_transformed_inline = {} + + # assuming depth first traversal + # collect declaratins in the order + # in which they were present in the neuron + declarations_ordered = [] + + @classmethod + def enrich_with_additional_info( + cls, + neuron: ASTNeuron, + cm_syns_info: dict, + kernel_name_to_analytic_solver: dict): + cm_syns_info = cls.add_kernel_analysis( + neuron, cm_syns_info, kernel_name_to_analytic_solver) + cm_syns_info = cls.transform_analytic_solution(neuron, cm_syns_info) + cm_syns_info = cls.restoreOrderInternals(neuron, cm_syns_info) + return cm_syns_info + + """ + cm_syns_info input structure + + { + "AMPA": + { + "inline_expression": ASTInlineExpression, + "buffers_used": {"b_spikes"}, + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + } + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + } + } + } + + }, + "GABA": + { + ... + } + ... + } + + output + + { + "AMPA": + { + "inline_expression": ASTInlineExpression, + "buffers_used": {"b_spikes"}, + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + } + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + } + "analytic_solution": + { + 'propagators': + { + '__P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes': + 'exp(-__h/tau_syn_AMPA)' + }, + 'update_expressions': + { + 'g_ex_AMPA__X__b_spikes': + '__P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes*g_ex_AMPA__X__b_spikes' + }, + 'state_variables': ['g_ex_AMPA__X__b_spikes'], + 'initial_values': + { + 'g_ex_AMPA__X__b_spikes': '1', + }, + 'solver': "analytical", + 'parameters': + { + 'tau_syn_AMPA': '0.200000000000000', + }, + } + } + } + + }, + "GABA": + { + ... + } + ... + } + + + """ + + @classmethod + def add_kernel_analysis( + cls, + neuron: ASTNeuron, + cm_syns_info: dict, + kernel_name_to_analytic_solver: dict): + enriched_syns_info = copy.copy(cm_syns_info) + for synapse_name, synapse_info in cm_syns_info.items(): + for convolution_name, convolution_info in synapse_info["convolutions"].items( + ): + kernel_name = convolution_info["kernel"]["name"] + analytic_solution = kernel_name_to_analytic_solver[neuron.get_name( + )][kernel_name] + enriched_syns_info[synapse_name]["convolutions"][convolution_name]["analytic_solution"] = analytic_solution + return enriched_syns_info + + """ + cm_syns_info input structure + + { + "AMPA": + { + "inline_expression": ASTInlineExpression, + "buffers_used": {"b_spikes"}, + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + "analytic_solution": + { + 'propagators': + { + '__P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes': + 'exp(-__h/tau_syn_AMPA)' + }, + 'update_expressions': + { + 'g_ex_AMPA__X__b_spikes': + '__P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes*g_ex_AMPA__X__b_spikes' + }, + 'state_variables': ['g_ex_AMPA__X__b_spikes'], + 'initial_values': + { + 'g_ex_AMPA__X__b_spikes': '1', + }, + 'solver': "analytical", + 'parameters': + { + 'tau_syn_AMPA': '0.200000000000000', + }, + } + } + } + + }, + "GABA": + { + ... + } + ... + } + + output + + { + "AMPA": + { + "inline_expression": ASTInlineExpression, #transformed version + "inline_expression_d": ASTExpression, + "buffer_name": "b_spikes", + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "analytic_helpers": + { + "__h": + { + "ASTVariable": ASTVariable, + "init_expression": ASTExpression, + "is_time_resolution": True, + }, + } + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + "analytic_solution": + { + 'kernel_states': + { + "g_ex_AMPA__X__b_spikes": + { + "ASTVariable": ASTVariable, + "init_expression": AST(Simple)Expression, + "update_expression": ASTExpression, + } + }, + 'propagators': + { + __P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes: + { + "ASTVariable": ASTVariable, + "init_expression": ASTExpression, + }, + }, + } + } + } + + }, + "GABA": + { + ... + } + ... + } + """ + + @classmethod + def transform_analytic_solution( + cls, + neuron: ASTNeuron, + cm_syns_info: dict): + + enriched_syns_info = copy.copy(cm_syns_info) + for synapse_name, synapse_info in cm_syns_info.items(): + for convolution_name in synapse_info["convolutions"].keys(): + analytic_solution = enriched_syns_info[synapse_name][ + "convolutions"][convolution_name]["analytic_solution"] + analytic_solution_transformed = defaultdict( + lambda: defaultdict()) + + for variable_name, expression_str in analytic_solution["initial_values"].items( + ): + variable = neuron.get_equations_block().get_scope( + ).resolve_to_symbol(variable_name, SymbolKind.VARIABLE) + + expression = ModelParser.parse_expression(expression_str) + # pretend that update expressions are in "equations" block, + # which should always be present, as synapses have been + # defined to get here + expression.update_scope( + neuron.get_equations_blocks().get_scope()) + expression.accept(ASTSymbolTableVisitor()) + + update_expr_str = analytic_solution["update_expressions"][variable_name] + update_expr_ast = ModelParser.parse_expression( + update_expr_str) + # pretend that update expressions are in "equations" block, + # which should always be present, as differential equations + # must have been defined to get here + update_expr_ast.update_scope( + neuron.get_equations_blocks().get_scope()) + update_expr_ast.accept(ASTSymbolTableVisitor()) + + analytic_solution_transformed['kernel_states'][variable_name] = { + "ASTVariable": variable, + "init_expression": expression, + "update_expression": update_expr_ast, + } + + for variable_name, expression_string in analytic_solution["propagators"].items( + ): + variable = cls.internal_variable_name_to_variable[variable_name] + expression = ModelParser.parse_expression( + expression_string) + # pretend that update expressions are in "equations" block, + # which should always be present, as synapses have been + # defined to get here + expression.update_scope( + neuron.get_equations_blocks().get_scope()) + expression.accept(ASTSymbolTableVisitor()) + analytic_solution_transformed['propagators'][variable_name] = { + "ASTVariable": variable, "init_expression": expression, } + + enriched_syns_info[synapse_name]["convolutions"][convolution_name]["analytic_solution"] = analytic_solution_transformed + + # only one buffer allowed, so allow direct access + # to it instead of a list + if "buffer_name" not in enriched_syns_info[synapse_name]: + buffers_used = list( + enriched_syns_info[synapse_name]["buffers_used"]) + del enriched_syns_info[synapse_name]["buffers_used"] + enriched_syns_info[synapse_name]["buffer_name"] = buffers_used[0] + + inline_expression_name = enriched_syns_info[synapse_name]["inline_expression"].variable_name + enriched_syns_info[synapse_name]["inline_expression"] = \ + SynsInfoEnricher.inline_name_to_transformed_inline[inline_expression_name] + enriched_syns_info[synapse_name]["inline_expression_d"] = \ + cls.computeExpressionDerivative( + enriched_syns_info[synapse_name]["inline_expression"]) + + # now also identify analytic helper variables such as __h + enriched_syns_info[synapse_name]["analytic_helpers"] = cls.get_analytic_helper_variable_declarations( + enriched_syns_info[synapse_name]) + + return enriched_syns_info + + """ + input: + { + "AMPA": + { + "inline_expression": ASTInlineExpression, #transformed version + "inline_expression_d": ASTExpression, + "buffer_name": "b_spikes", + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "analytic_helpers": + { + "__h": + { + "ASTVariable": ASTVariable, + "init_expression": ASTExpression, + "is_time_resolution": True, + }, + } + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + "analytic_solution": + { + 'kernel_states': + { + "g_ex_AMPA__X__b_spikes": + { + "ASTVariable": ASTVariable, + "init_expression": AST(Simple)Expression, + "update_expression": ASTExpression, + } + }, + 'propagators': + { + __P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes: + { + "ASTVariable": ASTVariable, + "init_expression": ASTExpression, + }, + }, + } + } + } + + }, + "GABA": + { + ... + } + ... + } + + output: + { + "AMPA": + { + "inline_expression": ASTInlineExpression, #transformed version + "inline_expression_d": ASTExpression, + "buffer_name": "b_spikes", + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + [ + ("td", ASTDeclaration), + ("g_norm_exc", ASTDeclaration), + ], + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "analytic_helpers": + { + "__h": + { + "ASTVariable": ASTVariable, + "init_expression": ASTExpression, + "is_time_resolution": True, + }, + } + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + "analytic_solution": + { + 'kernel_states': + { + "g_ex_AMPA__X__b_spikes": + { + "ASTVariable": ASTVariable, + "init_expression": AST(Simple)Expression, + "update_expression": ASTExpression, + } + }, + 'propagators': + { + __P__g_ex_AMPA__X__b_spikes__g_ex_AMPA__X__b_spikes: + { + "ASTVariable": ASTVariable, + "init_expression": ASTExpression, + }, + }, + } + } + } + + }, + "GABA": + { + ... + } + ... + } + """ + + # orders user defined internals + # back to the order they were originally defined + # this is important if one such variable uses another + # user needs to have control over the order + @classmethod + def restoreOrderInternals(cls, neuron: ASTNeuron, cm_syns_info: dict): + + # assign each variable a rank + # that corresponds to the order in + # SynsInfoEnricher.declarations_ordered + variable_name_to_order = {} + for index, declaration in enumerate( + SynsInfoEnricher.declarations_ordered): + variable_name = declaration.get_variables()[0].get_name() + variable_name_to_order[variable_name] = index + + enriched_syns_info = copy.copy(cm_syns_info) + for synapse_name, synapse_info in cm_syns_info.items(): + user_internals = enriched_syns_info[synapse_name]["internals_used_declared"] + user_internals_sorted = sorted( + user_internals.items(), key=lambda x: variable_name_to_order[x[0]]) + enriched_syns_info[synapse_name]["internals_used_declared"] = user_internals_sorted + + return enriched_syns_info + + @classmethod + def prettyPrint(cls, syns_info, indent=2): + print('\t' * indent + "{") + for key, value in syns_info.items(): + print('\t' * indent + "\"" + str(key) + "\":") + if isinstance(value, dict): + cls.prettyPrint(value, indent + 1) + else: + print('\t' * (indent + 1) + str(value).replace("\n", + '\n' + '\t' * (indent + 1)) + ", ") + print('\t' * indent + "},") + + @classmethod + def computeExpressionDerivative( + cls, inline_expression: ASTInlineExpression) -> ASTExpression: + expr_str = str(inline_expression.get_expression()) + sympy_expr = sympy.parsing.sympy_parser.parse_expr(expr_str) + sympy_expr = sympy.diff(sympy_expr, "v_comp") + + ast_expression_d = ModelParser.parse_expression(str(sympy_expr)) + # copy scope of the original inline_expression into the the derivative + ast_expression_d.update_scope(inline_expression.get_scope()) + ast_expression_d.accept(ASTSymbolTableVisitor()) + + return ast_expression_d + + @classmethod + def get_variable_names_used(cls, node) -> set: + variable_names_extractor = ASTUsedVariableNamesExtractor(node) + return variable_names_extractor.variable_names + + # returns all variable names referenced by the synapse inline + # and by the analytical solution + # assumes that the model has already been transformed + @classmethod + def get_all_synapse_variables(cls, single_synapse_info): + # get all variables from transformed inline + inline_variables = cls.get_variable_names_used( + single_synapse_info["inline_expression"]) + + analytic_solution_vars = set() + # get all variables from transformed analytic solution + for convolution_name, convolution_info in single_synapse_info["convolutions"].items( + ): + analytic_sol = convolution_info["analytic_solution"] + # get variables from init and update expressions + # for each kernel + for kernel_var_name, kernel_info in analytic_sol["kernel_states"].items( + ): + analytic_solution_vars.add(kernel_var_name) + + update_vars = cls.get_variable_names_used( + kernel_info["update_expression"]) + init_vars = cls.get_variable_names_used( + kernel_info["init_expression"]) + + analytic_solution_vars.update(update_vars) + analytic_solution_vars.update(init_vars) + + # get variables from init expressions + # for each propagator + # include propagator variable itself + for propagator_var_name, propagator_info in analytic_sol["propagators"].items( + ): + analytic_solution_vars.add(propagator_var_name) + + init_vars = cls.get_variable_names_used( + propagator_info["init_expression"]) + + analytic_solution_vars.update(init_vars) + + return analytic_solution_vars.union(inline_variables) + + @classmethod + def get_new_variables_after_transformation(cls, single_synapse_info): + return cls.get_all_synapse_variables(single_synapse_info).difference( + single_synapse_info["total_used_declared"]) + + # get new variables that only occur on the right hand side of analytic solution Expressions + # but for wich analytic solution does not offer any values + # this can isolate out additional variables that suddenly appear such as __h + # whose initial values are not inlcuded in the output of analytic solver + @classmethod + def get_analytic_helper_variable_names(cls, single_synapse_info): + analytic_lhs_vars = set() + + for convolution_name, convolution_info in single_synapse_info["convolutions"].items( + ): + analytic_sol = convolution_info["analytic_solution"] + + # get variables representing convolutions by kernel + for kernel_var_name, kernel_info in analytic_sol["kernel_states"].items( + ): + analytic_lhs_vars.add(kernel_var_name) + + # get propagator variable names + for propagator_var_name, propagator_info in analytic_sol["propagators"].items( + ): + analytic_lhs_vars.add(propagator_var_name) + + return cls.get_new_variables_after_transformation( + single_synapse_info).symmetric_difference(analytic_lhs_vars) + + @classmethod + def get_analytic_helper_variable_declarations(cls, single_synapse_info): + variable_names = cls.get_analytic_helper_variable_names( + single_synapse_info) + result = dict() + for variable_name in variable_names: + if variable_name not in cls.internal_variable_name_to_variable: + continue + variable = cls.internal_variable_name_to_variable[variable_name] + expression = cls.variables_to_internal_declarations[variable] + result[variable_name] = { + "ASTVariable": variable, + "init_expression": expression, + } + if expression.is_function_call() and expression.get_function_call( + ).callee_name == PredefinedFunctions.TIME_RESOLUTION: + result[variable_name]["is_time_resolution"] = True + else: + result[variable_name]["is_time_resolution"] = False + + return result + + def __init__(self, neuron): + super(SynsInfoEnricher, self).__init__() + + self.inside_parameter_block = False + self.inside_state_block = False + self.inside_internals_block = False + self.inside_inline_expression = False + self.inside_inline_expression = False + self.inside_declaration = False + self.inside_simple_expression = False + neuron.accept(self) + + def visit_inline_expression(self, node): + self.inside_inline_expression = True + inline_name = node.variable_name + SynsInfoEnricher.inline_name_to_transformed_inline[inline_name] = node + + def endvisit_inline_expression(self, node): + self.inside_inline_expression = False + + def visit_block_with_variables(self, node): + if node.is_state: + self.inside_state_block = True + if node.is_parameters: + self.inside_parameter_block = True + if node.is_internals: + self.inside_internals_block = True + + def endvisit_block_with_variables(self, node): + if node.is_state: + self.inside_state_block = False + if node.is_parameters: + self.inside_parameter_block = False + if node.is_internals: + self.inside_internals_block = False + + def visit_simple_expression(self, node): + self.inside_simple_expression = True + + def endvisit_simple_expression(self, node): + self.inside_simple_expression = False + + def visit_declaration(self, node): + self.declarations_ordered.append(node) + self.inside_declaration = True + if self.inside_internals_block: + variable = node.get_variables()[0] + expression = node.get_expression() + SynsInfoEnricher.variables_to_internal_declarations[variable] = expression + SynsInfoEnricher.internal_variable_name_to_variable[variable.get_name( + )] = variable + + def endvisit_declaration(self, node): + self.inside_declaration = False + + +class ASTUsedVariableNamesExtractor(ASTVisitor): + def __init__(self, node): + super(ASTUsedVariableNamesExtractor, self).__init__() + self.variable_names = set() + node.accept(self) + + def visit_variable(self, node): + self.variable_names.add(node.get_name()) diff --git a/pynestml/utils/syns_processing.py b/pynestml/utils/syns_processing.py new file mode 100644 index 000000000..a537902e5 --- /dev/null +++ b/pynestml/utils/syns_processing.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- +# +# syns_processing.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from collections import defaultdict +import copy + +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.utils.ast_synapse_information_collector import ASTSynapseInformationCollector +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages + + +class SynsProcessing(object): + padding_character = "_" + tau_sring = "tau" + equilibrium_string = "e" + + # used to keep track of whenever check_co_co was already called + # see inside check_co_co + first_time_run = defaultdict(lambda: True) + # stores syns_info from the first call of check_co_co + syns_info = defaultdict() + + def __init__(self, params): + ''' + Constructor + ''' + # @classmethod + # def extract_synapse_name(cls, name: str) -> str: + # return name + # #return name[len(cls.syns_expression_prefix):].strip(cls.padding_character) + # + + """ + returns + + { + "AMPA": + { + "inline_expression": ASTInlineExpression, + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + } + } + + }, + "GABA": + { + ... + } + ... + } + """ + @classmethod + def detectSyns(cls, neuron): + + # search for synapse_inline expressions inside equations block + # but do not traverse yet because tests run this as well + info_collector = ASTSynapseInformationCollector() + + syns_info = defaultdict() + if not FrontendConfiguration.target_is_compartmental(): + return syns_info, info_collector + + # tests will arrive here if we actually have compartmental model + neuron.accept(info_collector) + + synapse_inlines = info_collector.get_inline_expressions_with_kernels() + for synapse_inline in synapse_inlines: + + synapse_name = synapse_inline.variable_name + syns_info[synapse_name] = { + "inline_expression": synapse_inline, + "parameters_used": info_collector.get_synapse_specific_parameter_declarations(synapse_inline), + "states_used": info_collector.get_synapse_specific_state_declarations(synapse_inline), + "internals_used_declared": info_collector.get_synapse_specific_internal_declarations(synapse_inline), + "total_used_declared": info_collector.get_variable_names_of_synapse(synapse_inline), + "convolutions": {}} + + kernel_arg_pairs = info_collector.get_extracted_kernel_args( + synapse_inline) + for kernel_var, spikes_var in kernel_arg_pairs: + kernel_name = kernel_var.get_name() + spikes_name = spikes_var.get_name() + convolution_name = info_collector.construct_kernel_X_spike_buf_name( + kernel_name, spikes_name, 0) + syns_info[synapse_name]["convolutions"][convolution_name] = { + "kernel": { + "name": kernel_name, + "ASTKernel": info_collector.get_kernel_by_name(kernel_name), + }, + "spikes": { + "name": spikes_name, + "ASTInputPort": info_collector.get_input_port_by_name(spikes_name), + }, + } + + return syns_info, info_collector + + """ + input: + { + "AMPA": + { + "inline_expression": ASTInlineExpression, + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + } + } + + }, + "GABA": + { + ... + } + ... + } + + output: + { + "AMPA": + { + "inline_expression": ASTInlineExpression, + "buffers_used": {"b_spikes"}, + "parameters_used": + { + "e_AMPA": ASTDeclaration, + "tau_syn_AMPA": ASTDeclaration + }, + "states_used": + { + "v_comp": ASTDeclaration, + }, + "internals_used_declared": + { + "td": ASTDeclaration, + "g_norm_exc": ASTDeclaration, + }, + "total_used_declared": {"e_AMPA", ..., "v_comp", ..., "td", ...} + , + "convolutions": + { + "g_ex_AMPA__X__b_spikes": + { + "kernel": + { + "name": "g_ex_AMPA", + "ASTKernel": ASTKernel + }, + "spikes": + { + "name": "b_spikes", + "ASTInputPort": ASTInputPort + }, + } + } + + }, + "GABA": + { + ... + } + ... + } + """ + @classmethod + def collect_and_check_inputs_per_synapse( + cls, + neuron: ASTNeuron, + info_collector: ASTSynapseInformationCollector, + syns_info: dict): + new_syns_info = copy.copy(syns_info) + + # collect all buffers used + for synapse_name, synapse_info in syns_info.items(): + new_syns_info[synapse_name]["buffers_used"] = set() + for convolution_name, convolution_info in synapse_info["convolutions"].items( + ): + input_name = convolution_info["spikes"]["name"] + new_syns_info[synapse_name]["buffers_used"].add(input_name) + + # now make sure each synapse is using exactly one buffer + for synapse_name, synapse_info in syns_info.items(): + buffers = new_syns_info[synapse_name]["buffers_used"] + if len(buffers) != 1: + code, message = Messages.get_syns_bad_buffer_count( + buffers, synapse_name) + causing_object = synapse_info["inline_expression"] + Logger.log_message( + code=code, + message=message, + error_position=causing_object.get_source_position(), + log_level=LoggingLevel.ERROR, + node=causing_object) + + return new_syns_info + + @classmethod + def get_syns_info(cls, neuron: ASTNeuron): + """ + returns previously generated syns_info + as a deep copy so it can't be changed externally + via object references + :param neuron: a single neuron instance. + :type neuron: ASTNeuron + """ + + return copy.deepcopy(cls.syns_info[neuron]) + + @classmethod + def check_co_co(cls, neuron: ASTNeuron): + """ + Checks if synapse conditions apply for the handed over neuron. + :param neuron: a single neuron instance. + :type neuron: ASTNeuron + """ + + # make sure we only run this a single time + # subsequent calls will be after AST has been transformed + # and there would be no kernels or inlines any more + if cls.first_time_run[neuron]: + syns_info, info_collector = cls.detectSyns(neuron) + if len(syns_info) > 0: + # only do this if any synapses found + # otherwise tests may fail + syns_info = cls.collect_and_check_inputs_per_synapse( + neuron, info_collector, syns_info) + + cls.syns_info[neuron] = syns_info + cls.first_time_run[neuron] = False diff --git a/pynestml/utils/type_caster.py b/pynestml/utils/type_caster.py index 97d9703df..dc15b7a1f 100644 --- a/pynestml/utils/type_caster.py +++ b/pynestml/utils/type_caster.py @@ -25,22 +25,21 @@ from pynestml.utils.messages import Messages -class TypeCaster(object): +class TypeCaster: @staticmethod def do_magnitude_conversion_rhs_to_lhs(_rhs_type_symbol, _lhs_type_symbol, _containing_expression): """ - determine conversion factor from rhs to lhs, register it with the relevant expression, drop warning + determine conversion factor from rhs to lhs, register it with the relevant expression """ _containing_expression.set_implicit_conversion_factor( UnitTypeSymbol.get_conversion_factor(_lhs_type_symbol.astropy_unit, _rhs_type_symbol.astropy_unit)) _containing_expression.type = _lhs_type_symbol - code, message = Messages.get_implicit_magnitude_conversion(_lhs_type_symbol, _rhs_type_symbol, _containing_expression.get_implicit_conversion_factor()) Logger.log_message(code=code, message=message, error_position=_containing_expression.get_source_position(), - log_level=LoggingLevel.WARNING) + log_level=LoggingLevel.INFO) @staticmethod def try_to_recover_or_error(_lhs_type_symbol, _rhs_type_symbol, _containing_expression): diff --git a/pynestml/utils/unit_type.py b/pynestml/utils/unit_type.py index 9a65f0f16..1fef6bc6e 100644 --- a/pynestml/utils/unit_type.py +++ b/pynestml/utils/unit_type.py @@ -22,7 +22,7 @@ from astropy.units.quantity import Quantity -class UnitType(object): +class UnitType: """ This class is used to encapsulate the functionality of astropy.units in a new layer which provided additional functionality as required during context checks. diff --git a/pynestml/utils/with_options.py b/pynestml/utils/with_options.py new file mode 100644 index 000000000..96263f8f2 --- /dev/null +++ b/pynestml/utils/with_options.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# +# with_options.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Any, Mapping, Optional + +import copy + + +class WithOptions: + r"""This class allows options (indexed by strings) to be set and retrieved. A set of default options may be supplied by overriding the `_default_options` member in the inheriting class.""" + + _default_options: Mapping[str, Any] = {} + + def __init__(self, options: Optional[Mapping[str, Any]] = None): + super(WithOptions, self).__init__() + self._options = copy.deepcopy(self.__class__._default_options) + if options: + self.set_options(options) + + def get_option(self, k: str) -> Any: + r"""Get the value of a given option.""" + return self._options[k] + + def option_exists(self, k: str) -> bool: + r"""Test whether an option exists.""" + return k in self._options.keys() + + def set_options(self, options: Mapping[str, Any]) -> Mapping[str, Any]: + r"""Set options. "Eats off" any options that it knows how to set, and returns the rest as "unhandled" options.""" + unhandled_options = {} + for k in options.keys(): + if k in self.__class__._default_options: + self._options[k] = options[k] + else: + unhandled_options[k] = options[k] + return unhandled_options diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index aa7a1b2fc..ceb93fed8 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -19,14 +19,16 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import List + import ntpath import re -from pynestml.cocos.co_co_each_block_unique_and_defined import CoCoEachBlockUniqueAndDefined from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.frontend.frontend_configuration import FrontendConfiguration from pynestml.generated.PyNestMLParserVisitor import PyNestMLParserVisitor from pynestml.meta_model.ast_node_factory import ASTNodeFactory +from pynestml.meta_model.ast_parameter import ASTParameter from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger from pynestml.utils.port_signal_type import PortSignalType @@ -49,9 +51,16 @@ def visitNestMLCompilationUnit(self, ctx): neurons = list() for child in ctx.neuron(): neurons.append(self.visit(child)) + synapses = list() + for child in ctx.synapse(): + synapses.append(self.visit(child)) # extract the name of the artifact from the context - artifact_name = ntpath.basename(ctx.start.source[1].fileName) + if hasattr(ctx.start.source[1], 'fileName'): + artifact_name = ntpath.basename(ctx.start.source[1].fileName) + else: + artifact_name = 'parsed_from_string' compilation_unit = ASTNodeFactory.create_ast_nestml_compilation_unit(list_of_neurons=neurons, + list_of_synapses=synapses, source_position=create_source_pos(ctx), artifact_name=artifact_name) # first ensure certain properties of the neuron @@ -246,9 +255,17 @@ def visitLogicalOperator(self, ctx): # Visit a parse tree produced by PyNESTMLParser#variable. def visitVariable(self, ctx): + vector_parameter = None + if ctx.vectorParameter is not None: + if ctx.vectorParameter.sizeStr is not None: + vector_parameter = ctx.vectorParameter.sizeStr.text + elif ctx.vectorParameter.sizeInt is not None: + vector_parameter = ctx.vectorParameter.sizeInt.text + differential_order = (len(ctx.DIFFERENTIAL_ORDER()) if ctx.DIFFERENTIAL_ORDER() is not None else 0) return ASTNodeFactory.create_ast_variable(name=str(ctx.NAME()), differential_order=differential_order, + vector_parameter=vector_parameter, source_position=create_source_pos(ctx)) # Visit a parse tree produced by PyNESTMLParser#functionCall. @@ -293,8 +310,9 @@ def visitKernel(self, ctx): expr_node = self.visit(expr) var_nodes.append(var_node) expr_nodes.append(expr_node) - kernel = ASTNodeFactory.create_ast_kernel( - variables=var_nodes, expressions=expr_nodes, source_position=create_source_pos(ctx)) + kernel = ASTNodeFactory.create_ast_kernel(variables=var_nodes, + expressions=expr_nodes, + source_position=create_source_pos(ctx)) update_node_comments(kernel, self.__comments.visit(ctx)) return kernel @@ -350,19 +368,36 @@ def visitAssignment(self, ctx): # Visit a parse tree produced by PyNESTMLParser#declaration. def visitDeclaration(self, ctx): is_recordable = (True if ctx.isRecordable is not None else False) - is_function = (True if ctx.isFunction is not None else False) + is_inline_expression = (True if ctx.isInlineExpression is not None else False) + + decorators = [] + for kw in ctx.anyDecorator(): + decorators.append(self.visit(kw)) + variables = list() for var in ctx.variable(): variables.append(self.visit(var)) data_type = self.visit(ctx.dataType()) if ctx.dataType() is not None else None - size_param = str(ctx.sizeParameter.text) if ctx.sizeParameter is not None else None expression = self.visit(ctx.rhs) if ctx.rhs is not None else None invariant = self.visit(ctx.invariant) if ctx.invariant is not None else None - declaration = ASTNodeFactory.create_ast_declaration(is_recordable=is_recordable, is_function=is_function, - variables=variables, data_type=data_type, - size_parameter=size_param, + + # print("Visiting variable \"" + str(str(ctx.NAME())) + "\"...") + # # check if this variable was decorated as homogeneous + # import pynestml.generated.PyNestMLLexer + # is_homogeneous = any([isinstance(ch, pynestml.generated.PyNestMLParser.PyNestMLParser.AnyDecoratorContext) \ + # and len(ch.getTokens(pynestml.generated.PyNestMLLexer.PyNestMLLexer.DECORATOR_HOMOGENEOUS)) > 0 \ + # for ch in ctx.parentCtx.children]) + # if is_homogeneous: + # print("\t----> is homogeneous") + + declaration = ASTNodeFactory.create_ast_declaration(is_recordable=is_recordable, + variables=variables, + data_type=data_type, expression=expression, - invariant=invariant, source_position=create_source_pos(ctx)) + is_inline_expression=is_inline_expression, + invariant=invariant, + source_position=create_source_pos(ctx), + decorators=decorators) update_node_comments(declaration, self.__comments.visit(ctx)) return declaration @@ -379,8 +414,9 @@ def visitIfStmt(self, ctx): for clause in ctx.elifClause(): elif_clauses.append(self.visit(clause)) else_clause = self.visit(ctx.elseClause()) if ctx.elseClause() is not None else None - return ASTNodeFactory.create_ast_if_stmt(if_clause=if_clause, elif_clauses=elif_clauses, - else_clause=else_clause, source_position=create_source_pos(ctx)) + ret = ASTNodeFactory.create_ast_if_stmt(if_clause=if_clause, elif_clauses=elif_clauses, + else_clause=else_clause, source_position=create_source_pos(ctx)) + return ret # Visit a parse tree produced by PyNESTMLParser#ifClause. def visitIfClause(self, ctx): @@ -436,7 +472,7 @@ def visitWhileStmt(self, ctx): # Visit a parse tree produced by PyNESTMLParser#neuron. def visitNeuron(self, ctx): name = str(ctx.NAME()) if ctx.NAME() is not None else None - body = self.visit(ctx.body()) if ctx.body() is not None else None + body = self.visit(ctx.neuronBody()) if ctx.neuronBody() is not None else None # after we have constructed the meta_model of the neuron, # we can ensure some basic properties which should always hold # we have to check if each type of block is defined at most once (except for function), and that input,output @@ -451,13 +487,54 @@ def visitNeuron(self, ctx): update_node_comments(neuron, self.__comments.visit(ctx)) # in order to enable the logger to print correct messages set as the source the corresponding neuron Logger.set_current_node(neuron) - CoCoEachBlockUniqueAndDefined.check_co_co(node=neuron) - Logger.set_current_node(neuron) - # now the meta_model seems to be correct, return it + return neuron - # Visit a parse tree produced by PyNESTMLParser#body. - def visitBody(self, ctx): + def visitNamespaceDecoratorNamespace(self, ctx): + return ctx.NAME() + + def visitNamespaceDecoratorName(self, ctx): + return ctx.NAME() + + def visitAnyDecorator(self, ctx): + from pynestml.generated.PyNestMLLexer import PyNestMLLexer + if ctx.getToken(PyNestMLLexer.DECORATOR_HETEROGENEOUS, 0) is not None: + return PyNestMLLexer.DECORATOR_HETEROGENEOUS + elif ctx.getToken(PyNestMLLexer.DECORATOR_HOMOGENEOUS, 0) is not None: + return PyNestMLLexer.DECORATOR_HOMOGENEOUS + elif ctx.getToken(PyNestMLLexer.AT, 0) is not None: + namespaceDecoratorNamespace = self.visit(ctx.namespaceDecoratorNamespace()) if ctx.namespaceDecoratorNamespace() is not None else None + namespaceDecoratorName = self.visit(ctx.namespaceDecoratorName()) if ctx.namespaceDecoratorName() is not None else None + return ASTNodeFactory.create_ast_namespace_decorator(namespaceDecoratorNamespace, namespaceDecoratorName, source_position=create_source_pos(ctx)) + else: + return None + + # Visit a parse tree produced by PyNESTMLParser#neuron. + def visitSynapse(self, ctx): + name = str(ctx.NAME()) if ctx.NAME() is not None else None + body = self.visit(ctx.synapseBody()) if ctx.synapseBody() is not None else None + + # after we have constructed the meta_model of the neuron, + # we can ensure some basic properties which should always hold + # we have to check if each type of block is defined at most once (except for function), and that input,output + # and update are defined once + if hasattr(ctx.start.source[1], 'fileName'): + artifact_name = ntpath.basename(ctx.start.source[1].fileName) + else: + artifact_name = 'parsed from string' + synapse = ASTNodeFactory.create_ast_synapse(name=name + FrontendConfiguration.suffix, body=body, source_position=create_source_pos(ctx), + artifact_name=artifact_name) + + # update the comments + update_node_comments(synapse, self.__comments.visit(ctx)) + + # in order to enable the logger to print correct messages set as the source the corresponding synapse + Logger.set_current_node(synapse) + + return synapse + + # Visit a parse tree produced by PyNESTMLParser#neuronBody. + def visitNeuronBody(self, ctx): """ Here, in order to ensure that the correct order of elements is kept, we use a method which inspects a list of elements and returns the one with the smallest source line. @@ -487,7 +564,43 @@ def visitBody(self, ctx): elem = get_next(body_elements) elements.append(self.visit(elem)) body_elements.remove(elem) - body = ASTNodeFactory.create_ast_body(elements, create_source_pos(ctx)) + body = ASTNodeFactory.create_ast_neuron_or_synapse_body(elements, create_source_pos(ctx)) + return body + + # Visit a parse tree produced by PyNESTMLParser#synapseBody. + def visitSynapseBody(self, ctx): + """ + Here, in order to ensure that the correct order of elements is kept, we use a method which inspects + a list of elements and returns the one with the smallest source line. + """ + body_elements = list() + if ctx.onReceiveBlock() is not None: + for child in ctx.onReceiveBlock(): + body_elements.append(child) + if ctx.blockWithVariables() is not None: + for child in ctx.blockWithVariables(): + body_elements.append(child) + if ctx.updateBlock() is not None: + for child in ctx.updateBlock(): + body_elements.append(child) + if ctx.equationsBlock() is not None: + for child in ctx.equationsBlock(): + body_elements.append(child) + if ctx.inputBlock() is not None: + for child in ctx.inputBlock(): + body_elements.append(child) + if ctx.outputBlock() is not None: + for child in ctx.outputBlock(): + body_elements.append(child) + if ctx.function() is not None: + for child in ctx.function(): + body_elements.append(child) + elements = list() + while len(body_elements) > 0: + elem = get_next(body_elements) + elements.append(self.visit(elem)) + body_elements.remove(elem) + body = ASTNodeFactory.create_ast_neuron_or_synapse_body(elements, create_source_pos(ctx)) return body # Visit a parse tree produced by PyNESTMLParser#blockWithVariables. @@ -499,13 +612,11 @@ def visitBlockWithVariables(self, ctx): block_type = ctx.blockType.text # the text field stores the exact name of the token, e.g., state source_pos = create_source_pos(ctx) if block_type == 'state': - ret = ASTNodeFactory.create_ast_block_with_variables(True, False, False, False, declarations, source_pos) + ret = ASTNodeFactory.create_ast_block_with_variables(True, False, False, declarations, source_pos) elif block_type == 'parameters': - ret = ASTNodeFactory.create_ast_block_with_variables(False, True, False, False, declarations, source_pos) + ret = ASTNodeFactory.create_ast_block_with_variables(False, True, False, declarations, source_pos) elif block_type == 'internals': - ret = ASTNodeFactory.create_ast_block_with_variables(False, False, True, False, declarations, source_pos) - elif block_type == 'initial_values': - ret = ASTNodeFactory.create_ast_block_with_variables(False, False, False, True, declarations, source_pos) + ret = ASTNodeFactory.create_ast_block_with_variables(False, False, True, declarations, source_pos) else: raise RuntimeError('(PyNestML.ASTBuilder) Unspecified type (=%s) of var-block.' % str(ctx.blockType)) update_node_comments(ret, self.__comments.visit(ctx)) @@ -559,8 +670,8 @@ def visitInputPort(self, ctx): for qual in ctx.inputQualifier(): input_qualifiers.append(self.visit(qual)) data_type = self.visit(ctx.dataType()) if ctx.dataType() is not None else None - if ctx.isCurrent: - signal_type = PortSignalType.CURRENT + if ctx.isContinuous: + signal_type = PortSignalType.CONTINUOUS elif ctx.isSpike: signal_type = PortSignalType.SPIKE else: @@ -585,17 +696,18 @@ def visitOutputBlock(self, ctx): ret = ASTNodeFactory.create_ast_output_block(s_type=PortSignalType.SPIKE, source_position=source_pos) update_node_comments(ret, self.__comments.visit(ctx)) return ret - elif ctx.isCurrent is not None: - ret = ASTNodeFactory.create_ast_output_block(s_type=PortSignalType.CURRENT, source_position=source_pos) + + if ctx.isContinuous is not None: + ret = ASTNodeFactory.create_ast_output_block(s_type=PortSignalType.CONTINUOUS, source_position=source_pos) update_node_comments(ret, self.__comments.visit(ctx)) return ret - else: - raise RuntimeError('(PyNestML.ASTBuilder) Type of output buffer not recognized.') + + raise RuntimeError('(PyNestML.ASTBuilder) Type of output buffer not recognized.') # Visit a parse tree produced by PyNESTMLParser#function. def visitFunction(self, ctx): name = str(ctx.NAME()) if ctx.NAME() is not None else None - parameters = list() + parameters: List[ASTParameter] = [] if type(ctx.parameter()) is list: for par in ctx.parameter(): parameters.append(self.visit(par)) @@ -621,6 +733,16 @@ def visitStmt(self, ctx): compound = self.visit(ctx.compoundStmt()) if ctx.compoundStmt() is not None else None return ASTNodeFactory.create_ast_stmt(small, compound, create_source_pos(ctx)) + def visitOnReceiveBlock(self, ctx): + block = self.visit(ctx.block()) if ctx.block() is not None else None + port_name = ctx.inputPortName.text + const_parameters = {} + for el in ctx.constParameter(): + const_parameters[el.name.text] = el.value.text + ret = ASTNodeFactory.create_ast_on_receive_block(block=block, port_name=port_name, const_parameters=const_parameters, source_position=create_source_pos(ctx)) + update_node_comments(ret, self.__comments.visit(ctx)) + return ret + def update_node_comments(node, comments): node.comment = comments[0] diff --git a/pynestml/visitors/ast_equations_with_delay_vars_visitor.py b/pynestml/visitors/ast_equations_with_delay_vars_visitor.py new file mode 100644 index 000000000..98313e100 --- /dev/null +++ b/pynestml/visitors/ast_equations_with_delay_vars_visitor.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# ast_equations_with_delay_vars_visitor.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.meta_model.ast_node_factory import ASTNodeFactory +from pynestml.meta_model.ast_ode_equation import ASTOdeEquation +from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import Messages +from pynestml.visitors.ast_visitor import ASTVisitor + + +class ASTEquationsWithDelayVarsVisitor(ASTVisitor): + """ + A visitor that converts the delay variables parsed as function calls to ASTVariable and collects all the + equations that have these delay variables. + """ + def __init__(self): + super(ASTEquationsWithDelayVarsVisitor, self).__init__() + self.equations = list() + self.has_delay = False + + def visit_simple_expression(self, node: ASTSimpleExpression): + if node.is_function_call() and ASTUtils.is_function_delay_variable(node.get_function_call()): + # Create a new ASTVariable + ast_variable = ASTNodeFactory.create_ast_variable(node.get_function_call().get_name(), + source_position=node.get_source_position()) + # Get the delay parameter + delay_parameter = ASTUtils.extract_delay_parameter(node.get_function_call()) + ast_variable.set_delay_parameter(delay_parameter) + + # Set the variable in the SimpleExpression node + node.set_variable(ast_variable) + + # Set the delay parameter in its corresponding variable symbol + delay_var_symbol = ASTUtils.get_delay_variable_symbol(node.get_function_call()) + if delay_var_symbol is None: + code, message = Messages.get_no_variable_found(node.get_function_call().get_name()) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR) + return + + delay_var_symbol.set_delay_parameter(delay_parameter) + + # Update scope + node.get_scope().update_variable_symbol(delay_var_symbol) + + # Nullify the function call + node.set_function_call(None) + + self.has_delay = True + + def endvisit_ode_equation(self, node: ASTOdeEquation): + if self.has_delay: + self.equations.append(node) + self.has_delay = False diff --git a/pynestml/visitors/ast_function_call_visitor.py b/pynestml/visitors/ast_function_call_visitor.py index 78af2d85b..667fc11a5 100644 --- a/pynestml/visitors/ast_function_call_visitor.py +++ b/pynestml/visitors/ast_function_call_visitor.py @@ -21,12 +21,16 @@ """ simpleExpression : functionCall """ +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_node_factory import ASTNodeFactory from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.symbols.error_type_symbol import ErrorTypeSymbol from pynestml.symbols.template_type_symbol import TemplateTypeSymbol from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.variable_symbol import BlockType from pynestml.symbols.void_type_symbol import VoidTypeSymbol +from pynestml.utils.ast_utils import ASTUtils from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages from pynestml.visitors.ast_visitor import ASTVisitor @@ -37,10 +41,11 @@ class ASTFunctionCallVisitor(ASTVisitor): Visits a single function call and updates its type. """ - def visit_simple_expression(self, node): + def visit_simple_expression(self, node: ASTSimpleExpression) -> None: """ Visits a single function call as stored in a simple expression and derives the correct type of all its - parameters. :param node: a simple expression :type node: ASTSimpleExpression :rtype void + parameters. + :param node: a simple expression """ assert isinstance(node, ASTSimpleExpression), \ '(PyNestML.Visitor.FunctionCallVisitor) No or wrong type of simple expression provided (%s)!' % tuple(node) @@ -49,6 +54,16 @@ def visit_simple_expression(self, node): scope = node.get_scope() function_name = node.get_function_call().get_name() method_symbol = scope.resolve_to_symbol(function_name, SymbolKind.FUNCTION) + + # check if this is a delay variable + symbol = ASTUtils.get_delay_variable_symbol(node.get_function_call()) + if method_symbol is None and symbol is not None: + code, message = Messages.get_function_is_delay_variable(function_name) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.DEBUG) + node.type = symbol.get_type_symbol() + return + # check if this function exists if method_symbol is None: code, message = Messages.get_could_not_resolve(function_name) @@ -66,10 +81,11 @@ def visit_simple_expression(self, node): if isinstance(return_type, TemplateTypeSymbol): # error: return type template not found among parameter type templates - assert(False) + assert False, "return type template not found among parameter type templates" # check for consistency among actual derived types for template parameters - from pynestml.cocos.co_co_function_argument_template_types_consistent import CorrectTemplatedArgumentTypesVisitor + from pynestml.cocos.co_co_function_argument_template_types_consistent import \ + CorrectTemplatedArgumentTypesVisitor correctTemplatedArgumentTypesVisitor = CorrectTemplatedArgumentTypesVisitor() correctTemplatedArgumentTypesVisitor._failure_occurred = False node.accept(correctTemplatedArgumentTypesVisitor) diff --git a/pynestml/visitors/ast_mark_delay_vars_visitor.py b/pynestml/visitors/ast_mark_delay_vars_visitor.py new file mode 100644 index 000000000..b327f9a8c --- /dev/null +++ b/pynestml/visitors/ast_mark_delay_vars_visitor.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# +# ast_mark_delay_vars_visitor.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression +from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.symbol import SymbolKind +from pynestml.visitors.ast_visitor import ASTVisitor + + +class ASTMarkDelayVarsVisitor(ASTVisitor): + """ + A visitor that marks has_delay value in ASTExpression and ASTSimpleExpression nodes to True + """ + def __init__(self): + super(ASTMarkDelayVarsVisitor, self).__init__() + + def visit_expression(self, node: ASTExpression): + node.has_delay = True + + def visit_simple_expression(self, node: ASTSimpleExpression): + node.has_delay = True + + def visit_variable(self, node: ASTVariable): + delay_var_symbol = node.get_scope().resolve_to_symbol(node.get_complete_name(), SymbolKind.VARIABLE) + if delay_var_symbol is not None: + delay_parameter = delay_var_symbol.get_delay_parameter() + if delay_parameter is not None: + node.set_delay_parameter(delay_parameter) diff --git a/pynestml/visitors/ast_symbol_table_visitor.py b/pynestml/visitors/ast_symbol_table_visitor.py index effb0b322..382f19b4b 100644 --- a/pynestml/visitors/ast_symbol_table_visitor.py +++ b/pynestml/visitors/ast_symbol_table_visitor.py @@ -18,8 +18,12 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from pynestml.cocos.co_cos_manager import CoCosManager +from pynestml.meta_model.ast_namespace_decorator import ASTNamespaceDecorator +from pynestml.meta_model.ast_declaration import ASTDeclaration from pynestml.meta_model.ast_node_factory import ASTNodeFactory +from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.symbol_table.scope import Scope, ScopeType from pynestml.symbols.function_symbol import FunctionSymbol @@ -28,6 +32,7 @@ from pynestml.symbols.predefined_variables import PredefinedVariables from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.variable_symbol import VariableSymbol, BlockType, VariableType +from pynestml.utils.ast_utils import ASTUtils from pynestml.utils.either import Either from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages @@ -58,8 +63,9 @@ def visit_neuron(self, node): Logger.set_current_node(node) code, message = Messages.get_start_building_symbol_table() Logger.log_message(node=node, code=code, error_position=node.get_source_position(), - message=message, log_level=LoggingLevel.INFO) - scope = Scope(scope_type=ScopeType.GLOBAL, source_position=node.get_source_position()) + message=message, log_level=LoggingLevel.DEBUG) + scope = Scope(scope_type=ScopeType.GLOBAL, + source_position=node.get_source_position()) node.update_scope(scope) node.get_body().update_scope(scope) # now first, we add all predefined elements to the scope @@ -75,29 +81,17 @@ def visit_neuron(self, node): def endvisit_neuron(self, node): # before following checks occur, we need to ensure several simple properties - CoCosManager.post_symbol_table_builder_checks(node, after_ast_rewrite=self.after_ast_rewrite_) - # the following part is done in order to mark conductance based buffers as such. - if node.get_input_blocks() is not None and node.get_equations_blocks() is not None and \ - len(node.get_equations_blocks().get_declarations()) > 0: - # this case should be prevented, since several input blocks result in a incorrect model - if isinstance(node.get_input_blocks(), list): - buffers = (buffer for bufferA in node.get_input_blocks() for buffer in bufferA.get_input_ports()) - else: - buffers = (buffer for buffer in node.get_input_blocks().get_input_ports()) - from pynestml.meta_model.ast_kernel import ASTKernel - # todo: ode declarations are not used, is this correct? - # ode_declarations = (decl for decl in node.get_equations_blocks().get_declarations() if - # not isinstance(decl, ASTKernel)) - # now update the equations + CoCosManager.post_symbol_table_builder_checks( + node, after_ast_rewrite=self.after_ast_rewrite_) + + # update the equations if node.get_equations_blocks() is not None and len(node.get_equations_blocks().get_declarations()) > 0: equation_block = node.get_equations_blocks() - assign_ode_to_variables(equation_block) - if not self.after_ast_rewrite_: - CoCosManager.post_ode_specification_checks(node) + ASTUtils.assign_ode_to_variables(equation_block) + Logger.set_current_node(None) - return - def visit_body(self, node): + def visit_neuron_or_synapse_body(self, node): """ Private method: Used to visit a single neuron body and create the corresponding scope. :param node: a single body element. @@ -105,6 +99,53 @@ def visit_body(self, node): """ for bodyElement in node.get_body_elements(): bodyElement.update_scope(node.get_scope()) + + def visit_synapse(self, node): + """ + Private method: Used to visit a single synapse and create the corresponding global as well as local scopes. + :return: a single synapse. + :rtype: ast_synapse + """ + # set current processed synapse + # Logger.set_current_synapse(node) + Logger.set_current_node(node) + code, message = Messages.get_start_building_symbol_table() + Logger.log_message(node=node, code=code, error_position=node.get_source_position(), + message=message, log_level=LoggingLevel.DEBUG) + # before starting the work on the synapse, make everything which was implicit explicit + # but if we have a model without an equations block, just skip this step + scope = Scope(scope_type=ScopeType.GLOBAL, + source_position=node.get_source_position()) + + node.update_scope(scope) + node.get_body().update_scope(scope) + # now first, we add all predefined elements to the scope + variables = PredefinedVariables.get_variables() + functions = PredefinedFunctions.get_function_symbols() + types = PredefinedTypes.get_types() + for symbol in variables.keys(): + node.get_scope().add_symbol(variables[symbol]) + for symbol in functions.keys(): + node.get_scope().add_symbol(functions[symbol]) + for symbol in types.keys(): + node.get_scope().add_symbol(types[symbol]) + + def endvisit_synapse(self, node): + # before following checks occur, we need to ensure several simple properties + CoCosManager.post_symbol_table_builder_checks(node) + Logger.set_current_node(None) + + def endvisit_synapse_body(self, node): + return + + def visit_synapse_body(self, node): + """ + Private method: Used to visit a single synapse body and create the corresponding scope. + :param node: a single body element. + :type node: ast_body + """ + for synapseBodyElement in node.get_body_elements(): + synapseBodyElement.update_scope(node.get_scope()) return def visit_function(self, node): @@ -113,7 +154,8 @@ def visit_function(self, node): :param node: a function block object. :type node: ast_function """ - self.block_type_stack.push(BlockType.LOCAL) # before entering, update the current node type + self.block_type_stack.push( + BlockType.LOCAL) # before entering, update the current node type symbol = FunctionSymbol(scope=node.get_scope(), element_reference=node, param_types=list(), name=node.get_name(), is_predefined=False, return_type=None) # put it on the stack for the endvisit method @@ -150,16 +192,18 @@ def endvisit_function(self, node): arg.update_scope(scope) # create the corresponding variable symbol representing the parameter var_symbol = VariableSymbol(element_reference=arg, scope=scope, name=arg.get_name(), - block_type=BlockType.LOCAL, is_predefined=False, is_function=False, + block_type=BlockType.LOCAL, is_predefined=False, is_inline_expression=False, is_recordable=False, - type_symbol=PredefinedTypes.get_type(type_name), + type_symbol=PredefinedTypes.get_type( + type_name), variable_type=VariableType.VARIABLE) assert isinstance(scope, Scope) scope.add_symbol(var_symbol) if node.has_return_type(): data_type_visitor = ASTDataTypeVisitor() node.get_return_type().accept(data_type_visitor) - symbol.set_return_type(PredefinedTypes.get_type(data_type_visitor.result)) + symbol.set_return_type( + PredefinedTypes.get_type(data_type_visitor.result)) else: symbol.set_return_type(PredefinedTypes.get_void_type()) self.block_type_stack.pop() # before leaving update the type @@ -182,6 +226,21 @@ def endvisit_update_block(self, node=None): self.block_type_stack.pop() return + def visit_on_receive_block(self, node): + """ + Private method: Used to visit a single onReceive block and create the corresponding scope. + :param node: an onReceive block object. + :type node: ASTOnReceiveBlock + """ + self.block_type_stack.push(BlockType.LOCAL) + scope = Scope(scope_type=ScopeType.ON_RECEIVE, enclosing_scope=node.get_scope(), + source_position=node.get_source_position()) + node.get_scope().add_scope(scope) + node.get_block().update_scope(scope) + + def endvisit_on_receive_block(self, node=None): + self.block_type_stack.pop() + def visit_block(self, node): """ Private method: Used to visit a single block of statements, create and update the corresponding scope. @@ -246,14 +305,11 @@ def visit_function_call(self, node): arg.update_scope(node.get_scope()) return - def visit_declaration(self, node): + def visit_declaration(self, node: ASTDeclaration) -> None: """ - Private method: Used to visit a single declaration, update its scope and return the corresponding set of - symbols - :param node: a declaration object. - :type node: ast_declaration - :return: the scope is update without a return value. - :rtype: void + Private method: Used to visit a single declaration, update its scope and return the corresponding set of symbols + :param node: a declaration AST node + :return: the scope is updated without a return value. """ expression = node.get_expression() if node.has_expression() else None visitor = ASTDataTypeVisitor() @@ -261,25 +317,42 @@ def visit_declaration(self, node): type_name = visitor.result # all declarations in the state block are recordable is_recordable = (node.is_recordable - or self.block_type_stack.top() == BlockType.STATE - or self.block_type_stack.top() == BlockType.INITIAL_VALUES) - init_value = node.get_expression() if self.block_type_stack.top() == BlockType.INITIAL_VALUES else None - vector_parameter = node.get_size_parameter() + or self.block_type_stack.top() == BlockType.STATE) + init_value = node.get_expression( + ) if self.block_type_stack.top() == BlockType.STATE else None + + # split the decorators in the AST up into namespace decorators and other decorators + decorators = [] + namespace_decorators = {} + for d in node.get_decorators(): + if isinstance(d, ASTNamespaceDecorator): + namespace_decorators[str(d.get_namespace())] = str( + d.get_name()) + else: + decorators.append(d) + # now for each variable create a symbol and update the scope + block_type = None + if not self.block_type_stack.is_empty(): + block_type = self.block_type_stack.top() for var in node.get_variables(): # for all variables declared create a new symbol var.update_scope(node.get_scope()) type_symbol = PredefinedTypes.get_type(type_name) + vector_parameter = var.get_vector_parameter() symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=var.get_complete_name(), - block_type=self.block_type_stack.top(), - declaring_expression=expression, is_predefined=False, - is_function=node.is_function, + block_type=block_type, + declaring_expression=expression, + is_predefined=False, + is_inline_expression=False, is_recordable=is_recordable, type_symbol=type_symbol, initial_value=init_value, vector_parameter=vector_parameter, - variable_type=VariableType.VARIABLE + variable_type=VariableType.VARIABLE, + decorators=decorators, + namespace_decorators=namespace_decorators ) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) @@ -292,7 +365,6 @@ def visit_declaration(self, node): # the invariant update if node.has_invariant(): node.get_invariant().update_scope(node.get_scope()) - return def visit_return_stmt(self, node): """ @@ -302,7 +374,6 @@ def visit_return_stmt(self, node): """ if node.has_expression(): node.get_expression().update_scope(node.get_scope()) - return def visit_if_stmt(self, node): """ @@ -315,7 +386,6 @@ def visit_if_stmt(self, node): elIf.update_scope(node.get_scope()) if node.has_else_clause(): node.get_else_clause().update_scope(node.get_scope()) - return def visit_if_clause(self, node): """ @@ -387,7 +457,6 @@ def visit_unit_type(self, node): if isinstance(node.lhs, ASTUnitType): # lhs can be a numeric Or a unit-type node.lhs.update_scope(node.get_scope()) node.get_rhs().update_scope(node.get_scope()) - return def visit_expression(self, node): """ @@ -413,7 +482,6 @@ def visit_expression(self, node): node.get_condition().update_scope(node.get_scope()) node.get_if_true().update_scope(node.get_scope()) node.get_if_not().update_scope(node.get_scope()) - return def visit_simple_expression(self, node): """ @@ -425,7 +493,6 @@ def visit_simple_expression(self, node): node.get_function_call().update_scope(node.get_scope()) elif node.is_variable() or node.has_unit(): node.get_variable().update_scope(node.get_scope()) - return def visit_inline_expression(self, node): """ @@ -441,7 +508,8 @@ def visit_inline_expression(self, node): name=node.get_variable_name(), block_type=BlockType.EQUATION, declaring_expression=node.get_expression(), - is_predefined=False, is_function=True, + is_predefined=False, + is_inline_expression=True, is_recordable=node.is_recordable, type_symbol=type_symbol, variable_type=VariableType.VARIABLE) @@ -465,7 +533,7 @@ def visit_kernel(self, node): block_type=BlockType.EQUATION, declaring_expression=expr, is_predefined=False, - is_function=False, + is_inline_expression=False, is_recordable=True, type_symbol=PredefinedTypes.get_real_type(), variable_type=VariableType.KERNEL) @@ -492,15 +560,12 @@ def visit_block_with_variables(self, node): self.block_type_stack.push( BlockType.STATE if node.is_state else BlockType.INTERNALS if node.is_internals else - BlockType.PARAMETERS if node.is_parameters else - BlockType.INITIAL_VALUES) + BlockType.PARAMETERS) for decl in node.get_declarations(): decl.update_scope(node.get_scope()) - return def endvisit_block_with_variables(self, node): self.block_type_stack.pop() - return def visit_equations_block(self, node): """ @@ -527,9 +592,10 @@ def visit_input_port(self, node): :type node: ASTInputPort """ if not node.has_datatype(): - code, message = Messages.get_buffer_type_not_defined(node.get_name()) + code, message = Messages.get_input_port_type_not_defined( + node.get_name()) Logger.log_message(code=code, message=message, error_position=node.get_source_position(), - log_level=LoggingLevel.ERROR) + log_level=LoggingLevel.ERROR, node=node) else: node.get_datatype().update_scope(node.get_scope()) @@ -537,93 +603,23 @@ def visit_input_port(self, node): qual.update_scope(node.get_scope()) def endvisit_input_port(self, node): - buffer_type = BlockType.INPUT_BUFFER_SPIKE if node.is_spike() else BlockType.INPUT_BUFFER_CURRENT if not node.has_datatype(): return type_symbol = node.get_datatype().get_type_symbol() type_symbol.is_buffer = True # set it as a buffer symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=node.get_name(), - block_type=buffer_type, vector_parameter=node.get_index_parameter(), - is_predefined=False, is_function=False, is_recordable=False, + block_type=BlockType.INPUT, vector_parameter=node.get_index_parameter(), + is_predefined=False, is_inline_expression=False, is_recordable=False, type_symbol=type_symbol, variable_type=VariableType.BUFFER) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) - def visit_stmt(self, node): + def visit_stmt(self, node: ASTStmt): """ Private method: Used to visit a single stmt and update its scope. :param node: a single statement - :type node: ast_stmt """ if node.is_small_stmt(): node.small_stmt.update_scope(node.get_scope()) if node.is_compound_stmt(): node.compound_stmt.update_scope(node.get_scope()) - - -def assign_ode_to_variables(ode_block): - """ - Adds for each variable symbol the corresponding ode declaration if present. - :param ode_block: a single block of ode declarations. - :type ode_block: ASTEquations - """ - from pynestml.meta_model.ast_ode_equation import ASTOdeEquation - from pynestml.meta_model.ast_kernel import ASTKernel - for decl in ode_block.get_declarations(): - if isinstance(decl, ASTOdeEquation): - add_ode_to_variable(decl) - elif isinstance(decl, ASTKernel): - add_kernel_to_variable(decl) - - -def add_ode_to_variable(ode_equation): - """ - Resolves to the corresponding symbol and updates the corresponding ode-declaration. - :param ode_equation: a single ode-equation - :type ode_equation: ast_ode_equation - """ - for diff_order in range(ode_equation.get_lhs().get_differential_order()): - var_name = ode_equation.get_lhs().get_name() + "'" * diff_order - existing_symbol = ode_equation.get_scope().resolve_to_symbol(var_name, SymbolKind.VARIABLE) - - if existing_symbol is None: - code, message = Messages.get_no_variable_found(ode_equation.get_lhs().get_name_of_lhs()) - Logger.log_message(code=code, message=message, error_position=ode_equation.get_source_position(), - log_level=LoggingLevel.ERROR) - return - - existing_symbol.set_ode_or_kernel(ode_equation) - - ode_equation.get_scope().update_variable_symbol(existing_symbol) - code, message = Messages.get_ode_updated(ode_equation.get_lhs().get_name_of_lhs()) - Logger.log_message(error_position=existing_symbol.get_referenced_object().get_source_position(), - code=code, message=message, log_level=LoggingLevel.INFO) - - -def add_kernel_to_variable(kernel): - """ - Adds the kernel as the defining equation. - - If the definition of the kernel is e.g. `g'' = ...` then variable symbols `g` and `g'` will have their kernel definition and variable type set. - - :param kernel: a single kernel object. - :type kernel: ASTKernel - """ - if len(kernel.get_variables()) == 1 \ - and kernel.get_variables()[0].get_differential_order() == 0: - # we only update those which define an ODE; skip "direct function of time" specifications - return - - for var, expr in zip(kernel.get_variables(), kernel.get_expressions()): - for diff_order in range(var.get_differential_order()): - var_name = var.get_name() + "'" * diff_order - existing_symbol = kernel.get_scope().resolve_to_symbol(var_name, SymbolKind.VARIABLE) - - if existing_symbol is None: - code, message = Messages.get_no_variable_found(var.get_name_of_lhs()) - Logger.log_message(code=code, message=message, error_position=kernel.get_source_position(), log_level=LoggingLevel.ERROR) - return - - existing_symbol.set_ode_or_kernel(expr) - existing_symbol.set_variable_type(VariableType.KERNEL) - kernel.get_scope().update_variable_symbol(existing_symbol) diff --git a/pynestml/visitors/ast_variable_visitor.py b/pynestml/visitors/ast_variable_visitor.py index b03fb8a86..07860acd7 100644 --- a/pynestml/visitors/ast_variable_visitor.py +++ b/pynestml/visitors/ast_variable_visitor.py @@ -19,9 +19,6 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -""" -simpleExpression : variable -""" from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.symbols.error_type_symbol import ErrorTypeSymbol from pynestml.symbols.symbol import SymbolKind @@ -48,25 +45,26 @@ def visit_simple_expression(self, node): scope = node.get_scope() var_name = node.get_variable().get_complete_name() - var_resolve = scope.resolve_to_symbol(var_name, SymbolKind.VARIABLE) + var_resolve = node.get_variable().get_scope().resolve_to_symbol(var_name, SymbolKind.VARIABLE) # update the type of the variable according to its symbol type. if var_resolve is not None: node.type = var_resolve.get_type_symbol() node.type.referenced_object = node - else: - # check if var_name is actually a type literal (e.g. "mV") - var_resolve = scope.resolve_to_symbol(var_name, SymbolKind.TYPE) - if var_resolve is not None: - node.type = var_resolve - node.type.referenced_object = node - else: - message = 'Variable ' + str(node) + ' could not be resolved!' - Logger.log_message(code=MessageCode.SYMBOL_NOT_RESOLVED, - error_position=node.get_source_position(), - message=message, log_level=LoggingLevel.ERROR) - node.type = ErrorTypeSymbol() - return + return + + # check if var_name is actually a type literal (e.g. "mV") + var_resolve = scope.resolve_to_symbol(var_name, SymbolKind.TYPE) + if var_resolve is not None: + node.type = var_resolve + node.type.referenced_object = node + return + + message = 'Variable ' + str(node) + ' could not be resolved!' + Logger.log_message(code=MessageCode.SYMBOL_NOT_RESOLVED, + error_position=node.get_source_position(), + message=message, log_level=LoggingLevel.ERROR) + node.type = ErrorTypeSymbol() def visit_expression(self, node): raise Exception("Deprecated method used!") diff --git a/pynestml/visitors/ast_visitor.py b/pynestml/visitors/ast_visitor.py index f20452d63..783ecb846 100644 --- a/pynestml/visitors/ast_visitor.py +++ b/pynestml/visitors/ast_visitor.py @@ -24,7 +24,6 @@ from pynestml.meta_model.ast_bit_operator import ASTBitOperator from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables -from pynestml.meta_model.ast_body import ASTBody from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_data_type import ASTDataType @@ -44,15 +43,18 @@ from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.meta_model.ast_neuron_or_synapse_body import ASTNeuronOrSynapseBody from pynestml.meta_model.ast_ode_equation import ASTOdeEquation from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_kernel import ASTKernel +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock from pynestml.meta_model.ast_output_block import ASTOutputBlock from pynestml.meta_model.ast_parameter import ASTParameter from pynestml.meta_model.ast_return_stmt import ASTReturnStmt from pynestml.meta_model.ast_simple_expression import ASTSimpleExpression from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt +from pynestml.meta_model.ast_synapse import ASTSynapse from pynestml.meta_model.ast_unary_operator import ASTUnaryOperator from pynestml.meta_model.ast_unit_type import ASTUnitType from pynestml.meta_model.ast_update_block import ASTUpdateBlock @@ -60,7 +62,7 @@ from pynestml.meta_model.ast_while_stmt import ASTWhileStmt -class ASTVisitor(object): +class ASTVisitor: """ This class represents a standard implementation of a visitor as used to create concrete instances. Attributes: @@ -90,11 +92,19 @@ def visit_neuron(self, node): """ return - def visit_body(self, node): + def visit_synapse(self, node): + """ + Used to visit a single synapse. + :return: a single synapse. + :rtype: ASTSynapse + """ + return + + def visit_neuron_or_synapse_body(self, node): """ Used to visit a single neuron body. :param node: a single body element. - :type node: ASTBody + :type node: ASTNeuronOrSynapseBody """ return @@ -114,6 +124,13 @@ def visit_update_block(self, node): """ return + def visit_on_receive_block(self, node): + """ + Used to visit a single onReceive block. + :type node: ASTOnReceiveBlock + """ + return + def visit_block(self, node): """ Used to visit a single block of statements. @@ -397,11 +414,19 @@ def endvisit_neuron(self, node): """ return - def endvisit_body(self, node): + def endvisit_synapse(self, node): + """ + Used to endvisit a single synapse. + :return: a single synapse. + :rtype: ASTSynapse + """ + return + + def endvisit_neuron_or_synapse_body(self, node): """ Used to endvisit a single neuron body. :param node: a single body element. - :type node: ASTBody + :type node: ASTNeuronOrSynapseBody """ return @@ -421,6 +446,12 @@ def endvisit_update_block(self, node): """ return + def endvisit_on_receive_block(self, node): + """ + Used to endvisit a onReceive block. + """ + return + def endvisit_block(self, node): """ Used to endvisit a single block of statements. @@ -728,8 +759,8 @@ def visit(self, node): if isinstance(node, ASTBlockWithVariables): self.visit_block_with_variables(node) return - if isinstance(node, ASTBody): - self.visit_body(node) + if isinstance(node, ASTNeuronOrSynapseBody): + self.visit_neuron_or_synapse_body(node) return if isinstance(node, ASTComparisonOperator): self.visit_comparison_operator(node) @@ -788,6 +819,9 @@ def visit(self, node): if isinstance(node, ASTNeuron): self.visit_neuron(node) return + if isinstance(node, ASTSynapse): + self.visit_synapse(node) + return if isinstance(node, ASTOdeEquation): self.visit_ode_equation(node) return @@ -821,6 +855,9 @@ def visit(self, node): if isinstance(node, ASTUpdateBlock): self.visit_update_block(node) return + if isinstance(node, ASTOnReceiveBlock): + self.visit_on_receive_block(node) + return if isinstance(node, ASTVariable): self.visit_variable(node) return @@ -853,8 +890,8 @@ def traverse(self, node): if isinstance(node, ASTBlockWithVariables): self.traverse_block_with_variables(node) return - if isinstance(node, ASTBody): - self.traverse_body(node) + if isinstance(node, ASTNeuronOrSynapseBody): + self.traverse_neuron_or_synapse_body(node) return if isinstance(node, ASTComparisonOperator): self.traverse_comparison_operator(node) @@ -913,6 +950,9 @@ def traverse(self, node): if isinstance(node, ASTNeuron): self.traverse_neuron(node) return + if isinstance(node, ASTSynapse): + self.traverse_synapse(node) + return if isinstance(node, ASTOdeEquation): self.traverse_ode_equation(node) return @@ -946,6 +986,9 @@ def traverse(self, node): if isinstance(node, ASTUpdateBlock): self.traverse_update_block(node) return + if isinstance(node, ASTOnReceiveBlock): + self.traverse_on_receive_block(node) + return if isinstance(node, ASTVariable): self.traverse_variable(node) return @@ -978,8 +1021,8 @@ def endvisit(self, node): if isinstance(node, ASTBlockWithVariables): self.endvisit_block_with_variables(node) return - if isinstance(node, ASTBody): - self.endvisit_body(node) + if isinstance(node, ASTNeuronOrSynapseBody): + self.endvisit_neuron_or_synapse_body(node) return if isinstance(node, ASTComparisonOperator): self.endvisit_comparison_operator(node) @@ -1038,6 +1081,9 @@ def endvisit(self, node): if isinstance(node, ASTNeuron): self.endvisit_neuron(node) return + if isinstance(node, ASTSynapse): + self.endvisit_synapse(node) + return if isinstance(node, ASTOdeEquation): self.endvisit_ode_equation(node) return @@ -1071,6 +1117,9 @@ def endvisit(self, node): if isinstance(node, ASTUpdateBlock): self.endvisit_update_block(node) return + if isinstance(node, ASTOnReceiveBlock): + self.endvisit_on_receive_block(node) + return if isinstance(node, ASTVariable): self.endvisit_variable(node) return @@ -1107,7 +1156,13 @@ def traverse_block_with_variables(self, _node): sub_node.accept(self.get_real_self()) return - def traverse_body(self, node): + def traverse_neuron_or_synapse_body(self, node): + if node.get_body_elements() is not None: + for sub_node in node.get_body_elements(): + sub_node.accept(self.get_real_self()) + return + + def traverse_synapse_body(self, node): if node.get_body_elements() is not None: for sub_node in node.get_body_elements(): sub_node.accept(self.get_real_self()) @@ -1188,9 +1243,8 @@ def traverse_for_stmt(self, node): return def traverse_function(self, node): - if node.get_parameters() is not None: - for sub_node in node.get_parameters(): - sub_node.accept(self.get_real_self()) + for sub_node in node.get_parameters(): + sub_node.accept(self.get_real_self()) if node.get_return_type() is not None: node.get_return_type().accept(self.get_real_self()) if node.get_block() is not None: @@ -1241,6 +1295,9 @@ def traverse_compilation_unit(self, node): if node.get_neuron_list() is not None: for sub_node in node.get_neuron_list(): sub_node.accept(self.get_real_self()) + if node.get_synapse_list() is not None: + for sub_node in node.get_synapse_list(): + sub_node.accept(self.get_real_self()) return def traverse_neuron(self, node): @@ -1248,6 +1305,11 @@ def traverse_neuron(self, node): node.get_body().accept(self.get_real_self()) return + def traverse_synapse(self, node): + if node.get_body() is not None: + node.get_body().accept(self.get_real_self()) + return + def traverse_ode_equation(self, node): if node.get_lhs() is not None: node.get_lhs().accept(self.get_real_self()) @@ -1319,6 +1381,11 @@ def traverse_update_block(self, node): node.get_block().accept(self.get_real_self()) return + def traverse_on_receive_block(self, node): + if node.get_block() is not None: + node.get_block().accept(self.get_real_self()) + return + def traverse_variable(self, node): return diff --git a/pynestml/visitors/comment_collector_visitor.py b/pynestml/visitors/comment_collector_visitor.py index e20a83769..ff9db61b2 100644 --- a/pynestml/visitors/comment_collector_visitor.py +++ b/pynestml/visitors/comment_collector_visitor.py @@ -18,6 +18,9 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +from typing import List, Optional + from pynestml.generated.PyNestMLParserVisitor import PyNestMLParserVisitor @@ -26,134 +29,154 @@ class CommentCollectorVisitor(PyNestMLParserVisitor): This visitor iterates over a given parse tree and inspects the corresponding stream of tokens in order to update all nodes by their corresponding tokens. Attributes: - __tokens (list): A list of all tokens representing the model. """ - def __init__(self, tokens): + def __init__(self, tokens, strip_delim: bool = True): + """ + Parameters + ---------- + tokens + A list of all tokens representing the model. + strip_delim + Whether to strip the comment delimiters (``#`` and ``\"\"\"``...``\"\"\"``). + """ + self.__tokens = tokens + self.__strip_delim = strip_delim def visitBlockWithVariables(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitBlock(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitNeuron(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) + + def visitSynapse(self, ctx): + return (get_comments(ctx, self.__tokens), get_pre_comments(ctx, self.__tokens), + get_in_comment(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) def visitOdeEquation(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitInlineExpression(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitKernel(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitStmt(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitSmallStmt(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitCompoundStmt(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitInputPort(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitDeclaration(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitAssignment(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitUpdateBlock(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) + + def visitOnReceiveBlock(self, ctx): + return (get_comments(ctx, self.__tokens), get_pre_comments(ctx, self.__tokens), + get_in_comment(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) def visitEquationsBlock(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitInputBlock(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitOutputBlock(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitFunctionCall(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitFunction(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitForStmt(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitWhileStmt(self, ctx): - return (get_comments(ctx, self.__tokens), get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), get_post_comments(ctx, self.__tokens)) + return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), get_post_comments(ctx, self.__tokens, self.__strip_delim)) def visitIfClause(self, ctx): temp = list() - temp.extend(get_pre_comment(ctx, self.__tokens)) - temp.append(get_in_comments(ctx, self.__tokens)) + temp.extend(get_pre_comments(ctx, self.__tokens, self.__strip_delim)) + temp.append(get_in_comment(ctx, self.__tokens, self.__strip_delim)) # for if clauses no post comments are supported - return (temp, get_pre_comment(ctx, self.__tokens), - get_in_comments(ctx, self.__tokens), list()) + return (temp, get_pre_comments(ctx, self.__tokens, self.__strip_delim), + get_in_comment(ctx, self.__tokens, self.__strip_delim), list()) def visitElifClause(self, ctx): - temp = get_in_comments(ctx, self.__tokens) + temp = get_in_comment(ctx, self.__tokens, self.__strip_delim) if temp is None: temp = list() else: temp = list(temp) # for elif clauses, only in comments are supported - return (temp, list(), get_in_comments(ctx, self.__tokens), + return (temp, list(), get_in_comment(ctx, self.__tokens, self.__strip_delim), list()) def visitElseClause(self, ctx): - temp = get_in_comments(ctx, self.__tokens) + temp = get_in_comment(ctx, self.__tokens, self.__strip_delim) if temp is None: temp = list() else: temp = list(temp) - return (temp, list(), get_in_comments(ctx, self.__tokens), - get_post_comments(ctx, self.__tokens)) + return (temp, list(), get_in_comment(ctx, self.__tokens, self.__strip_delim), + get_post_comments(ctx, self.__tokens, self.__strip_delim)) -def get_comments(ctx, tokens): +def is_newline(tok): + return tok.text in ['\n', '\r\n'] + + +def get_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: """ - Returns all previously, in-line and pos comments. + Returns all pre-, inline and post-comments. :param ctx: a context :type ctx: ctx :param tokens: list of token objects :type tokens: list(Tokens) :return: a list of comments - :rtype: list(str) """ ret = list() - pre_comments = get_pre_comment(ctx, tokens) - in_comment = get_in_comments(ctx, tokens) - post_comments = get_post_comments(ctx, tokens) + pre_comments = get_pre_comments(ctx, tokens, strip_delim=strip_delim) + in_comment = get_in_comment(ctx, tokens, strip_delim=strip_delim) + post_comments = get_post_comments(ctx, tokens, strip_delim=strip_delim) if pre_comments is not None: ret.extend(pre_comments) if in_comment is not None: @@ -163,49 +186,55 @@ def get_comments(ctx, tokens): return ret -def get_pre_comment(ctx, tokens): +def get_pre_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: """ - Returns the comment which has been stated before this element but also before the next previous token. + Returns the comment which has been started before this element but also before the next previous token. :param ctx: a context :type ctx: ctx :param tokens: list of token objects :type tokens: list(Tokens) - :return: the corresponding comment or None - :rtype: str + :return: the corresponding comments """ # first find the position of this token in the stream comments = list() empty_before = __no_definitions_before(ctx, tokens) - eol = False temp = None for possibleCommentToken in reversed(tokens[0:tokens.index(ctx.start)]): - # if we hit a normal token (i.e. not whitespace, not newline and not token) then stop, since we reached - # the next previous element, thus the next comments belong to this element - if possibleCommentToken.channel == 0: - break - # if we have found a comment, put it on the "stack". we now have to check if there is an element defined - # in the same line, since in this case, the comments does not belong to us - if possibleCommentToken.channel == 2: - # if it is something on the comment channel -> get it - temp = replace_delimiters(possibleCommentToken.text) - eol = False # skip whitespaces if possibleCommentToken.channel == 1: continue - # if the previous token was an EOL and and this token is neither a white space nor a comment, thus - # it is yet another newline,stop (two lines separate a two elements) - elif eol and not empty_before: + # if we hit a normal token (i.e. not whitespace and not newline) then stop + if possibleCommentToken.channel == 0 and (not is_newline(possibleCommentToken)): break - # we have found a new line token. thus if we have stored a comment on the stack, its ok to store it in - # our element, since it does not belong to a declaration in its line - if possibleCommentToken.channel == 3: + # a newline by itself separates elements + if possibleCommentToken.channel == 0 and is_newline(possibleCommentToken): if temp is not None: comments.append(temp) - eol = True - continue - # this last part is required in the case, that the very fist token is a comment + break + # if we have found a comment, put it on the "stack". we now have to check if there is an element defined + # in the same line, since in this case, the comments does not belong to us + if possibleCommentToken.channel == 2: + if temp is not None: + comments.append(temp) + if strip_delim: + temp = replace_delimiters(possibleCommentToken.text) + else: + temp = possibleCommentToken.text + # this last part is required in the case, that the very first token is a comment if empty_before and temp is not None and temp not in comments: comments.append(temp) + # strip leading newlines -- this removes the newline after an opening ``"""`` if present + for i, comment in enumerate(comments): + if len(comment) > 0 and comment[0] == '\n': + comments[i] = comment[1:] + if len(comment) > 1 and comment[0] == '\r' and comment[1] == '\n': + comments[i] = comment[2:] + # strip trailing newlines + for i, comment in enumerate(comments): + if len(comment) > 0 and comment[-1] == '\n': + comments[i] = comment[:-1] + if len(comment) > 1 and comment[-1] == '\n' and comment[-2] == '\r': + comments[i] = comment[:-2] # we reverse it in order to get the right order of comments return list(reversed(comments)) if len(comments) > 0 else list() @@ -222,73 +251,96 @@ def __no_definitions_before(ctx, tokens): :rtype: bool """ for token in tokens[0:tokens.index(ctx.start)]: - if token.channel == 0: + if token.channel == 0 and (not is_newline(token)): return False return True -def get_in_comments(ctx, tokens): +def get_in_comment(ctx, tokens, strip_delim: bool = True) -> Optional[str]: """ - Returns the sole comment if one is defined in the same line, e.g. function a mV = 10mV # comment + Returns the sole comment if one is defined in the same line, e.g. ``a = 10 mV # comment`` :param ctx: a context :type ctx: ctx :param tokens: list of token objects :type tokens: list(Tokens) :return: a comment - :rtype: str """ for possibleComment in tokens[tokens.index(ctx.start):]: if possibleComment.channel == 2: - return replace_delimiters(possibleComment.text) - if possibleComment.channel == 3: # channel 3 == new line, thus the one line comment ends here + if strip_delim: + comment = replace_delimiters(possibleComment.text) + else: + comment = possibleComment.text + if len(comment) > 0 and comment[-1] == '\n': + comment = comment[:-1] + if len(comment) > 1 and comment[-1] == '\n' and comment[-2] == '\r': + comment = comment[:-2] + return comment + if is_newline(possibleComment): # new line, thus the one line comment ends here break return None -def get_post_comments(ctx, tokens): +def get_post_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: """ - Returns the comment which has been stated after the current token but in the same line. + Returns comments which have been stated after the current token but not in the same line. + :param ctx: a context :type ctx: ctx :param tokens: list of token objects :type tokens: list(Tokens) - :return: the corresponding comment or None - :rtype: str + :return: the corresponding comments """ comments = list() next_line_start_index = -1 # first find out where the next line start, since we want to avoid to see comments, which have # been stated in the same line, as comments which are stated after the element + prev_token_was_comment = False for possibleToken in tokens[tokens.index(ctx.stop) + 1:]: - if possibleToken.channel == 3: - next_line_start_index = tokens.index(possibleToken) + if possibleToken.channel == 0 or is_newline(possibleToken): + next_line_start_index = tokens.index(possibleToken) + 1 break + if possibleToken.channel == 2: + if prev_token_was_comment: + # two comments in a row, first one is inline comment, second is post comment + next_line_start_index = tokens.index(possibleToken) + break + prev_token_was_comment = True first_line = False for possibleCommentToken in tokens[next_line_start_index:]: if possibleCommentToken.channel == 2: # if it is a comment on the comment channel -> get it - comments.append(replace_delimiters(possibleCommentToken.text)) - first_line = False + if strip_delim: + comments.append(replace_delimiters(possibleCommentToken.text)) + else: + comments.append(possibleCommentToken.text) # we found a white line, thus a comment separator - if possibleCommentToken.channel == 3 and first_line: + if is_newline(possibleCommentToken): break - elif possibleCommentToken.channel == 3: - first_line = True # if we see a different element, i.e. that we have reached the next declaration and should stop - if possibleCommentToken.channel == 0: + if possibleCommentToken.channel == 0 and (not is_newline(possibleCommentToken)): break + # strip newlines + for i, comment in enumerate(comments): + if len(comment) > 0 and comment[-1] == '\n': + comments[i] = comment[:-1] + if len(comment) > 1 and comment[-1] == '\n' and comment[-2] == '\r': + comments[i] = comment[:-2] return comments if len(comments) > 0 else list() -def replace_delimiters(comment): - # type: (str) -> str +def replace_delimiters(comment: str) -> str: """ - Returns the raw comment, i.e., without the comment-tags /* ..*/, \""" ""\" and # + Returns the raw comment, i.e., without the comment delimiters (``#`` or ``\"\"\"``...``\"\"\"``). """ - ret = comment - ret = ret.replace('/*', '').replace('*/', '') - ret = ret.replace('"""', '') - return ret.replace('#', '') + if len(comment) > 2 and comment[:2] == "\"\"\"": + # it's a docstring comment + return comment.replace("\"\"\"", "") + # it's a hash comment + if len(comment) > 0 and comment[0] == "#": + # strip initial character hash + comment = comment[1:] + return comment.replace('\n#', '').replace('\r\n#', '') diff --git a/requirements.txt b/requirements.txt index 72e49b270..9192b028a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ numpy >= 1.8.2 -sympy >= 1.1.1 -antlr4-python3-runtime >= 4.7 +sympy >= 1.1.1,!= 1.11, != 1.11.1 +antlr4-python3-runtime == 4.10 setuptools Jinja2 >= 2.10 -typing +typing;python_version<"3.5" astropy -odetoolbox >= 2.0 +odetoolbox >= 2.4 diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 index 27aa7e7ac..5bfe2bab1 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ import sys from setuptools import setup, find_packages -assert sys.version_info.major >= 3, "Python 3 is required to run PyNESTML" +assert sys.version_info.major >= 3 and sys.version_info.minor >= 9, "Python 3.9 or higher is required to run NESTML" with open("requirements.txt") as f: requirements = f.read().splitlines() @@ -39,7 +39,7 @@ setup( name="NESTML", - version="3.1-post-dev", + version="5.1.0-post-dev", description="NESTML is a domain specific language that supports the specification of neuron models in a" " precise and concise syntax, based on the syntax of Python. Model equations can either be given" " as a simple string of mathematical notation or as an algorithm written in the built-in procedural" @@ -48,9 +48,14 @@ license="GNU General Public License v2.0", url="https://github.com/nest/nestml", packages=find_packages(), - package_data={"pynestml": ["codegeneration/resources_nest/*.jinja2", - "codegeneration/resources_nest/setup/*.jinja2", - "codegeneration/resources_nest/directives/*.jinja2"]}, + package_data={"pynestml": ["codegeneration/resources_autodoc/*.jinja2", + "codegeneration/resources_nest/point_neuron/*.jinja2", + "codegeneration/resources_nest/point_neuron/common/*.jinja2", + "codegeneration/resources_nest/point_neuron/directives/*.jinja2", + "codegeneration/resources_nest/point_neuron/setup/*.jinja2", + "codegeneration/resources_nest_compartmental/cm_neuron/*.jinja2", + "codegeneration/resources_nest_compartmental/cm_neuron/directives/*.jinja2", + "codegeneration/resources_nest_compartmental/cm_neuron/setup/*.jinja2"]}, data_files=data_files, entry_points={ "console_scripts": [ diff --git a/tests/as_component_test.py b/tests/as_component_test.py deleted file mode 100644 index 74520c444..000000000 --- a/tests/as_component_test.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -# -# as_component_test.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -import unittest -import os -import shutil - -from pynestml.frontend.pynestml_frontend import to_nest -from pynestml.frontend.frontend_configuration import FrontendConfiguration - - -class AsComponentTest(unittest.TestCase): - """" - This test checks whether PyNestML can be executed correctly as a component from a different component. - """ - - def test_from_string(self): - input_path = str(os.path.join(os.path.dirname(__file__), 'resources', 'CommentTest.nestml')) - target_path = 'target' - logging_level = 'INFO' - module_name = 'module' - store_log = False - suffix = '' - dev = True - to_nest(input_path, target_path, logging_level, module_name, store_log, suffix, dev) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'CMakeLists.txt'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'commentTest.cpp'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'commentTest.h'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'module.cpp'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'module.h'))) - - def test_from_objects(self): - input_path = os.path.join(os.path.dirname(__file__), 'resources', 'CommentTest.nestml') - target_path = os.path.join('target') - logging_level = 'INFO' - module_name = 'module' - store_log = False - suffix = '' - dev = True - to_nest(input_path, target_path, logging_level, module_name, store_log, suffix, dev) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'CMakeLists.txt'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'commentTest.cpp'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'commentTest.h'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'module.cpp'))) - self.assertTrue(os.path.isfile(os.path.join(FrontendConfiguration.get_target_path(), 'module.h'))) - - def tearDown(self): - # clean up - shutil.rmtree(FrontendConfiguration.target_path) diff --git a/tests/ast_builder_test.py b/tests/ast_builder_test.py index 49d34790d..a49c6d3d2 100644 --- a/tests/ast_builder_test.py +++ b/tests/ast_builder_test.py @@ -45,8 +45,8 @@ class ASTBuildingTest(unittest.TestCase): - @classmethod - def test(cls): + + def test(self): for filename in os.listdir(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join('..', 'models')))): if filename.endswith(".nestml"): @@ -54,13 +54,20 @@ def test(cls): input_file = FileStream( os.path.join(os.path.dirname(__file__), os.path.join(os.path.join('..', 'models'), filename))) lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() + # parse the file parser = PyNestMLParser(stream) - # process the comments + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + compilation_unit = parser.nestMLCompilationUnit() + # now build the meta_model ast_builder_visitor = ASTBuilderVisitor(stream.tokens) ast = ast_builder_visitor.visit(compilation_unit) diff --git a/tests/ast_clone_test.py b/tests/ast_clone_test.py index d5bf9e28f..923cc9f90 100644 --- a/tests/ast_clone_test.py +++ b/tests/ast_clone_test.py @@ -52,13 +52,21 @@ def _test_single_input_path(cls, input_path): print('Start creating AST for ' + input_path + ' ...'), input_file = FileStream(input_path) lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() + # parse the file parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + # process the comments compilation_unit = parser.nestMLCompilationUnit() + # now build the meta_model ast_builder_visitor = ASTBuilderVisitor(stream.tokens) ast = ast_builder_visitor.visit(compilation_unit) diff --git a/tests/cocos_test.py b/tests/cocos_test.py index 1f7411f6b..e39e16c11 100644 --- a/tests/cocos_test.py +++ b/tests/cocos_test.py @@ -38,7 +38,12 @@ class CoCosTest(unittest.TestCase): def setUp(self): Logger.init_logger(LoggingLevel.INFO) - SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + SymbolTable.initialize_symbol_table( + ASTSourceLocation( + start_line=0, + start_column=0, + end_line=0, + end_column=0)) PredefinedUnits.register_units() PredefinedTypes.register_types() PredefinedVariables.register_variables() @@ -46,467 +51,819 @@ def setUp(self): def test_invalid_element_defined_after_usage(self): model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVariableDefinedAfterUsage.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVariableDefinedAfterUsage.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_element_defined_after_usage(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableDefinedAfterUsage.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVariableDefinedAfterUsage.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_element_in_same_line(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoElementInSameLine.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoElementInSameLine.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_element_in_same_line(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoElementInSameLine.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoElementInSameLine.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_integrate_odes_called_if_equations_defined(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoIntegrateOdesCalledIfEquationsDefined.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_integrate_odes_called_if_equations_defined(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoIntegrateOdesCalledIfEquationsDefined.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_element_not_defined_in_scope(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVariableNotDefined.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)), 5) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVariableNotDefined.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) def test_valid_element_not_defined_in_scope(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableNotDefined.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), - 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVariableNotDefined.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_variable_with_same_name_as_unit(self): Logger.set_logging_level(LoggingLevel.NO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableWithSameNameAsUnit.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.WARNING)), - 3) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVariableWithSameNameAsUnit.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.WARNING)), 3) def test_invalid_variable_redeclaration(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVariableRedeclared.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVariableRedeclared.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_variable_redeclaration(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableRedeclared.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVariableRedeclared.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_each_block_unique(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoEachBlockUnique.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoEachBlockUnique.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) def test_valid_each_block_unique(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoEachBlockUnique.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoEachBlockUnique.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_function_unique_and_defined(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoFunctionNotUnique.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoFunctionNotUnique.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) def test_valid_function_unique_and_defined(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoFunctionNotUnique.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoFunctionNotUnique.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_inline_expressions_have_rhs(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInlineExpressionHasNoRhs.nestml')) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoInlineExpressionHasNoRhs.nestml')) assert model is None def test_valid_inline_expressions_have_rhs(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInlineExpressionHasNoRhs.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoInlineExpressionHasNoRhs.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_inline_expression_has_several_lhs(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInlineExpressionWithSeveralLhs.nestml')) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoInlineExpressionWithSeveralLhs.nestml')) assert model is None def test_valid_inline_expression_has_several_lhs(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInlineExpressionWithSeveralLhs.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_no_values_assigned_to_buffers(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoInlineExpressionWithSeveralLhs.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_no_values_assigned_to_input_ports(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoValueAssignedToBuffer.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_no_values_assigned_to_buffers(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoValueAssignedToInputPort.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_no_values_assigned_to_input_ports(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoValueAssignedToBuffer.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoValueAssignedToInputPort.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_order_of_equations_correct(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoNoOrderOfEquations.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoNoOrderOfEquations.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) def test_valid_order_of_equations_correct(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoNoOrderOfEquations.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoNoOrderOfEquations.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_numerator_of_unit_one(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoUnitNumeratorNotOne.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)), 2) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoUnitNumeratorNotOne.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) def test_valid_numerator_of_unit_one(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoUnitNumeratorNotOne.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoUnitNumeratorNotOne.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_names_of_neurons_unique(self): Logger.init_logger(LoggingLevel.INFO) ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoMultipleNeuronsWithEqualName.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoMultipleNeuronsWithEqualName.nestml')) + self.assertEqual( + len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)), 1) def test_valid_names_of_neurons_unique(self): Logger.init_logger(LoggingLevel.INFO) ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoMultipleNeuronsWithEqualName.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoMultipleNeuronsWithEqualName.nestml')) + self.assertEqual( + len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)), 0) def test_invalid_no_nest_collision(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoNestNamespaceCollision.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoNestNamespaceCollision.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_no_nest_collision(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoNestNamespaceCollision.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_redundant_buffer_keywords_detected(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoNestNamespaceCollision.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_redundant_input_port_keywords_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoBufferWithRedundantTypes.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_redundant_buffer_keywords_detected(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoInputPortWithRedundantTypes.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_redundant_input_port_keywords_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoBufferWithRedundantTypes.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoInputPortWithRedundantTypes.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_parameters_assigned_only_in_parameters_block(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoParameterAssignedOutsideBlock.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoParameterAssignedOutsideBlock.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_parameters_assigned_only_in_parameters_block(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoParameterAssignedOutsideBlock.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_current_buffers_not_specified_with_keywords(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoParameterAssignedOutsideBlock.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_continuous_input_ports_not_specified_with_keywords(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoCurrentBufferQualifierSpecified.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_current_buffers_not_specified(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoContinuousInputPortQualifierSpecified.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_continuous_input_ports_not_specified(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoCurrentBufferQualifierSpecified.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_spike_buffer_without_datatype(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoContinuousInputPortQualifierSpecified.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_spike_input_port_without_datatype(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoSpikeBufferWithoutType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_spike_buffer_without_datatype(self): + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoSpikeInputPortWithoutType.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_spike_input_port_without_datatype(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoSpikeBufferWithoutType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoSpikeInputPortWithoutType.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_function_with_wrong_arg_number_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_function_with_wrong_arg_number_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_init_values_have_rhs_and_ode(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInitValuesWithoutOde.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.WARNING)), 3) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoInitValuesWithoutOde.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.WARNING)), 2) def test_valid_init_values_have_rhs_and_ode(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInitValuesWithoutOde.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.WARNING)), 2) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoInitValuesWithoutOde.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.WARNING)), 2) def test_invalid_incorrect_return_stmt_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoIncorrectReturnStatement.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoIncorrectReturnStatement.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) def test_valid_incorrect_return_stmt_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoIncorrectReturnStatement.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoIncorrectReturnStatement.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_ode_vars_outside_init_block_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOdeVarNotInInitialValues.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoOdeVarNotInInitialValues.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_ode_vars_outside_init_block_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoOdeVarNotInInitialValues.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoOdeVarNotInInitialValues.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_convolve_correctly_defined(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoConvolveNotCorrectlyProvided.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)), 3) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoConvolveNotCorrectlyProvided.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) def test_valid_convolve_correctly_defined(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoConvolveNotCorrectlyProvided.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoConvolveNotCorrectlyProvided.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_vector_in_non_vector_declaration_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVectorInNonVectorDeclaration.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVectorInNonVectorDeclaration.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_vector_in_non_vector_declaration_detected(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVectorInNonVectorDeclaration.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVectorInNonVectorDeclaration.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_vector_parameter_declaration(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVectorParameterDeclaration.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_vector_parameter_declaration(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVectorParameterDeclaration.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_vector_parameter_type(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVectorParameterType.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_vector_parameter_type(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVectorParameterType.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_vector_parameter_size(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoVectorDeclarationSize.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_vector_parameter_size(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoVectorDeclarationSize.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_convolve_correctly_parameterized(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoConvolveNotCorrectlyParametrized.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoConvolveNotCorrectlyParametrized.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_convolve_correctly_parameterized(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoConvolveNotCorrectlyParametrized.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoConvolveNotCorrectlyParametrized.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_invariant_correctly_typed(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInvariantNotBool.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoInvariantNotBool.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_valid_invariant_correctly_typed(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInvariantNotBool.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoInvariantNotBool.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_expression_correctly_typed(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoIllegalExpression.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)), 6) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoIllegalExpression.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 6) def test_valid_expression_correctly_typed(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoIllegalExpression.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoIllegalExpression.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_compound_expression_correctly_typed(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 5) + + def test_valid_compound_expression_correctly_typed(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_ode_correctly_typed(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOdeIncorrectlyTyped.nestml')) - self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)) > 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoOdeIncorrectlyTyped.nestml')) + self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)) > 0) def test_valid_ode_correctly_typed(self): Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoOdeCorrectlyTyped.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoOdeCorrectlyTyped.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_output_block_defined_if_emit_call(self): """test that an error is raised when the emit_spike() function is called by the neuron, but an output block is not defined""" Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOutputPortDefinedIfEmitCall.nestml')) - self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)) > 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoOutputPortDefinedIfEmitCall.nestml')) + self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)) > 0) def test_invalid_output_port_defined_if_emit_call(self): """test that an error is raised when the emit_spike() function is called by the neuron, but a spiking output port is not defined""" Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOutputPortDefinedIfEmitCall-2.nestml')) - self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)) > 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoOutputPortDefinedIfEmitCall-2.nestml')) + self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)) > 0) def test_valid_output_port_defined_if_emit_call(self): """test that no error is raised when the output block is missing, but not emit_spike() functions are called""" Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoOutputPortDefinedIfEmitCall.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoOutputPortDefinedIfEmitCall.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_valid_coco_kernel_type(self): """ @@ -514,10 +871,14 @@ def test_valid_coco_kernel_type(self): """ Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoKernelType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoKernelType.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) def test_invalid_coco_kernel_type(self): """ @@ -525,10 +886,14 @@ def test_invalid_coco_kernel_type(self): """ Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoKernelType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoKernelType.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) def test_invalid_coco_kernel_type_initial_values(self): """ @@ -536,7 +901,301 @@ def test_invalid_coco_kernel_type_initial_values(self): """ Logger.set_logging_level(LoggingLevel.INFO) model = ModelParser.parse_model( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoKernelTypeInitialValues.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoKernelTypeInitialValues.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) + + def test_valid_coco_state_variables_initialized(self): + """ + Test that the CoCo condition is applicable for all the variables in the state block initialized with a value + """ + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoStateVariablesInitialized.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_coco_state_variables_initialized(self): + """ + Test that the CoCo condition is applicable for all the variables in the state block not initialized + """ + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoStateVariablesInitialized.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_invalid_at_least_one_cm_gating_variable_name(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmVariableName.nestml')) + # assert there is exactly one error + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_at_least_one_cm_gating_variable_name(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmVariableName.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_cm_function_existence(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmFunctionExists.nestml')) + # assert there are exactly 2 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_cm_function_existence(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmFunctionExists.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_cm_variables_declared(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmVariablesDeclared.nestml')) + # assert there are exactly 3 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 3) + + def test_valid_cm_variables_declared(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmVariablesDeclared.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_cm_function_one_arg(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmFunctionOneArg.nestml')) + # assert there are exactly 2 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_cm_function_one_arg(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmFunctionOneArg.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_cm_function_returns_real(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmFunctionReturnsReal.nestml')) + # assert there are exactly 4 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 4) + + def test_valid_cm_function_returns_real(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmFunctionReturnsReal.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_synapse_uses_exactly_one_buffer(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoSynsOneBuffer.nestml')) + # assert there are exactly 1 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_synapse_uses_exactly_one_buffer(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoSynsOneBuffer.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + # it is currently not enforced for the non-cm parameter block, but cm + # needs that + def test_invalid_cm_variable_has_rhs(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmVariableHasRhs.nestml')) + # assert there are exactly 5 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 5) + + def test_valid_cm_variable_has_rhs(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmVariableHasRhs.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + # it is currently not enforced for the non-cm parameter block, but cm + # needs that + def test_invalid_cm_v_comp_exists(self): + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoCmVcompExists.nestml')) + # assert there are exactly 5 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_cm_v_comp_exists(self): + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoCmVcompExists.nestml')) + # assert there is exactly 0 errors + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_neuron_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_co_co_priorities_correctly_specified(self): + """ + """ + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoPrioritiesCorrectlySpecified.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_synapse_list()[0], LoggingLevel.ERROR)), 1) + + def test_valid_co_co_priorities_correctly_specified(self): + """ + """ + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoPrioritiesCorrectlySpecified.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_synapse_list()[0], LoggingLevel.ERROR)), 0) + + def test_invalid_co_co_resolution_legally_used(self): + """ + """ + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'invalid')), + 'CoCoResolutionLegallyUsed.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_synapse_list()[0], LoggingLevel.ERROR)), 2) + + def test_valid_co_co_resolution_legally_used(self): + """ + """ + Logger.set_logging_level(LoggingLevel.INFO) + model = ModelParser.parse_model( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + 'valid')), + 'CoCoResolutionLegallyUsed.nestml')) + self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node( + model.get_synapse_list()[0], LoggingLevel.ERROR)), 0) diff --git a/tests/codegen_opts_detects_non_existing.py b/tests/codegen_opts_detects_non_existing.py new file mode 100644 index 000000000..b16a6c091 --- /dev/null +++ b/tests/codegen_opts_detects_non_existing.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# +# codegen_opts_detects_non_existing.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os +import pytest + +from pynestml.exceptions.code_generator_options_exception import CodeGeneratorOptionsException +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +@pytest.mark.xfail(strict=True, raises=CodeGeneratorOptionsException) +def test_codegen_opts_detects_non_existing(): + generate_nest_target(input_path="models/neurons/iaf_psc_exp.nestml", + codegen_opts={"non_existing_options": "42"}) diff --git a/tests/comment_test.py b/tests/comment_test.py index 014c02a9c..ac64b7de1 100644 --- a/tests/comment_test.py +++ b/tests/comment_test.py @@ -51,21 +51,31 @@ def test(self): os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'CommentTest.nestml')) lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() + # parse the file parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + # process the comments compilation_unit = parser.nestMLCompilationUnit() + # now build the meta_model ast_builder_visitor = ASTBuilderVisitor(stream.tokens) ast = ast_builder_visitor.visit(compilation_unit) - neuron_body_elements = ast.get_neuron_list()[0].get_body().get_body_elements() + neuron_or_synapse_body_elements = ast.get_neuron_list()[0].get_body().get_body_elements() + # check if init values comment is correctly detected - assert (neuron_body_elements[0].get_comment()[0] == 'init_values comment ok') + assert (neuron_or_synapse_body_elements[0].get_comment()[0] == 'state comment ok') + # check that all declaration comments are detected - comments = neuron_body_elements[0].get_declarations()[0].get_comment() + comments = neuron_or_synapse_body_elements[0].get_declarations()[0].get_comment() assert (comments[0] == 'pre comment 1 ok') assert (comments[1] == 'pre comment 2 ok') assert (comments[2] == 'inline comment ok') @@ -73,18 +83,19 @@ def test(self): assert (comments[4] == 'post comment 2 ok') assert ('pre comment not ok' not in comments) assert ('post comment not ok' not in comments) + # check that equation block comment is detected - self.assertEqual(neuron_body_elements[1].get_comment()[0], 'equations comment ok') + self.assertEqual(neuron_or_synapse_body_elements[1].get_comment()[0], 'equations comment ok') # check that parameters block comment is detected - self.assertEqual(neuron_body_elements[2].get_comment()[0], 'parameters comment ok') + self.assertEqual(neuron_or_synapse_body_elements[2].get_comment()[0], 'parameters comment ok') # check that internals block comment is detected - self.assertEqual(neuron_body_elements[3].get_comment()[0], 'internals comment ok') + self.assertEqual(neuron_or_synapse_body_elements[3].get_comment()[0], 'internals comment ok') # check that input comment is detected - self.assertEqual(neuron_body_elements[4].get_comment()[0], 'input comment ok') + self.assertEqual(neuron_or_synapse_body_elements[4].get_comment()[0], 'input comment ok') # check that output comment is detected - self.assertEqual(neuron_body_elements[5].get_comment()[0], 'output comment ok') + self.assertEqual(neuron_or_synapse_body_elements[5].get_comment()[0], 'output comment ok') # check that update comment is detected - self.assertEqual(neuron_body_elements[6].get_comment()[0], 'update comment ok') + self.assertEqual(neuron_or_synapse_body_elements[6].get_comment()[0], 'update comment ok') if __name__ == '__main__': diff --git a/tests/pynestml_2_nest_type_converter_test.py b/tests/cpp_types_printer_test.py similarity index 78% rename from tests/pynestml_2_nest_type_converter_test.py rename to tests/cpp_types_printer_test.py index fdef19ec9..777697155 100644 --- a/tests/pynestml_2_nest_type_converter_test.py +++ b/tests/cpp_types_printer_test.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# pynestml_2_nest_type_converter_test.py +# cpp_types_printer_test.py # # This file is part of NEST. # @@ -18,11 +18,12 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + import unittest from astropy import units -from pynestml.codegeneration.pynestml_2_nest_type_converter import PyNestml2NestTypeConverter +from pynestml.codegeneration.printers.cpp_types_printer import CppTypesPrinter from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol from pynestml.symbols.integer_type_symbol import IntegerTypeSymbol from pynestml.symbols.nest_time_type_symbol import NESTTimeTypeSymbol @@ -34,52 +35,51 @@ from pynestml.symbols.void_type_symbol import VoidTypeSymbol from pynestml.utils.unit_type import UnitType -PredefinedUnits.register_units() -PredefinedTypes.register_types() - -convert = PyNestml2NestTypeConverter.convert +class CppTypesPrinterTest(unittest.TestCase): + def setUp(self): + PredefinedUnits.register_units() + PredefinedTypes.register_types() -class PyNestMl2NESTTypeConverterTest(unittest.TestCase): def test_boolean_type(self): bts = BooleanTypeSymbol() - result = convert(bts) + result = CppTypesPrinter().convert(bts) self.assertEqual(result, 'bool') return def test_real_type(self): rts = RealTypeSymbol() - result = convert(rts) + result = CppTypesPrinter().convert(rts) self.assertEqual(result, 'double') def test_void_type(self): vts = VoidTypeSymbol() - result = convert(vts) + result = CppTypesPrinter().convert(vts) self.assertEqual(result, 'void') def test_string_type(self): sts = StringTypeSymbol() - result = convert(sts) + result = CppTypesPrinter().convert(sts) self.assertEqual(result, 'std::string') def test_integer_type(self): its = IntegerTypeSymbol() - result = convert(its) + result = CppTypesPrinter().convert(its) self.assertEqual(result, 'long') def test_unit_type(self): ms_unit = UnitType(name=str(units.ms), unit=units.ms) uts = UnitTypeSymbol(unit=ms_unit) - result = convert(uts) + result = CppTypesPrinter().convert(uts) self.assertEqual(result, 'double') def test_buffer_type(self): bts = IntegerTypeSymbol() bts.is_buffer = True - result = convert(bts) + result = CppTypesPrinter().convert(bts) self.assertEqual(result, 'nest::RingBuffer') def test_time_type(self): tts = NESTTimeTypeSymbol() - result = convert(tts) + result = CppTypesPrinter().convert(tts) self.assertEqual(result, 'nest::Time') diff --git a/tests/docstring_comment_test.py b/tests/docstring_comment_test.py new file mode 100644 index 000000000..7f907b002 --- /dev/null +++ b/tests/docstring_comment_test.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# +# docstring_comment_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os +import pytest +import unittest + +from antlr4 import * +from antlr4.error.ErrorStrategy import BailErrorStrategy, DefaultErrorStrategy + +from pynestml.generated.PyNestMLLexer import PyNestMLLexer +from pynestml.generated.PyNestMLParser import PyNestMLParser +from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit +from pynestml.meta_model.ast_neuron import ASTNeuron +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.visitors.ast_builder_visitor import ASTBuilderVisitor +from pynestml.visitors.ast_visitor import ASTVisitor +from pynestml.visitors.comment_collector_visitor import CommentCollectorVisitor + + +# setups the infrastructure +PredefinedUnits.register_units() +PredefinedTypes.register_types() +PredefinedFunctions.register_functions() +PredefinedVariables.register_variables() +SymbolTable.initialize_symbol_table( + ASTSourceLocation( + start_line=0, + start_column=0, + end_line=0, + end_column=0)) +Logger.init_logger(LoggingLevel.ERROR) + + +class DocstringCommentException(Exception): + pass + + +class DocstringCommentTest(unittest.TestCase): + + def test_docstring_success(self): + self.run_docstring_test('valid') + + # for some reason xfail is completely ignored when executing on my machine (python 3.8.5) + # pytest bug? + @pytest.mark.xfail(strict=True, raises=DocstringCommentException) + def test_docstring_failure(self): + self.run_docstring_test('invalid') + + def run_docstring_test(self, case: str): + assert case in ['valid', 'invalid'] + input_file = FileStream( + os.path.join( + os.path.realpath( + os.path.join( + os.path.dirname(__file__), + case)), + 'DocstringCommentTest.nestml')) + lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream + stream = CommonTokenStream(lexer) + stream.fill() + # parse the file + parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + compilation_unit = parser.nestMLCompilationUnit() + # now build the meta_model + ast_builder_visitor = ASTBuilderVisitor(stream.tokens) + ast = ast_builder_visitor.visit(compilation_unit) + neuron_or_synapse_body_elements = ast.get_neuron_list()[ + 0].get_body().get_body_elements() + + # now run the docstring checker visitor + visitor = CommentCollectorVisitor(stream.tokens, strip_delim=False) + compilation_unit.accept(visitor) + # test whether ``"""`` is used correctly + assert len(ast.get_neuron_list() + ) == 1, "Neuron failed to load correctly" + + class CommentCheckerVisitor(ASTVisitor): + def visit(self, ast): + for comment in ast.get_comments(): + if "\"\"\"" in comment and not ( + isinstance( + ast, + ASTNeuron) or isinstance( + ast, + ASTNestMLCompilationUnit)): + raise DocstringCommentException() + for comment in ast.get_post_comments(): + if "\"\"\"" in comment: + raise DocstringCommentException() + visitor = CommentCheckerVisitor() + ast.accept(visitor) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/expression_parser_test.py b/tests/expression_parser_test.py index f32a096d0..b1869cc1b 100644 --- a/tests/expression_parser_test.py +++ b/tests/expression_parser_test.py @@ -52,21 +52,26 @@ class ExpressionParsingTest(unittest.TestCase): """ def test(self): - # print('Start Expression Parser Test...'), input_file = FileStream( os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'ExpressionCollection.nestml')) lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() + # parse the file parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) compilation_unit = parser.nestMLCompilationUnit() - # print('done') + assert compilation_unit is not None + ast_builder_visitor = ASTBuilderVisitor(stream.tokens) ast = ast_builder_visitor.visit(compilation_unit) - # print('done') self.assertTrue(isinstance(ast, ASTNestMLCompilationUnit)) diff --git a/tests/expression_type_calculation_test.py b/tests/expression_type_calculation_test.py index b3d0db6fe..502c140f0 100644 --- a/tests/expression_type_calculation_test.py +++ b/tests/expression_type_calculation_test.py @@ -21,8 +21,7 @@ import os import unittest -from pynestml.codegeneration.unit_converter import UnitConverter -from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.codegeneration.printers.unit_converter import UnitConverter from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes @@ -30,6 +29,7 @@ from pynestml.symbols.predefined_variables import PredefinedVariables from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import MessageCode from pynestml.utils.model_parser import ModelParser @@ -80,7 +80,6 @@ class ExpressionTypeCalculationTest(unittest.TestCase): A simple test that prints all top-level expression types in a file. """ - # TODO: this test needs to be refactored. def test(self): Logger.init_logger(LoggingLevel.INFO) model = ModelParser.parse_model( @@ -88,10 +87,9 @@ def test(self): 'resources', 'ExpressionTypeTest.nestml')))) Logger.set_current_node(model.get_neuron_list()[0]) model.accept(ExpressionTestVisitor()) - # ExpressionTestVisitor().handle(model) Logger.set_current_node(None) self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], - LoggingLevel.ERROR)), 2) + LoggingLevel.ERROR)), 0) if __name__ == '__main__': diff --git a/tests/function_parameter_templating_test.py b/tests/function_parameter_templating_test.py index cf917ac22..0f512e9ed 100644 --- a/tests/function_parameter_templating_test.py +++ b/tests/function_parameter_templating_test.py @@ -22,8 +22,7 @@ import os import unittest -from pynestml.codegeneration.unit_converter import UnitConverter -from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.codegeneration.printers.unit_converter import UnitConverter from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes @@ -31,6 +30,7 @@ from pynestml.symbols.predefined_variables import PredefinedVariables from pynestml.symbols.symbol import SymbolKind from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import MessageCode from pynestml.utils.model_parser import ModelParser @@ -53,7 +53,7 @@ def test(self): Logger.init_logger(LoggingLevel.INFO) model = ModelParser.parse_model( os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), - 'resources', 'FunctionParameterTemplatingTest.nestml')))) + "resources", "FunctionParameterTemplatingTest.nestml")))) self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 7) diff --git a/tests/invalid/CoCoBufferWithRedundantTypes.nestml b/tests/invalid/CoCoBufferWithRedundantTypes.nestml deleted file mode 100644 index ac7244215..000000000 --- a/tests/invalid/CoCoBufferWithRedundantTypes.nestml +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * CoCoBufferWithRedundantTypes.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if each buffer is defined uniquely, i.e., - * no redundant keywords are used. - * Negative case. -*/ - -neuron CoCoBufferWithRedundantTypes: - input: - spikeInhX2 integer <- inhibitory inhibitory spike # spike redundant keywords used. - end -end diff --git a/tests/invalid/CoCoCmFunctionExists.nestml b/tests/invalid/CoCoCmFunctionExists.nestml new file mode 100644 index 000000000..bd00ae78d --- /dev/null +++ b/tests/invalid/CoCoCmFunctionExists.nestml @@ -0,0 +1,59 @@ +""" +CoCoCmFunctionExists.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether functions expected for each +matching compartmental variable have been defined + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_one_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + + end + + equations: + inline Na real = m_Na**3 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/invalid/CoCoCmFunctionOneArg.nestml b/tests/invalid/CoCoCmFunctionOneArg.nestml new file mode 100644 index 000000000..91a4b8b8e --- /dev/null +++ b/tests/invalid/CoCoCmFunctionOneArg.nestml @@ -0,0 +1,81 @@ +""" +CoCoCmFunctionOneArg.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether compartmental model functions receive exactly +one argument + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_two_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + h_Na real = 0.0 + + end + + #sodium + function m_inf_Na() real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real, v_comp_1 real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + function some_random_function_to_ignore(v_comp real, something_else real) real: + return 0.0 + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/invalid/CoCoCmFunctionReturnsReal.nestml b/tests/invalid/CoCoCmFunctionReturnsReal.nestml new file mode 100644 index 000000000..a3d705549 --- /dev/null +++ b/tests/invalid/CoCoCmFunctionReturnsReal.nestml @@ -0,0 +1,82 @@ +""" +CoCoCmFunctionReturnsReal.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether functions expected for each +matching compartmental variable return type 'real' + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_three_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + h_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) boolean: + return true + end + + function tau_m_Na(v_comp real) integer: + return 1111111111 + end + + function h_inf_Na(v_comp real) string: + return "hello" + end + + function tau_h_Na(v_comp real) void: + v_comp+=1.0 + return + end + + function some_random_function_to_ignore(v_comp real, something_else real) string: + return "ignore" + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/invalid/CoCoCmVariableHasRhs.nestml b/tests/invalid/CoCoCmVariableHasRhs.nestml new file mode 100644 index 000000000..7283a48ab --- /dev/null +++ b/tests/invalid/CoCoCmVariableHasRhs.nestml @@ -0,0 +1,68 @@ +""" +CoCoCmVariableHasRhs.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether the all variable declarations of the +compartmental model contain a right hand side expression + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_four_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real + + m_Na real + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + equations: + inline Na real = m_Na**3 + + end + + parameters: + e_Na real + gbar_Na real + + end + + +end diff --git a/tests/invalid/CoCoCmVariableMultiUse.nestml b/tests/invalid/CoCoCmVariableMultiUse.nestml new file mode 100644 index 000000000..88a41f066 --- /dev/null +++ b/tests/invalid/CoCoCmVariableMultiUse.nestml @@ -0,0 +1,68 @@ +""" +CoCoCmVariableMultiUse.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether the inline expression that characterizes +a channel uses each variable exactly once + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_five_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + equations: + inline Na real = m_Na**3 * m_Na**2 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/invalid/CoCoCmVariableName.nestml b/tests/invalid/CoCoCmVariableName.nestml new file mode 100644 index 000000000..92388faba --- /dev/null +++ b/tests/invalid/CoCoCmVariableName.nestml @@ -0,0 +1,73 @@ +""" +CoCoCmVariableName.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether there is at least +one gating variable in the inline expression, meaning it +is suffixed with '_{channel_name_from_inline}' + +Negative case. + +Here _K instad of _Na is used +so no variable is recognized to be a gating variable + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model__six_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_K real = 0.0 + h_K real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + equations: + inline Na real = m_K**3 * h_K**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/invalid/CoCoCmVariablesDeclared.nestml b/tests/invalid/CoCoCmVariablesDeclared.nestml new file mode 100644 index 000000000..62226d95b --- /dev/null +++ b/tests/invalid/CoCoCmVariablesDeclared.nestml @@ -0,0 +1,72 @@ +""" +CoCoCmVariablesDeclared.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether compartmental variables used in the inline expression +are also declared in the corresponding state / parameter block + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_seven_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + + end + + +end diff --git a/tests/invalid/CoCoCmVcompExists.nestml b/tests/invalid/CoCoCmVcompExists.nestml new file mode 100644 index 000000000..1eef14096 --- /dev/null +++ b/tests/invalid/CoCoCmVcompExists.nestml @@ -0,0 +1,71 @@ +""" +CoCoCmVcompExists.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether, in case of a compartmental model ("NEST_COMPARTMENTAL"), +there is the required variable called v_comp defined in the state block + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_eight_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + m_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + + end + +end diff --git a/tests/invalid/CoCoContinuousInputPortQualifierSpecified.nestml b/tests/invalid/CoCoContinuousInputPortQualifierSpecified.nestml new file mode 100644 index 000000000..355b2b99c --- /dev/null +++ b/tests/invalid/CoCoContinuousInputPortQualifierSpecified.nestml @@ -0,0 +1,38 @@ +""" +CoCoContinuousInputPortQualifierSpecified.nestml +################################################ + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if continuous time input ports are not specified by qualifiers. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoContinuousInputPortQualifierSpecified: + input: + currents pA <- inhibitory continuous # qualifiers may not be specified for a continuous time input port + end +end diff --git a/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml b/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml index 0cd5608dc..738b3cdc5 100644 --- a/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml +++ b/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml @@ -1,32 +1,38 @@ -/** - * - * CoCoConvolveNotCorrectlyParametrized.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly - * provided with a initial_block variable and a spike buffer. - * Negative case. -*/ +""" +CoCoConvolveNotCorrectlyParametrized.nestml +########################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoConvolveNotCorrectlyParametrized: - initial_values: + state: V_m mV = 10mV end @@ -35,6 +41,6 @@ neuron CoCoConvolveNotCorrectlyParametrized: end input: - spikeExc integer <- excitatory spike + spikeExc integer <- excitatory spike end end diff --git a/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml b/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml index 327fb2027..f632d9e5b 100644 --- a/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml +++ b/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml @@ -1,37 +1,41 @@ -/** - * - * CoCoConvolveNotCorrectlyProvided.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly - * provided with a initial_block variable and a spike buffer. - * Negative case. -*/ +""" +CoCoConvolveNotCorrectlyProvided.nestml +####################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoConvolveNotCorrectlyProvided: - state: - g_ex mV = 10mV - end - initial_values: + state: V_m mV = 10mV + g_ex mV = 10mV end equations: @@ -43,4 +47,8 @@ neuron CoCoConvolveNotCorrectlyProvided: input: spikeExc integer <- excitatory spike end + + update: + integrate_odes() + end end diff --git a/tests/invalid/CoCoCurrentBufferQualifierSpecified.nestml b/tests/invalid/CoCoCurrentBufferQualifierSpecified.nestml deleted file mode 100644 index 4638d8cd4..000000000 --- a/tests/invalid/CoCoCurrentBufferQualifierSpecified.nestml +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * CoCoCurrentBufferQualifierSpecified.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if current buffers are not specified by - * keywords. - * Negative case. -*/ - -neuron CoCoCurrentBufferQualifierSpecified: - input: - currents pA <- inhibitory current # qualifiers may not be specified for a current buffer - end -end diff --git a/tests/invalid/CoCoEachBlockUnique.nestml b/tests/invalid/CoCoEachBlockUnique.nestml index f70a824be..8ea40937f 100644 --- a/tests/invalid/CoCoEachBlockUnique.nestml +++ b/tests/invalid/CoCoEachBlockUnique.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoEachBlockUnique.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. - * Negative case. -*/ +""" +CoCoEachBlockUnique.nestml +########################## + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoEachBlockUnique: state: test1 integer = 0 diff --git a/tests/invalid/CoCoElementInSameLine.nestml b/tests/invalid/CoCoElementInSameLine.nestml index ceb2e82d2..d08e652a0 100644 --- a/tests/invalid/CoCoElementInSameLine.nestml +++ b/tests/invalid/CoCoElementInSameLine.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoElementInSameLine.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * recursive definition is detected. - * Negative case. -*/ +""" +CoCoElementInSameLine.nestml +############################ + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +recursive definition is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoElementInSameLine: state: test1 integer = test1 # case 1: variable set to value as currently declared diff --git a/tests/invalid/CoCoElementNotDefined.nestml b/tests/invalid/CoCoElementNotDefined.nestml index 88e9a360a..ce2969025 100644 --- a/tests/invalid/CoCoElementNotDefined.nestml +++ b/tests/invalid/CoCoElementNotDefined.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoElementNotDefined.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * definition with not defined references is detected. - * Negative case. -*/ +""" +CoCoElementNotDefined.nestml +############################ + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +definition with not defined references is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoElementNotDefined: state: test1 integer = test2 # case 1: variable set to a not defined value diff --git a/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml b/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml index 1aa4d4f92..aaf5798e1 100644 --- a/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml +++ b/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml @@ -1,30 +1,36 @@ -/** - * - * CoCoFunctionCallNotConsistentWrongArgNumber.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if current buffers are not specified by - * keywords. - * Negative case. -*/ +""" +CoCoFunctionCallNotConsistentWrongArgNumber.nestml +################################################## + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if function calls have the right number of arguments. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoFunctionCallNotConsistentWrongArgNumber: state: test integer = max(1,2,3) # wrong number of args diff --git a/tests/invalid/CoCoFunctionNotUnique.nestml b/tests/invalid/CoCoFunctionNotUnique.nestml index 7136bbd3f..0d44493da 100644 --- a/tests/invalid/CoCoFunctionNotUnique.nestml +++ b/tests/invalid/CoCoFunctionNotUnique.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoFunctionNotUnique.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions - * is detected. - * Negative case. -*/ +""" +CoCoFunctionNotUnique.nestml +############################ + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions +is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoFunctionNotUnique: function delta(Tau_a ms,Tau_b ms) real: # redeclaration should be detected test real = 1 diff --git a/tests/invalid/CoCoFunctionRedeclared.nestml b/tests/invalid/CoCoFunctionRedeclared.nestml index 374beefe0..10ebc4b54 100644 --- a/tests/invalid/CoCoFunctionRedeclared.nestml +++ b/tests/invalid/CoCoFunctionRedeclared.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoFunctionRedeclared.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. - * Here, if redeclaration of functions has been detected. - * Negative case. -*/ +""" +CoCoFunctionRedeclared.nestml +############################# + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. +Here, if redeclaration of functions has been detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoFunctionRedeclared: function max(arg1 integer,arg2 integer) integer: if arg1>arg2: diff --git a/tests/invalid/CoCoIllegalExpression.nestml b/tests/invalid/CoCoIllegalExpression.nestml index bd59247d8..7100ae9bb 100644 --- a/tests/invalid/CoCoIllegalExpression.nestml +++ b/tests/invalid/CoCoIllegalExpression.nestml @@ -1,31 +1,37 @@ -/** - * - * CoCoIllegalExpression.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. - * type(lhs)!= type(rhs) are detected. - * Negative case. - * -*/ +""" +CoCoIllegalExpression.nestml +############################ + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. +type(lhs)!= type(rhs) are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoIllegalExpression: state: test boolean = True diff --git a/tests/invalid/CoCoIncorrectReturnStatement.nestml b/tests/invalid/CoCoIncorrectReturnStatement.nestml index f276ae4d4..0b6442221 100644 --- a/tests/invalid/CoCoIncorrectReturnStatement.nestml +++ b/tests/invalid/CoCoIncorrectReturnStatement.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoIncorrectReturnStatement.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without - * a proper return statement and wrong type are detected. - * Negative case. -*/ +""" +CoCoIncorrectReturnStatement.nestml +################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without +a proper return statement and wrong type are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoIncorrectReturnStatement: function foo() mV: test mV = 10mV diff --git a/tests/invalid/CoCoInitValuesWithoutOde.nestml b/tests/invalid/CoCoInitValuesWithoutOde.nestml index a077955a3..ace9b7dcb 100644 --- a/tests/invalid/CoCoInitValuesWithoutOde.nestml +++ b/tests/invalid/CoCoInitValuesWithoutOde.nestml @@ -1,32 +1,39 @@ -/** - * - * CoCoInitValuesWithoutOde.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode - * declarations are detected. Moreover, if initial values without a right-hand side are detected. - * Negative case. -*/ +""" +CoCoInitValuesWithoutOde.nestml +############################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode +declarations are detected. Moreover, if initial values without a right-hand side are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInitValuesWithoutOde: - initial_values: + state: V_m mV = 10 mV end end diff --git a/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml b/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml index 73c091a8b..278d0fde8 100644 --- a/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml +++ b/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoInlineExpressionHasNoRhs.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. - * - * Negative case. -*/ +""" +CoCoInlineExpressionHasNoRhs.nestml +################################### + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInlineExpressionHasNoRhs: equations: inline V_rest mV # the missing rhs should be detected diff --git a/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml b/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml index a96cd948d..c255ac077 100644 --- a/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml +++ b/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoInlineExpressionWithSeveralLhs.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. - * - * Negative case. -*/ +""" +CoCoInlineExpressionWithSeveralLhs.nestml +######################################### + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInlineExpressionWithSeveralLhs: equations: inline V_rest,V_reset mV = 10mV # several lhs's should be detected diff --git a/tests/invalid/CoCoInputPortWithRedundantTypes.nestml b/tests/invalid/CoCoInputPortWithRedundantTypes.nestml new file mode 100644 index 000000000..0d425cc8b --- /dev/null +++ b/tests/invalid/CoCoInputPortWithRedundantTypes.nestml @@ -0,0 +1,38 @@ +""" +CoCoInputPortWithRedundantTypes.nestml +###################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if each input port is defined uniquely, i.e., no redundant keywords are used. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoInputPortWithRedundantTypes: + input: + spikeInhX2 integer <- inhibitory inhibitory spike # spike redundant keywords used + end +end diff --git a/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml b/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml new file mode 100644 index 000000000..d6189dbe9 --- /dev/null +++ b/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml @@ -0,0 +1,47 @@ +""" +CoCoIntegrateOdesCalledIfEquationsDefined.nestml +################################################ + + +Description ++++++++++++ + +This model is used to test the check that integrate_odes() is called if one or more dynamical equations are defined. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoIntegrateOdesCalledIfEquationsDefined: + state: + x real = 1. + y integer = 0 + end + + equations: + x' = -x / (10 ms) + end + + update: + y = min(x, y) + end +end diff --git a/tests/invalid/CoCoInvariantNotBool.nestml b/tests/invalid/CoCoInvariantNotBool.nestml index ccf1311c1..67745d645 100644 --- a/tests/invalid/CoCoInvariantNotBool.nestml +++ b/tests/invalid/CoCoInvariantNotBool.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoInvariantNotBool.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants - * is detected and invariants are correctly constructed. - * Negative case. -*/ +""" +CoCoInvariantNotBool.nestml +########################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants +is detected and invariants are correctly constructed. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInvariantNotBool: state: V_notBool mV = 10mV [[V_notBool + V_notBool]] # here a non boolean invariant should be detected diff --git a/tests/invalid/CoCoKernelType.nestml b/tests/invalid/CoCoKernelType.nestml index 3b202ade3..15b6b6094 100644 --- a/tests/invalid/CoCoKernelType.nestml +++ b/tests/invalid/CoCoKernelType.nestml @@ -1,38 +1,44 @@ -/** - * - * CoCoKernelCorrectlyTyped.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. - * - * Here, the kernel is defined with an incorrect type. - * - * Negative case -*/ +""" +CoCoKernelCorrectlyTyped.nestml +############################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. + +Here, the kernel is defined with an incorrect type. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoKernelCorrectlyTyped: parameters: tau ms = 10 ms end - initial_values: # variable is now defined in the initial block, thus everything is correct. + state: # variable is now defined in the state block, thus everything is correct. g real = 1 g' ms**-1 = 1 ms**-1 end diff --git a/tests/invalid/CoCoKernelTypeInitialValues.nestml b/tests/invalid/CoCoKernelTypeInitialValues.nestml index 4f609b18e..176ea3ea6 100644 --- a/tests/invalid/CoCoKernelTypeInitialValues.nestml +++ b/tests/invalid/CoCoKernelTypeInitialValues.nestml @@ -1,38 +1,44 @@ -/** - * - * CoCoKernelCorrectlyTyped.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. - * - * Here, the kernel is defined with an incorrect type. - * - * Negative case -*/ +""" +CoCoKernelCorrectlyTyped.nestml +############################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. + +Here, the kernel is defined with an incorrect type. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoKernelCorrectlyTyped: parameters: tau ms = 10 ms end - initial_values: # variable is now defined in the initial block, thus everything is correct. + state: # variable is now defined in the initial block, thus everything is correct. g real = 1 g' real = 1 end diff --git a/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml b/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml index 1949ec00f..c1b0cac2c 100644 --- a/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml +++ b/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoMultipleNeuronsWithEqualName.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name - * are detected. - * Negative case. -*/ +""" +CoCoMultipleNeuronsWithEqualName.nestml +####################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name +are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoMultipleNeuronsWithEqualName: end diff --git a/tests/invalid/CoCoNestNamespaceCollision.nestml b/tests/invalid/CoCoNestNamespaceCollision.nestml index 99ad74b8e..1d8d0b6a9 100644 --- a/tests/invalid/CoCoNestNamespaceCollision.nestml +++ b/tests/invalid/CoCoNestNamespaceCollision.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoNestNamespaceCollision.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace - * is detected. - * Negative case. -*/ +""" +CoCoNestNamespaceCollision.nestml +################################# + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace +is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoNestNamespaceCollision: function handle(Tau_1 mV):# <- function 'handle' already in nest namespace return diff --git a/tests/invalid/CoCoNoOrderOfEquations.nestml b/tests/invalid/CoCoNoOrderOfEquations.nestml index d30a421e2..8dc095838 100644 --- a/tests/invalid/CoCoNoOrderOfEquations.nestml +++ b/tests/invalid/CoCoNoOrderOfEquations.nestml @@ -1,35 +1,46 @@ -/** - * - * CoCoNoOrderOfEquations.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. - * Negative case. -*/ +""" +CoCoNoOrderOfEquations.nestml +############################# + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoNoOrderOfEquations: - initial_values: + state: V_m mV = 10mV end equations: V_m = 10 mV / s # here, we did not specified the order of equation end + + update: + integrate_odes() + end end diff --git a/tests/invalid/CoCoOdeIncorrectlyTyped.nestml b/tests/invalid/CoCoOdeIncorrectlyTyped.nestml index af9d25efe..1e4db948e 100644 --- a/tests/invalid/CoCoOdeIncorrectlyTyped.nestml +++ b/tests/invalid/CoCoOdeIncorrectlyTyped.nestml @@ -1,31 +1,38 @@ -/** - * - * CoCoOdeIncorrectlyTyped.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. - * - * Here, an ODE is defined with incorrect units. - * - * Negative case. -*/ +""" +CoCoOdeIncorrectlyTyped.nestml +############################## + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. + +Here, an ODE is defined with incorrect units. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoOdeIncorrectlyTyped: state: diff --git a/tests/invalid/CoCoOdeVarNotInInitialValues.nestml b/tests/invalid/CoCoOdeVarNotInInitialValues.nestml index bc910fb5a..027df8b41 100644 --- a/tests/invalid/CoCoOdeVarNotInInitialValues.nestml +++ b/tests/invalid/CoCoOdeVarNotInInitialValues.nestml @@ -1,36 +1,50 @@ -/** - * - * CoCoOdeVarNotInInitialValues.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if each buffer is defined uniquely, i.e., - * no redundant keywords are used. - * Negative case. -*/ +""" +CoCoOdeVarNotInInitialValues.nestml +################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if each ODE variable is specified with initial values. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoOdeVarNotInInitialValues: + parameters: + V_m mV = -50 mV + end + state: - V_m mV = 10mV + V_abs mV = 10mV end equations: V_m' = 10 mV / s end + + update: + integrate_odes() + end end diff --git a/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml b/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml index 10a70eabd..ebd2d704b 100644 --- a/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml +++ b/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml @@ -1,56 +1,61 @@ -/** - * - * CoCoOutputPortDefinedIfEmitCall-2.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the output port has the wrong type. Based on the ``iaf_psc_exp`` model at Sep 2020. - * Negative case. -*/ +""" +CoCoOutputPortDefinedIfEmitCall-2.nestml +######################################## + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the output port has the wrong type. Based on the ``iaf_psc_exp`` model at Sep 2020. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron iaf_psc_exp: state: r integer # counts number of tick during the refractory period - end - - initial_values: V_abs mV = 0 mV end equations: - kernel I_kernel_in = exp(-1/tau_syn_in*t) - kernel I_kernel_ex = exp(-1/tau_syn_ex*t) + kernel I_kernel_inh = exp(-t/tau_syn_inh) + kernel I_kernel_exc = exp(-t/tau_syn_exc) recordable inline V_m mV = V_abs + E_L # Membrane potential. - inline I_syn pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + I_e + I_stim + inline I_syn pA = convolve(I_kernel_inh, inh_spikes) + convolve(I_kernel_exc, exc_spikes) + I_e + I_stim V_abs' = -V_abs / tau_m + I_syn / C_m end parameters: - C_m pF = 250 pF # Capacity of the membrane - tau_m ms = 10 ms # Membrane time constant - tau_syn_in ms = 2 ms # Time constant of synaptic current - tau_syn_ex ms = 2 ms # Time constant of synaptic current - t_ref ms = 2 ms # Duration of refractory period - E_L mV = -70 mV # Resting potential + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of synaptic current + tau_syn_exc ms = 2 ms # Time constant of synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential V_reset mV = -70 mV - E_L # reset value of the membrane potential Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!). - # I.e. the real threshold is (E_L_+V_th_) + # I.e. the real threshold is (E_L_+V_th_) # constant external input current I_e pA = 0 pA @@ -61,12 +66,12 @@ neuron iaf_psc_exp: end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end - output: current + output: continuous update: if r == 0: # neuron not refractory, so evolve V diff --git a/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml b/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml index aed01452c..f20b7cefe 100644 --- a/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml +++ b/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml @@ -1,56 +1,61 @@ -/** - * - * CoCoOutputPortDefinedIfEmitCall.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the output port is not defined. Based on the ``iaf_psc_exp`` model at Sep 2020. - * Negative case. -*/ +""" +CoCoOutputPortDefinedIfEmitCall.nestml +###################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the output port is not defined. Based on the ``iaf_psc_exp`` model at Sep 2020. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron iaf_psc_exp: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0 mV end equations: - kernel I_kernel_in = exp(-1/tau_syn_in*t) - kernel I_kernel_ex = exp(-1/tau_syn_ex*t) + kernel I_kernel_inh = exp(-t/tau_syn_inh) + kernel I_kernel_exc = exp(-t/tau_syn_exc) recordable inline V_m mV = V_abs + E_L # Membrane potential. - inline I_syn pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + I_e + I_stim + inline I_syn pA = convolve(I_kernel_inh, inh_spikes) + convolve(I_kernel_exc, exc_spikes) + I_e + I_stim V_abs' = -V_abs / tau_m + I_syn / C_m end parameters: - C_m pF = 250 pF # Capacity of the membrane - tau_m ms = 10 ms # Membrane time constant - tau_syn_in ms = 2 ms # Time constant of synaptic current - tau_syn_ex ms = 2 ms # Time constant of synaptic current - t_ref ms = 2 ms # Duration of refractory period - E_L mV = -70 mV # Resting potential + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of synaptic current + tau_syn_exc ms = 2 ms # Time constant of synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential V_reset mV = -70 mV - E_L # reset value of the membrane potential - Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!). - # I.e. the real threshold is (E_L_+V_th_) + Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!) + # I.e. the real threshold is E_L + Theta # constant external input current I_e pA = 0 pA @@ -61,9 +66,9 @@ neuron iaf_psc_exp: end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end update: diff --git a/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml b/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml index ee7d6473b..75b974f69 100644 --- a/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml +++ b/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoParameterAssignedOutsideBlock.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * assignment of values to parameters outside of parameter blocks is detected. - * Negative case. -*/ +""" +CoCoParameterAssignedOutsideBlock.nestml +######################################## + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +assignment of values to parameters outside of parameter blocks is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoParameterAssignedOutsideBlock: parameters: test mV = 10mV diff --git a/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml b/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml new file mode 100644 index 000000000..2b20173ac --- /dev/null +++ b/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml @@ -0,0 +1,44 @@ +""" +CoCoPrioritiesCorrectlySpecified.nestml +####################################### + + +Description ++++++++++++ + +This model is used to test the sequencing of event handlers in synapse models. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse CoCoPrioritiesCorrectlySpecified: + input: + pre_spikes real <- spike + post_spikes real <- spike + end + + onReceive(pre_spikes, priority=1): + end + + onReceive(post_spikes, priority=1): + end + +end diff --git a/tests/invalid/CoCoResolutionLegallyUsed.nestml b/tests/invalid/CoCoResolutionLegallyUsed.nestml new file mode 100644 index 000000000..6e1dfa718 --- /dev/null +++ b/tests/invalid/CoCoResolutionLegallyUsed.nestml @@ -0,0 +1,49 @@ +""" +CoCoResolutionLegallyUsed.nestml +################################ + + +Description ++++++++++++ + +This model is used to test the use of the predefined ``resolution()`` function. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse CoCoResolutionLegallyUsed: + state: + x real = 0. + end + + equations: + x' = -x / tau + (resolution() / ms**2) + end + + function test(tau ms) real: + w ms = resolution() + return w + end + + parameters: + tau ms = 10 ms + end +end diff --git a/tests/invalid/CoCoSpikeBufferWithoutType.nestml b/tests/invalid/CoCoSpikeBufferWithoutType.nestml deleted file mode 100644 index ef22c44ed..000000000 --- a/tests/invalid/CoCoSpikeBufferWithoutType.nestml +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * CoCoSpikeBufferWithoutType.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if spike buffers without a data-type - * are detected. - * Negative case. -*/ - -neuron CoCoSpikeBufferWithoutType: - input: - spikeAll <- spike # spike buffer type not specified - end -end diff --git a/tests/invalid/CoCoSpikeInputPortWithoutType.nestml b/tests/invalid/CoCoSpikeInputPortWithoutType.nestml new file mode 100644 index 000000000..5d71782c1 --- /dev/null +++ b/tests/invalid/CoCoSpikeInputPortWithoutType.nestml @@ -0,0 +1,38 @@ +""" +CoCoSpikeInputPortWithoutType.nestml +#################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if spike input ports without a data-type are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoSpikeInputPortWithoutType: + input: + spikeAll <- spike # type not specified + end +end diff --git a/tests/invalid/CoCoStateVariablesInitialized.nestml b/tests/invalid/CoCoStateVariablesInitialized.nestml new file mode 100644 index 000000000..8e2b4d5cf --- /dev/null +++ b/tests/invalid/CoCoStateVariablesInitialized.nestml @@ -0,0 +1,39 @@ +""" +CoCoStateVariablesInitialized.nestml +#################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if initial values are provided for all state variables declared in the ``state`` block. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoStateVariablesInitialized: + state: + V_m mV + V_abs mV = 10 mV + r integer + end +end diff --git a/tests/invalid/CoCoSynsOneBuffer.nestml b/tests/invalid/CoCoSynsOneBuffer.nestml new file mode 100644 index 000000000..d386190f1 --- /dev/null +++ b/tests/invalid/CoCoSynsOneBuffer.nestml @@ -0,0 +1,88 @@ +""" +CoCoSynsOneBuffer.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether each synapse +uses exactly one buffer + +Here the AMPA synapse uses one buffer: spikesAMPA +but the AMPA_NMDA synapse uses two buffers: spikesExc and spikesAMPA + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron cm_syns_model_one_invalid: + + state: + + # the presence of the state variable [v_comp] + # triggers compartment model context + v_comp real = 0 + + end + + + parameters: + + ### synapses ### + e_AMPA real = 0.0 + tau_syn_AMPA real = 0.2 + + e_NMDA real = 0.0 + tau_syn_NMDA real = 0.2 # Synaptic Time Constant Excitatory Synapse + + NMDA_ratio_ real = 2.0 + + end + + equations: + + ### synapses ### + + kernel g_ex_AMPA = exp(-t / tau_syn_AMPA) + inline AMPA real = convolve(g_ex_AMPA, spikesAMPA) * (v_comp - e_AMPA) + + kernel g_ex_NMDA = exp(-t / tau_syn_NMDA) + inline AMPA_NMDA real = convolve(g_ex_NMDA, spikesAMPA) * (v_comp - e_NMDA) + NMDA_ratio_ * convolve(g_ex_AMPA, spikesExc) * (v_comp - e_AMPA) + + end + + internals: + + end + + input: + spikesExc nS <- excitatory spike + spikesAMPA ns <- excitatory spike + end + + output: spike + + update: + end + +end \ No newline at end of file diff --git a/tests/invalid/CoCoUnitNumeratorNotOne.nestml b/tests/invalid/CoCoUnitNumeratorNotOne.nestml index 3c2711476..e03a9842d 100644 --- a/tests/invalid/CoCoUnitNumeratorNotOne.nestml +++ b/tests/invalid/CoCoUnitNumeratorNotOne.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoUnitNumeratorNotOne.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the - * incorrect numerator of the unit is detected. - * Negative case. -*/ +""" +CoCoUnitNumeratorNotOne.nestml +############################## + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the +incorrect numerator of the unit is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoUnitNumeratorNotOne: state: test1 2/s = 10 / s diff --git a/tests/invalid/CoCoValueAssignedToBuffer.nestml b/tests/invalid/CoCoValueAssignedToBuffer.nestml deleted file mode 100644 index 73c05ae08..000000000 --- a/tests/invalid/CoCoValueAssignedToBuffer.nestml +++ /dev/null @@ -1,36 +0,0 @@ -/** - * - * CoCoValueAssignedToBuffer.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to buffers - * is detected. - * Negative case. -*/ - -neuron CoCoValueAssignedToBuffer: - input: - spikeInh integer <- inhibitory spike - end - - update: - spikeInh = 10 - end -end diff --git a/tests/invalid/CoCoValueAssignedToInputPort.nestml b/tests/invalid/CoCoValueAssignedToInputPort.nestml new file mode 100644 index 000000000..ee635ab09 --- /dev/null +++ b/tests/invalid/CoCoValueAssignedToInputPort.nestml @@ -0,0 +1,42 @@ +""" +CoCoValueAssignedToInputPort.nestml +################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to input ports is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoValueAssignedToInputPort: + input: + spikeInh integer <- inhibitory spike + end + + update: + spikeInh = 10 + end +end diff --git a/tests/invalid/CoCoVariableDefinedAfterUsage.nestml b/tests/invalid/CoCoVariableDefinedAfterUsage.nestml index 7b383319e..ab6c49402 100644 --- a/tests/invalid/CoCoVariableDefinedAfterUsage.nestml +++ b/tests/invalid/CoCoVariableDefinedAfterUsage.nestml @@ -1,36 +1,43 @@ -/** - * - * CoCoVariableDefinedAfterUsage.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. - * Negative case. -*/ +""" +CoCoVariableDefinedAfterUsage.nestml +#################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableDefinedAfterUsage: - update: - test1 = test2 + test1 + state: + test2 integer = 10 end - state: - test1 integer = 10 [[test1 < 10]] - test2 integer = test1 + update: + test1 = test2 + test1 integer = 20 end end diff --git a/tests/invalid/CoCoVariableNotDefined.nestml b/tests/invalid/CoCoVariableNotDefined.nestml index 68dcb3311..d6e020fac 100644 --- a/tests/invalid/CoCoVariableNotDefined.nestml +++ b/tests/invalid/CoCoVariableNotDefined.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoVariableNotDefined.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. - * Negative case. -*/ +""" +CoCoVariableNotDefined.nestml +############################# + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableNotDefined: update: test1 = test2 + 1 diff --git a/tests/invalid/CoCoVariableRedeclared.nestml b/tests/invalid/CoCoVariableRedeclared.nestml index 5bb870454..158216656 100644 --- a/tests/invalid/CoCoVariableRedeclared.nestml +++ b/tests/invalid/CoCoVariableRedeclared.nestml @@ -1,28 +1,36 @@ -/** - * - * CoCoVariableRedeclared.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. - * Negative case. -*/ +""" +CoCoVariableRedeclared.nestml +############################# + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableRedeclared: state: test1 mV = 20mV # should not be detected as redeclared, since in global scope diff --git a/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml b/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml index 90410ac32..cf7852f8b 100644 --- a/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml +++ b/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoVariableRedeclaredInSameScope.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * a variable has been redeclared in a single scope. - * Negative case. -*/ +""" +CoCoVariableRedeclaredInSameScope.nestml +######################################## + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +a variable has been redeclared in a single scope. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableRedeclaredInSameScope: state: test1 integer = 10 diff --git a/tests/invalid/CoCoVectorDeclarationSize.nestml b/tests/invalid/CoCoVectorDeclarationSize.nestml new file mode 100644 index 000000000..097a06be4 --- /dev/null +++ b/tests/invalid/CoCoVectorDeclarationSize.nestml @@ -0,0 +1,45 @@ +""" +CoCoVectorParameterSize.nestml +############################## + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. +Here, if the vector parameter or the size of the vector is greater than 0. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron CoCoVectorParameterSize: + state: + V_m [0] mV = -10. mV + end + + parameters: + N integer = -12 + coeff [N] real = 0 + end +end diff --git a/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml b/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml index df412c7ad..caa8e66ff 100644 --- a/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml +++ b/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml @@ -1,34 +1,43 @@ -/** - * - * CoCoVectorInNonVectorDeclaration.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration - * are detected. - * Negative case. -*/ +""" +CoCoVectorInNonVectorDeclaration.nestml +####################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration +are detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVectorInNonVectorDeclaration: state: - ten integer = 10 - g_ex mV [ten] = 10mV + g_ex [ten] mV = 10mV g_in mV = 10mV + g_ex end + parameters: + ten integer = 10 + end end diff --git a/tests/invalid/CoCoVectorParameterDeclaration.nestml b/tests/invalid/CoCoVectorParameterDeclaration.nestml new file mode 100644 index 000000000..341d37138 --- /dev/null +++ b/tests/invalid/CoCoVectorParameterDeclaration.nestml @@ -0,0 +1,41 @@ +""" +CoCoVectorParameterDeclaration.nestml +##################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. +Here, if the vector parameter is declared in the correct block. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron CoCoVectorParameterDeclaration: + state: + size integer = 20 + v_m [size] mV = -55 mV + end +end diff --git a/tests/invalid/CoCoVectorParameterType.nestml b/tests/invalid/CoCoVectorParameterType.nestml new file mode 100644 index 000000000..39d443832 --- /dev/null +++ b/tests/invalid/CoCoVectorParameterType.nestml @@ -0,0 +1,54 @@ +""" +CoCoVectorParameterType.nestml +############################## + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. +Here, if the vector parameter is of the type integer. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron CoCoVectorParameterType: + state: + v_m [size] mV = -55 mV + y [size_y] real = 1.5 + end + + parameters: + size integer = 20 + end + + internals: + size_y real = 5. + end + + update: + i real = 2. + v_m [i] = 11.2 mV + end +end diff --git a/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml b/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml new file mode 100644 index 000000000..772dc58a6 --- /dev/null +++ b/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml @@ -0,0 +1,38 @@ +""" +CompoundOperatorWithDifferentButCompatibleUnits.nestml +###################################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CompoundOperatorTest: + state: + lhs V = 1 V + end + + update: + lhs *= 1 nA + lhs /= 1 m + lhs *= (1. mA) * (1 Ohm) + lhs += 1 A + lhs -= 1 nS + end +end diff --git a/tests/invalid/DocstringCommentTest.nestml b/tests/invalid/DocstringCommentTest.nestml new file mode 100644 index 000000000..788c92add --- /dev/null +++ b/tests/invalid/DocstringCommentTest.nestml @@ -0,0 +1,42 @@ +""" +DocstringCommentTest.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether docstring comments are detected at any place other than just before the neuron keyword. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron docstringCommentTest: + state: + """hello""" + # foo + test boolean = True #inline comment ok + # foo + # bar + end +end diff --git a/tests/lexer_parser_test.py b/tests/lexer_parser_test.py index ae0c23e56..b5d35696e 100644 --- a/tests/lexer_parser_test.py +++ b/tests/lexer_parser_test.py @@ -19,11 +19,12 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . - +import glob import os import unittest from antlr4 import * +from antlr4.error.ErrorStrategy import BailErrorStrategy, DefaultErrorStrategy from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.generated.PyNestMLParser import PyNestMLParser @@ -35,21 +36,30 @@ class LexerParserTest(unittest.TestCase): """ def test(self): - for filename in os.listdir( - os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join('..', 'models')))): - if filename.endswith(".nestml"): - input_file = FileStream( - os.path.join(os.path.dirname(__file__), os.path.join(os.path.join('..', 'models'), filename))) - # print('Start parsing ' + filename), - lexer = PyNestMLLexer(input_file) - # create a token stream - stream = CommonTokenStream(lexer) - # parse the file - tree = PyNestMLParser(stream) - # print(' ...done') - self.assertTrue(tree is not None) - return - - -if __name__ == '__main__': + model_files = [] + for dir in ["models", + os.path.join("tests", "nest_tests", "resources"), + os.path.join("tests", "valid")]: + model_files += glob.glob(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(os.pardir, dir, "*.nestml")))) + + assert len(model_files) > 0 + + for filename in model_files: + print("Processing " + os.path.basename(filename)) + input_file = FileStream(filename) + lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream + stream = CommonTokenStream(lexer) + stream.fill() + # parse the file + parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + compilation_unit = parser.nestMLCompilationUnit() + assert compilation_unit is not None + + +if __name__ == "__main__": unittest.main() diff --git a/tests/nest_tests/compartmental_model_test.py b/tests/nest_tests/compartmental_model_test.py new file mode 100644 index 000000000..b8d390d9e --- /dev/null +++ b/tests/nest_tests/compartmental_model_test.py @@ -0,0 +1,533 @@ +# -*- coding: utf-8 -*- +# +# compartmental_model_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_compartmental_target + +try: + import matplotlib + import matplotlib.pyplot as plt + TEST_PLOTS = True +except BaseException: + TEST_PLOTS = False + +TEST_PLOTS = False +nest_version = NESTTools.detect_nest_version() + +dt = .001 + +soma_params = { + # passive parameters + 'C_m': 89.245535, # pF + 'g_C': 0.0, # soma has no parent + 'g_L': 8.924572508, # nS + 'e_L': -75.0, + # E-type specific + 'gbar_Na': 4608.698576715, # nS + 'e_Na': 60., + 'gbar_K': 956.112772900, # nS + 'e_K': -90. +} +dend_params_passive = { + # passive parameters + 'C_m': 1.929929, + 'g_C': 1.255439494, + 'g_L': 0.192992878, + 'e_L': -75.0, + # by default, active conducances are set to zero, so we don't need to specify + # them explicitely +} +dend_params_active = { + # passive parameters + 'C_m': 1.929929, # pF + 'g_C': 1.255439494, # nS + 'g_L': 0.192992878, # nS + 'e_L': -70.0, # mV + # E-type specific + 'gbar_Na': 17.203212493, # nS + 'e_Na': 60., # mV + 'gbar_K': 11.887347450, # nS + 'e_K': -90. # mV +} + + +class CMTest(unittest.TestCase): + + def reset_nest(self): + nest.ResetKernel() + nest.SetKernelStatus(dict(resolution=dt)) + + def install_nestml_model(self): + tests_path = os.path.realpath(os.path.dirname(__file__)) + input_path = os.path.join( + tests_path, + "resources", + "cm_default.nestml" + ) + target_path = os.path.join( + tests_path, + "target/" + ) + + if not os.path.exists(target_path): + os.makedirs(target_path) + + print( + f"Compiled nestml model 'cm_main_cm_default_nestml' not found, installing in:" + f" {target_path}" + ) + + """generate_nest_compartmental_target( + input_path=input_path, + target_path=os.path.join(target_path, "compartmental_model/"), + module_name="cm_defaultmodule", + suffix="_nestml", + logging_level="DEBUG" + )""" + + def get_model(self, reinstall_flag=True): + print("\n!!!!!!!!\nnestml_flag =", self.nestml_flag, "\n!!!!!!!!!\n") + if self.nestml_flag: + try: + if reinstall_flag: + raise AssertionError + + nest.Install("cm_defaultmodule") + + except (nest.NESTError, AssertionError) as e: + self.install_nestml_model() + + nest.Install("cm_defaultmodule") + + cm_act = nest.Create("cm_default_nestml") + cm_pas = nest.Create("cm_default_nestml") + + print("\n!!!!!!!!\nReturning NESTML model\n!!!!!!!!!\n") + + else: + # models built into NEST Simulator + cm_pas = nest.Create('cm_default') + cm_act = nest.Create('cm_default') + + print("\n!!!!!!!!\nReturning NEST model\n!!!!!!!!!\n") + + return cm_act, cm_pas + + def get_rec_list(self): + if self.nestml_flag: + return ['v_comp0', 'v_comp1', + 'm_Na_0', 'h_Na_0', 'n_K_0', 'm_Na_1', 'h_Na_1', 'n_K_1', + 'g_AN_AMPA_1', 'g_AN_NMDA_1'] + else: + return [ + 'v_comp0', + 'v_comp1', + 'm_Na_0', + 'h_Na_0', + 'n_K_0', + 'm_Na_1', + 'h_Na_1', + 'n_K_1', + 'g_r_AN_AMPA_1', + 'g_d_AN_AMPA_1', + 'g_r_AN_NMDA_1', + 'g_d_AN_NMDA_1'] + + def run_model(self): + self.reset_nest() + cm_act, cm_pas = self.get_model() + + # create a neuron model with a passive dendritic compartment + cm_pas.compartments = [ + {"parent_idx": -1, "params": soma_params}, + {"parent_idx": 0, "params": dend_params_passive} + ] + + # create a neuron model with an active dendritic compartment + cm_act.compartments = [ + {"parent_idx": -1, "params": soma_params}, + {"parent_idx": 0, "params": dend_params_active} + ] + + # set spike thresholds + cm_pas.V_th = -50. + cm_act.V_th = -50. + + # add somatic and dendritic receptor to passive dendrite model + cm_pas.receptors = [ + {"comp_idx": 0, "receptor_type": "AMPA_NMDA"}, + {"comp_idx": 1, "receptor_type": "AMPA_NMDA"} + ] + syn_idx_soma_pas = 0 + syn_idx_dend_pas = 1 + + # add somatic and dendritic receptor to active dendrite model + cm_act.receptors = [ + {"comp_idx": 0, "receptor_type": "AMPA_NMDA"}, + {"comp_idx": 1, "receptor_type": "AMPA_NMDA"} + ] + syn_idx_soma_act = 0 + syn_idx_dend_act = 1 + + # create a two spike generators + sg_soma = nest.Create('spike_generator', 1, { + 'spike_times': [10., 13., 16.]}) + sg_dend = nest.Create('spike_generator', 1, { + 'spike_times': [70., 73., 76.]}) + + # connect spike generators to passive dendrite model (weight in nS) + nest.Connect( + sg_soma, + cm_pas, + syn_spec={ + 'synapse_model': 'static_synapse', + 'weight': 5., + 'delay': .5, + 'receptor_type': syn_idx_soma_pas}) + nest.Connect( + sg_dend, + cm_pas, + syn_spec={ + 'synapse_model': 'static_synapse', + 'weight': 2., + 'delay': .5, + 'receptor_type': syn_idx_dend_pas}) + # connect spike generators to active dendrite model (weight in nS) + nest.Connect( + sg_soma, + cm_act, + syn_spec={ + 'synapse_model': 'static_synapse', + 'weight': 5., + 'delay': .5, + 'receptor_type': syn_idx_soma_act}) + nest.Connect( + sg_dend, + cm_act, + syn_spec={ + 'synapse_model': 'static_synapse', + 'weight': 2., + 'delay': .5, + 'receptor_type': syn_idx_dend_act}) + + # create multimeters to record state variables + rec_list = self.get_rec_list() + print("\n!!!!!!!!\n", rec_list, "\n!!!!!!!!!\n") + mm_pas = nest.Create('multimeter', 1, {'record_from': rec_list, 'interval': dt}) + mm_act = nest.Create('multimeter', 1, {'record_from': rec_list, 'interval': dt}) + # connect the multimeters to the respective neurons + nest.Connect(mm_pas, cm_pas) + nest.Connect(mm_act, cm_act) + + # simulate the models + nest.Simulate(160.) + res_pas = nest.GetStatus(mm_pas, 'events')[0] + res_act = nest.GetStatus(mm_act, 'events')[0] + + return res_act, res_pas + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_compartmental_model(self): + self.nestml_flag = False + recordables_nest = self.get_rec_list() + res_act_nest, res_pas_nest = self.run_model() + + self.nestml_flag = True + recordables_nestml = self.get_rec_list() + res_act_nestml, res_pas_nestml = self.run_model() + + # check if voltages, ion channels state variables are equal + for var_nest, var_nestml in zip( + recordables_nest[:8], recordables_nestml[:8]): + self.assertTrue(np.allclose( + res_act_nest[var_nest], res_act_nestml[var_nestml], atol=5e-1)) + + # check if synaptic conductances are equal + self.assertTrue( + np.allclose( + res_act_nest['g_r_AN_AMPA_1'] + res_act_nest['g_d_AN_AMPA_1'], + res_act_nestml['g_AN_AMPA_1'], + 5e-3)) + self.assertTrue( + np.allclose( + res_act_nest['g_r_AN_NMDA_1'] + res_act_nest['g_d_AN_NMDA_1'], + res_act_nestml['g_AN_NMDA_1'], + 5e-3)) + + if TEST_PLOTS: + w_legends = False + + plt.figure('voltage', figsize=(6, 6)) + # NEST + # plot voltage for somatic compartment + ax_soma = plt.subplot(221) + ax_soma.set_title('NEST') + ax_soma.plot( + res_pas_nest['times'], + res_pas_nest['v_comp0'], + c='b', + label='passive dend') + ax_soma.plot(res_act_nest['times'], res_act_nest['v_comp0'], + c='b', ls='--', lw=2., label='active dend') + ax_soma.set_xlabel(r'$t$ (ms)') + ax_soma.set_ylabel(r'$v_{soma}$ (mV)') + ax_soma.set_ylim((-90., 40.)) + if w_legends: + ax_soma.legend(loc=0) + # plot voltage for dendritic compartment + ax_dend = plt.subplot(222) + ax_dend.set_title('NEST') + ax_dend.plot( + res_pas_nest['times'], + res_pas_nest['v_comp1'], + c='r', + label='passive dend') + ax_dend.plot(res_act_nest['times'], res_act_nest['v_comp1'], + c='r', ls='--', lw=2., label='active dend') + ax_dend.set_xlabel(r'$t$ (ms)') + ax_dend.set_ylabel(r'$v_{dend}$ (mV)') + ax_dend.set_ylim((-90., 40.)) + if w_legends: + ax_dend.legend(loc=0) + + # NESTML + # plot voltage for somatic compartment + ax_soma = plt.subplot(223) + ax_soma.set_title('NESTML') + ax_soma.plot( + res_pas_nestml['times'], + res_pas_nestml['v_comp0'], + c='b', + label='passive dend') + ax_soma.plot(res_act_nestml['times'], res_act_nestml['v_comp0'], + c='b', ls='--', lw=2., label='active dend') + ax_soma.set_xlabel(r'$t$ (ms)') + ax_soma.set_ylabel(r'$v_{soma}$ (mV)') + ax_soma.set_ylim((-90., 40.)) + if w_legends: + ax_soma.legend(loc=0) + # plot voltage for dendritic compartment + ax_dend = plt.subplot(224) + ax_dend.set_title('NESTML') + ax_dend.plot( + res_pas_nestml['times'], + res_pas_nestml['v_comp1'], + c='r', + label='passive dend') + ax_dend.plot(res_act_nestml['times'], res_act_nestml['v_comp1'], + c='r', ls='--', lw=2., label='active dend') + ax_dend.set_xlabel(r'$t$ (ms)') + ax_dend.set_ylabel(r'$v_{dend}$ (mV)') + ax_dend.set_ylim((-90., 40.)) + if w_legends: + ax_dend.legend(loc=0) + + plt.figure('channel state variables', figsize=(6, 6)) + # NEST + # plot traces for somatic compartment + ax_soma = plt.subplot(221) + ax_soma.set_title('NEST') + ax_soma.plot( + res_pas_nest['times'], + res_pas_nest['m_Na_0'], + c='b', + label='m_Na passive dend') + ax_soma.plot( + res_pas_nest['times'], + res_pas_nest['h_Na_0'], + c='r', + label='h_Na passive dend') + ax_soma.plot( + res_pas_nest['times'], + res_pas_nest['n_K_0'], + c='g', + label='n_K passive dend') + ax_soma.plot(res_act_nest['times'], res_act_nest['m_Na_0'], + c='b', ls='--', lw=2., label='m_Na active dend') + ax_soma.plot(res_act_nest['times'], res_act_nest['h_Na_0'], + c='r', ls='--', lw=2., label='h_Na active dend') + ax_soma.plot(res_act_nest['times'], res_act_nest['n_K_0'], + c='g', ls='--', lw=2., label='n_K active dend') + ax_soma.set_xlabel(r'$t$ (ms)') + ax_soma.set_ylabel(r'svar') + ax_soma.set_ylim((0., 1.)) + if w_legends: + ax_soma.legend(loc=0) + # plot voltage for dendritic compartment + ax_dend = plt.subplot(222) + ax_dend.set_title('NEST') + ax_dend.plot( + res_pas_nest['times'], + res_pas_nest['m_Na_1'], + c='b', + label='m_Na passive dend') + ax_dend.plot( + res_pas_nest['times'], + res_pas_nest['h_Na_1'], + c='r', + label='h_Na passive dend') + ax_dend.plot( + res_pas_nest['times'], + res_pas_nest['n_K_1'], + c='g', + label='n_K passive dend') + ax_dend.plot(res_act_nest['times'], res_act_nest['m_Na_1'], + c='b', ls='--', lw=2., label='m_Na active dend') + ax_dend.plot(res_act_nest['times'], res_act_nest['h_Na_1'], + c='r', ls='--', lw=2., label='h_Na active dend') + ax_dend.plot(res_act_nest['times'], res_act_nest['n_K_1'], + c='g', ls='--', lw=2., label='n_K active dend') + ax_dend.set_xlabel(r'$t$ (ms)') + ax_dend.set_ylabel(r'svar') + ax_dend.set_ylim((0., 1.)) + if w_legends: + ax_dend.legend(loc=0) + + # NESTML + # plot traces for somatic compartment + ax_soma = plt.subplot(223) + ax_soma.set_title('NESTML') + ax_soma.plot( + res_pas_nestml['times'], + res_pas_nestml['m_Na_0'], + c='b', + label='m_Na passive dend') + ax_soma.plot( + res_pas_nestml['times'], + res_pas_nestml['h_Na_0'], + c='r', + label='h_Na passive dend') + ax_soma.plot( + res_pas_nestml['times'], + res_pas_nestml['n_K_0'], + c='g', + label='n_K passive dend') + ax_soma.plot(res_act_nestml['times'], res_act_nestml['m_Na_0'], + c='b', ls='--', lw=2., label='m_Na active dend') + ax_soma.plot(res_act_nestml['times'], res_act_nestml['h_Na_0'], + c='r', ls='--', lw=2., label='h_Na active dend') + ax_soma.plot(res_act_nestml['times'], res_act_nestml['n_K_0'], + c='g', ls='--', lw=2., label='n_K active dend') + ax_soma.set_xlabel(r'$t$ (ms)') + ax_soma.set_ylabel(r'svar') + ax_soma.set_ylim((0., 1.)) + if w_legends: + ax_soma.legend(loc=0) + # plot voltage for dendritic compartment + ax_dend = plt.subplot(224) + ax_dend.set_title('NESTML') + ax_dend.plot( + res_pas_nestml['times'], + res_pas_nestml['m_Na1'], + c='b', + label='m_Na passive dend') + ax_dend.plot( + res_pas_nestml['times'], + res_pas_nestml['h_Na1'], + c='r', + label='h_Na passive dend') + ax_dend.plot( + res_pas_nestml['times'], + res_pas_nestml['n_K1'], + c='g', + label='n_K passive dend') + ax_dend.plot(res_act_nestml['times'], res_act_nestml['m_Na1'], + c='b', ls='--', lw=2., label='m_Na active dend') + ax_dend.plot(res_act_nestml['times'], res_act_nestml['h_Na1'], + c='r', ls='--', lw=2., label='h_Na active dend') + ax_dend.plot(res_act_nestml['times'], res_act_nestml['n_K1'], + c='g', ls='--', lw=2., label='n_K active dend') + ax_dend.set_xlabel(r'$t$ (ms)') + ax_dend.set_ylabel(r'svar') + ax_dend.set_ylim((0., 1.)) + if w_legends: + ax_dend.legend(loc=0) + + plt.figure('dendritic synapse conductances', figsize=(3, 6)) + # NEST + # plot traces for dendritic compartment + ax_dend = plt.subplot(211) + ax_dend.set_title('NEST') + ax_dend.plot( + res_pas_nest['times'], + res_pas_nest['g_r_AN_AMPA_1'] + res_pas_nest['g_d_AN_AMPA_1'], + c='b', + label='AMPA passive dend') + ax_dend.plot( + res_pas_nest['times'], + res_pas_nest['g_r_AN_NMDA_1'] + res_pas_nest['g_d_AN_NMDA_1'], + c='r', + label='NMDA passive dend') + ax_dend.plot( + res_act_nest['times'], + res_act_nest['g_r_AN_AMPA_1'] + res_act_nest['g_d_AN_AMPA_1'], + c='b', + ls='--', + lw=2., + label='AMPA active dend') + ax_dend.plot( + res_act_nest['times'], + res_act_nest['g_r_AN_NMDA_1'] + res_act_nest['g_d_AN_NMDA_1'], + c='r', + ls='--', + lw=2., + label='NMDA active dend') + ax_dend.set_xlabel(r'$t$ (ms)') + ax_dend.set_ylabel(r'$g_{syn1}$ (uS)') + if w_legends: + ax_dend.legend(loc=0) + # plot traces for dendritic compartment + # NESTML + ax_dend = plt.subplot(212) + ax_dend.set_title('NESTML') + ax_dend.plot( + res_pas_nestml['times'], + res_pas_nestml['g_AN_AMPA_1'], + c='b', + label='AMPA passive dend') + ax_dend.plot( + res_pas_nestml['times'], + res_pas_nestml['g_AN_NMDA_1'], + c='r', + label='NMDA passive dend') + ax_dend.plot(res_act_nestml['times'], res_act_nestml['g_AN_AMPA_1'], + c='b', ls='--', lw=2., label='AMPA active dend') + ax_dend.plot(res_act_nestml['times'], res_act_nestml['g_AN_NMDA_1'], + c='r', ls='--', lw=2., label='NMDA active dend') + ax_dend.set_xlabel(r'$t$ (ms)') + ax_dend.set_ylabel(r'$g_{syn1}$ (uS)') + if w_legends: + ax_dend.legend(loc=0) + + plt.tight_layout() + plt.show() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/nest_tests/expressions_code_generator_test.py b/tests/nest_tests/expressions_code_generator_test.py new file mode 100644 index 000000000..6fc77c571 --- /dev/null +++ b/tests/nest_tests/expressions_code_generator_test.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# expressions_code_generator_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import os +import unittest + +from pynestml.codegeneration.nest_code_generator import NESTCodeGenerator +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.model_parser import ModelParser + + +class ExpressionsCodeGeneratorTest(unittest.TestCase): + + """ + Tests code generated for different types of expressions from NESTML to NEST + """ + + def setUp(self) -> None: + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedFunctions.register_functions() + PredefinedVariables.register_variables() + SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + Logger.init_logger(LoggingLevel.INFO) + + self.target_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, 'target')))) + + def test_expressions(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, 'resources', 'ExpressionTypeTest.nestml')))) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + FrontendConfiguration.parse_config(params) + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator() + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + + def tearDown(self): + import shutil + shutil.rmtree(self.target_path) diff --git a/tests/nest_tests/fir_filter_test.py b/tests/nest_tests/fir_filter_test.py new file mode 100644 index 000000000..64b39ce10 --- /dev/null +++ b/tests/nest_tests/fir_filter_test.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# +# fir_filter_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import nest +import numpy as np + +try: + import matplotlib + import matplotlib.pyplot as plt + + TEST_PLOTS = True +except BaseException: + TEST_PLOTS = False + +import os +import pytest +import scipy +import scipy.signal +import scipy.stats +import unittest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +nest_version = NESTTools.detect_nest_version() + + +class NestFirFilterTest(unittest.TestCase): + r""" + Tests the working of FIR filter model in NEST + """ + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_fir_filter(self): + nestml_model_file = "FIR_filter.nestml" + nestml_model_name = "fir_filter_nestml" + target_path = "/tmp/fir-filter" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + # Generate the NEST code + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", nestml_model_file))) + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + + t_sim = 101. + resolution = 0.1 + + nest.set_verbosity("M_ALL") + nest.Install(module_name) + + nest.ResetKernel() + + # Create a fir_filter node + neuron = nest.Create(nestml_model_name, {"N": 256}) + + # Create a spike generator + spikes = [1.0, 1.0, 1.5, 1.5, 1.5, 6.7, 10.0, 10.5, 10.5, 10.5, 10.5, 11.3, 11.3, 11.4, 11.4, 20., 22.5, 30., + 40., 42., 42., 42., 50.5, 50.5, 75., 88., 93., 93.] + sg = nest.Create("spike_generator", params={"spike_times": spikes}) + nest.Connect(sg, neuron, syn_spec=dict(delay=resolution)) + + # Get N (order of the filter) + n = nest.GetStatus(neuron, "N")[0] + print("N: {}".format(n)) + + # Set filter coefficients + h = self.generate_filter_coefficients(n) + nest.SetStatus(neuron, {"h": h}) + print("h: ", h) + + # Multimeter + multimeter = nest.Create("multimeter") + nest.SetStatus(multimeter, {"interval": resolution}) + multimeter.set({"record_from": ["y"]}) # output of the filter + nest.Connect(multimeter, neuron) + + # Spike recorder + sr = nest.Create("spike_recorder") + nest.Connect(sg, sr) + nest.Connect(neuron, sr) + + # Simulate + nest.Simulate(t_sim) + + # Record from multimeter + events = multimeter.get("events") + y = events["y"] + times = events["times"] + spike_times = nest.GetStatus(sr, keys="events")[0]["times"] + + # Scipy filtering + spikes, bin_edges = np.histogram(spike_times, np.arange(0, t_sim, resolution)) + output = scipy.signal.lfilter(h, 1, spikes) + + # Plots + if TEST_PLOTS: + self.plot_output(spike_times, times, y, title="FIR FILTER (NESTML)", + filename="fir_filter_output_nestml.png") + self.plot_output(spike_times, bin_edges[1:], output, title="FIR FILTER (scipy)", + filename="fir_filter_output_scipy.png") + + np.testing.assert_allclose(y, output) + + def generate_filter_coefficients(self, order: int): + """ + Generate the filter coefficients for the given order + :param order: order of the filter + :return: a list with the coefficients for the filter + """ + Ts = 1E-4 + f_sampling = 1 / Ts + f_cutoff = 50. # [Hz] + f_nyquist = f_sampling // 2 + cutoff = f_cutoff / f_nyquist + + return scipy.signal.firwin(order, cutoff, pass_zero=True) + + def plot_output(self, spike_times, times, y, title="FIR FILTER", filename="fir_filter_output.png"): + """ + Generate the filtered output plot computed via NESTML + :param spike_times: times when spikes occur + :param times: total simualtion time + :param y: output of the filter for the simulation time + :param filename: file name of the plot + :param title: title of the plot + """ + plt.figure() + plt.scatter(spike_times, np.zeros_like(spike_times), label="input", marker="d", color="orange") + plt.plot(times, y, label="filter") + plt.xlabel("Time (ms)") + plt.ylabel("Filter output") + plt.legend() + plt.title(title) + plt.savefig("/tmp/" + filename) diff --git a/tests/nest_tests/nest_biexponential_synapse_kernel_test.py b/tests/nest_tests/nest_biexponential_synapse_kernel_test.py index f43286d6e..7b64ad0a7 100644 --- a/tests/nest_tests/nest_biexponential_synapse_kernel_test.py +++ b/tests/nest_tests/nest_biexponential_synapse_kernel_test.py @@ -22,7 +22,8 @@ import nest import os import unittest -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +from pynestml.frontend.pynestml_frontend import generate_nest_target try: import matplotlib @@ -37,15 +38,14 @@ class NestBiexponentialSynapseTest(unittest.TestCase): def test_biexp_synapse(self): input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname( __file__), "resources", "BiexponentialPostSynapticResponse.nestml"))) - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - target_path = 'target' - logging_level = 'INFO' - module_name = 'nestmlmodule' - store_log = False - suffix = '_nestml' - dev = True - to_nest(input_path, target_path, logging_level, module_name, store_log, suffix, dev) - install_nest(target_path, nest_path) + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) nest.set_verbosity("M_ALL") nest.ResetKernel() @@ -67,11 +67,11 @@ def test_biexp_synapse(self): sg4 = nest.Create("spike_generator", params={"spike_times": [35., 55.]}) nest.Connect(sg3, neuron, syn_spec={"receptor_type": 4, "weight": 1000., "delay": 0.1}) - i_1 = nest.Create('multimeter', params={'record_from': [ - 'g_gap__X__spikeGap', 'g_ex__X__spikeExc', 'g_in__X__spikeInh', 'g_GABA__X__spikeGABA'], 'interval': .1}) + i_1 = nest.Create("multimeter", params={"record_from": [ + "g_gap__X__spikeGap", "g_ex__X__spikeExc", "g_in__X__spikeInh", "g_GABA__X__spikeGABA"], "interval": .1}) nest.Connect(i_1, neuron) - vm_1 = nest.Create('voltmeter') + vm_1 = nest.Create("voltmeter") nest.Connect(vm_1, neuron) # simulate @@ -91,7 +91,6 @@ def test_biexp_synapse(self): MAX_ABS_ERROR = 1E-6 assert abs(final_v_m - -64.2913308548727) < MAX_ABS_ERROR - def plot(self, vm_1, i_1): fig, ax = plt.subplots(nrows=5) diff --git a/tests/nest_codegenerator_test.py b/tests/nest_tests/nest_code_generator_test.py similarity index 66% rename from tests/nest_codegenerator_test.py rename to tests/nest_tests/nest_code_generator_test.py index 23da881c0..2ef6a7404 100644 --- a/tests/nest_codegenerator_test.py +++ b/tests/nest_tests/nest_code_generator_test.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# nest_codegenerator_test.py +# nest_code_generator_test.py # # This file is part of NEST. # @@ -18,18 +18,19 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + +import json import os import unittest -from pynestml.utils.ast_source_location import ASTSourceLocation - -from pynestml.codegeneration.nest_codegenerator import NESTCodeGenerator +from pynestml.codegeneration.nest_code_generator import NESTCodeGenerator from pynestml.frontend.frontend_configuration import FrontendConfiguration from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.predefined_units import PredefinedUnits from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.model_parser import ModelParser @@ -48,11 +49,11 @@ def setUp(self): Logger.init_logger(LoggingLevel.INFO) self.target_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( - os.pardir, 'target')))) + os.pardir, os.pardir, 'target')))) def test_iaf_psc_alpha(self): input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( - os.pardir, 'models', 'iaf_psc_alpha.nestml')))) + os.pardir, os.pardir, 'models', 'neurons', 'iaf_psc_alpha.nestml')))) params = list() params.append('--input_path') @@ -67,11 +68,11 @@ def test_iaf_psc_alpha(self): compilation_unit = ModelParser.parse_model(input_path) nestCodeGenerator = NESTCodeGenerator() - nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list() + compilation_unit.get_synapse_list()) def test_iaf_psc_delta(self): input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( - os.pardir, 'models', 'iaf_psc_delta.nestml')))) + os.pardir, os.pardir, 'models', 'neurons', 'iaf_psc_delta.nestml')))) params = list() params.append('--input_path') @@ -86,11 +87,11 @@ def test_iaf_psc_delta(self): compilation_unit = ModelParser.parse_model(input_path) nestCodeGenerator = NESTCodeGenerator() - nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list() + compilation_unit.get_synapse_list()) def test_iaf_cond_alpha_functional(self): input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( - os.pardir, 'models', 'iaf_cond_alpha.nestml')))) + os.pardir, os.pardir, 'models', 'neurons', 'iaf_cond_alpha.nestml')))) params = list() params.append('--input_path') @@ -109,6 +110,42 @@ def test_iaf_cond_alpha_functional(self): nestCodeGenerator = NESTCodeGenerator() nestCodeGenerator.generate_code(iaf_cond_alpha_functional) + def test_iaf_psc_alpha_with_codegen_opts(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, 'models', 'neurons', 'iaf_psc_alpha.nestml')))) + + code_opts_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join('resources', 'code_options.json')))) + codegen_opts = {"templates": { + "path": "point_neuron", + "model_templates": { + "neuron": ['@NEURON_NAME@.cpp.jinja2', '@NEURON_NAME@.h.jinja2'], + "synapse": [] + }, + "module_templates": ['setup/CMakeLists.txt.jinja2', + 'setup/@MODULE_NAME@.h.jinja2', 'setup/@MODULE_NAME@.cpp.jinja2'] + }} + + with open(code_opts_path, 'w+') as f: + json.dump(codegen_opts, f) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + params.append('--codegen_opts') + params.append(code_opts_path) + FrontendConfiguration.parse_config(params) + + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator(codegen_opts) + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + def tearDown(self): import shutil shutil.rmtree(self.target_path) diff --git a/tests/nest_tests/nest_custom_templates_test.py b/tests/nest_tests/nest_custom_templates_test.py new file mode 100644 index 000000000..bdedff95b --- /dev/null +++ b/tests/nest_tests/nest_custom_templates_test.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# +# nest_custom_templates_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os +import unittest +import pytest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_target + +nest_version = NESTTools.detect_nest_version() + + +class NestCustomTemplatesTest(unittest.TestCase): + """ + Tests the code generation and installation with custom NESTML templates for NEST + """ + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_custom_templates(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, "models", "neurons", "iaf_psc_exp.nestml")))) + target_path = "target" + target_platform = "NEST" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + codegen_opts = {"templates": {"path": "point_neuron", + "model_templates": {"neuron": ["@NEURON_NAME@.cpp.jinja2", "@NEURON_NAME@.h.jinja2"], + "synapse": ["@SYNAPSE_NAME@.h.jinja2"]}, + "module_templates": ["setup/CMakeLists.txt.jinja2", + "setup/@MODULE_NAME@.h.jinja2", "setup/@MODULE_NAME@.cpp.jinja2"]}} + + generate_target(input_path, target_platform, target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix, + codegen_opts=codegen_opts) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install("nestmlmodule") + + nrn = nest.Create("iaf_psc_exp_nestml") + mm = nest.Create("multimeter") + mm.set({"record_from": ["V_m"]}) + + nest.Connect(mm, nrn) + + nest.Simulate(5.0) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_custom_templates_with_synapse(self): + models = ["neurons/iaf_psc_delta.nestml", "synapses/stdp_triplet_naive.nestml"] + input_paths = [os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, "models", fn)))) for fn in models] + target_path = "target" + target_platform = "NEST" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + codegen_opts = { + "neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_delta", + "synapse": "stdp_triplet", + "post_ports": ["post_spikes"]}], + "templates": { + "path": "point_neuron", + "model_templates": { + "neuron": ["@NEURON_NAME@.cpp.jinja2", "@NEURON_NAME@.h.jinja2"], + "synapse": ["@SYNAPSE_NAME@.h.jinja2"] + }, + "module_templates": ["setup/CMakeLists.txt.jinja2", + "setup/@MODULE_NAME@.h.jinja2", "setup/@MODULE_NAME@.cpp.jinja2"] + } + } + + generate_target(input_paths, target_platform, target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix, + codegen_opts=codegen_opts) + nest.set_verbosity("M_ALL") diff --git a/tests/nest_tests/nest_delay_based_variables_test.py b/tests/nest_tests/nest_delay_based_variables_test.py new file mode 100644 index 000000000..1a6542f0d --- /dev/null +++ b/tests/nest_tests/nest_delay_based_variables_test.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +# +# nest_delay_based_variables_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +from typing import List +import pytest + +import nest + +try: + import matplotlib + import matplotlib.pyplot as plt + + TEST_PLOTS = True +except BaseException: + TEST_PLOTS = False + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +nest_version = NESTTools.detect_nest_version() + +target_path = "target_delay" +logging_level = "DEBUG" +suffix = "_nestml" + + +def plot_fig(times, recordable_events_delay: dict, recordable_events: dict, filename: str): + fig, axes = plt.subplots(len(recordable_events), 1, figsize=(7, 9), sharex=True) + for i, recordable_name in enumerate(recordable_events_delay.keys()): + axes[i].plot(times, recordable_events_delay[recordable_name], label=recordable_name + "(delay)") + axes[i].plot(times, recordable_events[recordable_name], label=recordable_name) + axes[i].set_xlabel("times") + axes[i].set_ylabel(recordable_name) + axes[i].legend() + + fig.savefig("/tmp/" + filename) + + +def run_simulation(neuron_model_name: str, module_name: str, recordables: List[str], delay: float): + nest.set_verbosity("M_ALL") + nest.ResetKernel() + + try: + nest.Install(module_name) + except BaseException: + pass + + neuron = nest.Create(neuron_model_name) + neuron.set({"delay": delay}) + + multimeter = nest.Create("multimeter", params={"record_from": recordables}) + nest.Connect(multimeter, neuron) + + nest.Simulate(100.0) + + events = multimeter.get("events") + times = events["times"] + + recordable_events = {} + for recordable in recordables: + recordable_events[recordable] = events[recordable] + + return recordable_events, times + + +@pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") +@pytest.mark.parametrize("file_name, neuron_model_name, recordables", + [("DelayDifferentialEquationsWithAnalyticSolver.nestml", "dde_analytic_nestml", + ["u_bar_plus", "foo"]), + ("DelayDifferentialEquationsWithNumericSolver.nestml", "dde_numeric_nestml", ["x", "z"]), + ("DelayDifferentialEquationsWithMixedSolver.nestml", "dde_mixed_nestml", ["x", "z"])]) +def test_dde_with_analytic_solver(file_name: str, neuron_model_name: str, recordables: List[str]): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", file_name))) + module_name = neuron_model_name + "_module" + print("Module name: ", module_name) + generate_nest_target(input_path=input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + delay = 5 + + # Run the simulation with delay value of 5.0 ms + recordable_events_delay, times = run_simulation(neuron_model_name, module_name, recordables, + delay=delay) + + # Run the simulation with no delay (0 ms) + recordable_events, times = run_simulation(neuron_model_name, module_name, recordables, delay=0) + + if TEST_PLOTS: + plot_fig(times, recordable_events_delay, recordable_events, neuron_model_name + ".png") + + # Assert only the analytical solver case. + # Delayed and non-delayed results for non-linear equations produce completely different results and hence it's + # difficult to perform a direct assert. + if neuron_model_name == "dde_analytic_nestml": + np.testing.assert_allclose(recordable_events_delay[recordables[1]][int(delay):], + recordable_events[recordables[1]][:-int(delay)]) + + @pytest.fixture(scope="function", autouse=True) + def cleanup(self): + # Run the test + yield + + # clean up + import shutil + if self.target_path: + try: + shutil.rmtree(self.target_path) + except Exception: + pass diff --git a/tests/nest_tests/nest_forbidden_variable_names_test.py b/tests/nest_tests/nest_forbidden_variable_names_test.py new file mode 100644 index 000000000..75cef3b97 --- /dev/null +++ b/tests/nest_tests/nest_forbidden_variable_names_test.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# +# nest_forbidden_variable_names_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import nest +import numpy as np +import os +import unittest + +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +class NestForbiddenVariableNamesTest(unittest.TestCase): + r"""Test rewriting of forbidden variable names: in the case of NEST, C++ language keywords.""" + + def test_forbidden_variable_names(self): + input_path = [os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "CppVariableNames.nestml")))] + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install("nestmlmodule") + + nrn = nest.Create("cpp_variable_names_test_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["concept_", "static_"]}) + nest.Connect(mm, nrn) + nest.Simulate(100.0) + nest.SetStatus(nrn, {"using_": 42.}) + + # getting here without exceptions means that the test has passed diff --git a/tests/nest_tests/nest_install_module_in_different_location_test.py b/tests/nest_tests/nest_install_module_in_different_location_test.py new file mode 100644 index 000000000..4402a003e --- /dev/null +++ b/tests/nest_tests/nest_install_module_in_different_location_test.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# +# nest_install_module_in_different_location_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import glob +import nest +import os +import tempfile +import unittest + +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +class NestInstallExistingModule(unittest.TestCase): + """ + Tests installing modules from different location + """ + + def test_installing_module_outside_nest(self): + + model_name = "iaf_psc_exp" + module_name = f"{model_name}module" + + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, "models", "neurons", f"{model_name}.nestml")))) + install_path = tempfile.mkdtemp(prefix="nest_install", suffix="") + target_path = "target" + logging_level = "INFO" + store_log = False + suffix = "_location_test" + dev = True + codegen_opts = {"templates": { + "path": "point_neuron", + "model_templates": { + "neuron": ["@NEURON_NAME@.cpp.jinja2", "@NEURON_NAME@.h.jinja2"], + "synapse": ["@SYNAPSE_NAME@.h.jinja2"] + }, + "module_templates": ["setup/CMakeLists.txt.jinja2", + "setup/@MODULE_NAME@.h.jinja2", "setup/@MODULE_NAME@.cpp.jinja2"] + }} + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + store_log=store_log, + suffix=suffix, + install_path=install_path, + dev=dev, + codegen_opts=codegen_opts) + + expected_found_module = f"{install_path}/{module_name}.so" + actual_found_module = glob.glob(f"{install_path}/*so") + + # check if tmp folder contains only one module + self.assertEqual(len(actual_found_module), 1) + # compare the expected module name with the actual found one + self.assertEqual(actual_found_module[0], expected_found_module) + + # install module + nest.set_verbosity("M_ALL") + nest.ResetKernel() + nest.Install(module_name) + + # check model existence + has_model = f"{model_name}{suffix}" in nest.Models() + self.assertTrue(has_model) + + # delete created folder + import shutil + shutil.rmtree(install_path) diff --git a/tests/nest_tests/nest_instantiability_test.py b/tests/nest_tests/nest_instantiability_test.py index 4d6c4bf5c..b6bc17e8a 100644 --- a/tests/nest_tests/nest_instantiability_test.py +++ b/tests/nest_tests/nest_instantiability_test.py @@ -35,7 +35,7 @@ def strip_suffix(names_list, suffix): class NestInstantiabilityTest(unittest.TestCase): - """Instantiate all the models generated by NESTML and run a NEST simulation. This is used for integration testing in Travis-CI, to ensure that all the generated models can be instantiated. No connectivity or stimuli are defined.""" + """Instantiate all the models generated by NESTML and run a NEST simulation. This is used for integration testing in GitHub Actions CI, to ensure that all the generated models can be instantiated. No connectivity or stimuli are defined.""" def test_nest_instantiability(self): # N.B. all models are assumed to have been already built (see .travis.yml) diff --git a/tests/nest_tests/nest_integration_test.py b/tests/nest_tests/nest_integration_test.py index 5de0f6ef4..44f0571e9 100644 --- a/tests/nest_tests/nest_integration_test.py +++ b/tests/nest_tests/nest_integration_test.py @@ -20,60 +20,120 @@ # along with NEST. If not, see . import copy -import nest import numpy as np import os +import re import unittest -import glob -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target try: import matplotlib import matplotlib.pyplot as plt + TEST_PLOTS = True except BaseException: TEST_PLOTS = False +nest_version = NESTTools.detect_nest_version() + + +def get_model_doc_title(model_fname: str): + with open(model_fname) as f: + model = f.read() + return re.compile(r'\"\"\"[^#]*###').search(model).group()[3:-3].strip() + class NestIntegrationTest(unittest.TestCase): + def generate_all_models(self): + codegen_opts = {"neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "neuromodulated_stdp", + "post_ports": ["post_spikes"], + "vt_ports": ["mod_spikes"]}, + {"neuron": "iaf_psc_exp", + "synapse": "stdp", + "post_ports": ["post_spikes"]}, + {"neuron": "iaf_psc_delta", + "synapse": "stdp_triplet", + "post_ports": ["post_spikes"]}, + {"neuron": "iaf_psc_delta", + "synapse": "stdp_triplet_nn", + "post_ports": ["post_spikes"]}, + {"neuron": "iaf_psc_exp", + "synapse": "stdp_nn_symm", + "post_ports": ["post_spikes"]}, + {"neuron": "iaf_psc_exp", + "synapse": "stdp_nn_restr_symm", + "post_ports": ["post_spikes"]}, + {"neuron": "iaf_psc_exp_dend", + "synapse": "third_factor_stdp", + "post_ports": ["post_spikes", + ["I_post_dend", "I_dend"]]}, + {"neuron": "iaf_psc_exp", + "synapse": "stdp_nn_pre_centered", + "post_ports": ["post_spikes"]}]} + if nest_version.startswith("v3"): + codegen_opts["neuron_parent_class"] = "StructuralPlasticityNode" + codegen_opts["neuron_parent_class_include"] = "structural_plasticity_node.h" + + generate_nest_target(input_path=["models"], + target_path="/tmp/nestml-allmodels", + logging_level="INFO", + module_name="nestml_allmodels_module", + suffix="_nestml", + codegen_opts=codegen_opts) + def test_nest_integration(self): # N.B. all models are assumed to have been already built (see .travis.yml) nest.ResetKernel() nest.set_verbosity("M_ALL") - nest.Install("nestml_allmodels_module") + try: + nest.Install("nestml_allmodels_module") + except Exception: + self.generate_all_models() + nest.Install("nestml_allmodels_module") - models = [] + s = "Models library\n==============\n\n" - models.append(("iaf_psc_delta", "iaf_psc_delta_nestml", None, 1E-3)) - models.append(("iaf_psc_exp", "iaf_psc_exp_nestml", None, .01)) - models.append(("iaf_psc_alpha", "iaf_psc_alpha_nestml", None, 1E-3)) + s += "Neuron models\n~~~~~~~~~~~~~\n\n" - models.append(("iaf_cond_exp", "iaf_cond_exp_nestml", 1E-3, 1E-3)) - models.append(("iaf_cond_alpha", "iaf_cond_alpha_nestml", 1E-3, 1E-3)) - models.append(("iaf_cond_beta", "iaf_cond_beta_nestml", 1E-3, 1E-3, {"tau_rise_ex": 2., "tau_decay_ex": 10., "tau_rise_in": 2., "tau_decay_in": 10.}, {"tau_syn_rise_E": 2., "tau_syn_decay_E": 10., "tau_syn_rise_I": 2., "tau_syn_decay_I": 10.})) # XXX: TODO: does not work yet when tau_rise = tau_fall (numerical singularity occurs in the propagators) + neuron_models = [] - models.append(("izhikevich", "izhikevich_nestml", 1E-3, 1)) # large tolerance because NEST Simulator model does not use GSL solver, but simple forward Euler - models.append(("hh_psc_alpha", "hh_psc_alpha_nestml", 1E-3, 1E-3)) - models.append(("iaf_chxk_2008", "iaf_chxk_2008_nestml", 1E-3, 1E-3)) + neuron_models.append(("iaf_psc_delta", "iaf_psc_delta_nestml", None, 1E-3)) + neuron_models.append(("iaf_psc_exp", "iaf_psc_exp_nestml", None, .01)) + neuron_models.append(("iaf_psc_alpha", "iaf_psc_alpha_nestml", None, 1E-3)) + + neuron_models.append(("iaf_cond_exp", "iaf_cond_exp_nestml", 1E-3, 1E-3)) + neuron_models.append(("iaf_cond_alpha", "iaf_cond_alpha_nestml", 1E-3, 1E-3)) + neuron_models.append(("iaf_cond_beta", "iaf_cond_beta_nestml", 1E-3, 1E-3, + {"tau_rise_ex": 2., "tau_decay_ex": 10., "tau_rise_in": 2., "tau_decay_in": 10.}, + {"tau_syn_rise_E": 2., "tau_syn_decay_E": 10., "tau_syn_rise_I": 2., + "tau_syn_decay_I": 10.})) # XXX: TODO: does not work yet when tau_rise = tau_fall (numerical singularity occurs in the propagators) + + if nest_version.startswith("v2"): + neuron_models.append(("izhikevich", "izhikevich_nestml", 1E-3, 1, {}, {}, {"V_m": -70., "U_m": .2 * -70.})) # large tolerance because NEST Simulator model does not use GSL solver, but simple forward Euler + else: + neuron_models.append(("izhikevich", "izhikevich_nestml", 1E-3, 1)) # large tolerance because NEST Simulator model does not use GSL solver, but simple forward Euler + neuron_models.append(("hh_psc_alpha", "hh_psc_alpha_nestml", 1E-3, 1E-3)) + neuron_models.append(("iaf_chxk_2008", "iaf_chxk_2008_nestml", 1E-3, 1E-3)) + neuron_models.append(("aeif_cond_exp", "aeif_cond_exp_nestml", 1E-3, 1E-3)) + neuron_models.append(("aeif_cond_alpha", "aeif_cond_alpha_nestml", 1E-3, 1E-3)) # -------------- # XXX: TODO! - # models.append(("aeif_cond_alpha", "aeif_cond_alpha_implicit_nestml", 1.e-3, 1E-3)) - # models.append(("aeif_cond_alpha", "aeif_cond_alpha_nestml", 1.e-3, 1E-3)) - # models.append(("aeif_cond_exp", "aeif_cond_exp_implicit_nestml", 1.e-3, 1E-3)) - # models.append(("aeif_cond_exp", "aeif_cond_exp_nestml", 1.e-3, 1E-3)) - # models.append(("hh_cond_exp_traub", "hh_cond_exp_traub_implicit_nestml", 1.e-3, 1E-3)) # models.append(("hh_cond_exp_traub", "hh_cond_exp_traub_nestml", 1.e-3, 1E-3)) # models.append(("ht_neuron", "hill_tononi_nestml", None, 1E-3)) # models.append(("iaf_cond_exp_sfa_rr", "iaf_cond_exp_sfa_rr_nestml", 1.e-3, 1E-3)) - # models.append(("iaf_cond_exp_sfa_rr", "iaf_cond_exp_sfa_rr_implicit_nestml", 1.e-3, 1E-3)) # models.append(("iaf_tum_2000", "iaf_tum_2000_nestml", None, 0.01)) # models.append(("mat2_psc_exp", "mat2_psc_exp_nestml", None, 0.1)) - for model in models: + for model in neuron_models: reference = model[0] testant = model[1] gsl_error_tol = model[2] @@ -82,30 +142,119 @@ def test_nest_integration(self): nest_ref_model_opts = model[4] else: nest_ref_model_opts = None + if len(model) > 5: custom_model_opts = model[5] else: custom_model_opts = None - self._test_model(reference, testant, gsl_error_tol, tolerance, nest_ref_model_opts, custom_model_opts) + if len(model) > 6: + model_initial_state = model[6] + else: + model_initial_state = None + + print("Now testing model: " + str(testant) + " (reference model: " + str(reference) + ")") + self._test_model(reference, testant, gsl_error_tol, tolerance, nest_ref_model_opts, custom_model_opts, model_initial_state) self._test_model_subthreshold(reference, testant, gsl_error_tol, tolerance, - nest_ref_model_opts, custom_model_opts) + nest_ref_model_opts, custom_model_opts, model_initial_state) - all_models = [s[:-7] for s in list(os.walk("models"))[0][2] if s[-7:] == ".nestml"] - self.generate_models_documentation(models, all_models) + all_neuron_models = [s[:-7] for s in list(os.walk("models/neurons"))[0][2] if s[-7:] == ".nestml"] + s += self.generate_neuron_models_documentation(neuron_models, all_neuron_models) - def generate_models_documentation(self, models, allmodels): - """ + s += "Synapse models\n~~~~~~~~~~~~~~\n\n" + + synapse_models = [] + synapse_models.append(("static", "static_synapse.nestml")) + synapse_models.append(("noisy_synapse", "noisy_synapse.nestml")) + synapse_models.append(("stdp", "stdp_synapse.nestml")) + synapse_models.append(("stdp_nn_pre_centered", "stdp_nn_pre_centered.nestml")) + synapse_models.append(("stdp_nn_restr_symm", "stdp_nn_restr_symm.nestml")) + synapse_models.append(("stdp_nn_symm", "stdp_nn_symm.nestml")) + synapse_models.append(("stdp_triplet_nn", "triplet_stdp_synapse.nestml")) + synapse_models.append(("stdp_triplet", "stdp_triplet_naive.nestml")) + synapse_models.append(("third_factor_stdp", "third_factor_stdp_synapse.nestml")) + synapse_models.append(("neuromodulated_stdp", "neuromodulated_stdp.nestml")) + + all_synapse_models = [s[:-7] for s in list(os.walk("models/synapses"))[0][2] if s[-7:] == ".nestml"] + s += self.generate_synapse_models_documentation(synapse_models, all_synapse_models) + + with open('models_library.rst', 'w') as f: + f.write(s) + + def generate_synapse_models_documentation(self, models, allmodels): + r""" allmodels : list of str List of all model file names (e.g. "iaf_psc_exp") found in the models directory. models : list of tuples Tested models and test conditions, in order. """ - s = "Models library\n==============\n\n" - print("allmodels = " + str(allmodels)) + untested_models = copy.deepcopy(allmodels) + for model in models: + model_fname = model[1] + assert model_fname.removesuffix(".nestml") in allmodels + if model_fname in untested_models: + untested_models.remove(model_fname) + print("untested_models = " + str(untested_models)) + + s = "" + + for model in models: + model_name = model[0] + model_fname = model[1] + model_fname_stripped = model_fname.removesuffix(".nestml") + + if model_fname_stripped in untested_models: + untested_models.remove(model_fname_stripped) + + s += "\n" + s += ":doc:`" + model_name + " <" + model_name + ">`" + "\n" + s += "-" * len(":doc:`" + model_name + " <" + model_name + ">`") + "\n" + + model_doc_title = get_model_doc_title(os.path.join("models", "synapses", model_fname)) + if model_doc_title.startswith(model_name): + model_doc_title = model_doc_title.removeprefix(model_name) + model_doc_title = model_doc_title.removeprefix(" - ") + s += "\n" + model_doc_title + "\n" + + s += "\n" + s += "Source file: `" + model_fname + " `_\n" + s += "\n" + + for model_name in untested_models: + testant = model_name + "_nestml" + model_fname = model_name + ".nestml" + + s += "\n" + s += ":doc:`" + model_name + " <" + model_name + ">`" + "\n" + s += "-" * len(":doc:`" + model_name + " <" + model_name + ">`") + "\n" + + model_doc_title = get_model_doc_title(os.path.join("models", "synapses", model_fname)) + if model_doc_title.startswith(model_name): + model_doc_title = model_doc_title.removeprefix(model_name) + model_doc_title = model_doc_title.removeprefix(" - ") + s += "\n" + model_doc_title + "\n" + + s += "\n" + s += "Source file: `" + model_fname + " `_\n" + s += "\n" + + return s + + def generate_neuron_models_documentation(self, models, allmodels): + """ + allmodels : list of str + List of all model file names (e.g. "iaf_psc_exp") found in the models directory. + models : list of tuples + Tested models and test conditions, in order. + """ + + print("All neuron models = " + str(allmodels)) + untested_models = copy.deepcopy(allmodels) for model in models: testant = model[1] @@ -113,7 +262,9 @@ def generate_models_documentation(self, models, allmodels): assert model_name in allmodels or (model_name[-9:] == "_implicit" and model_name[:-9] in allmodels) if model_name in untested_models: untested_models.remove(model_name) - print("untested_models = " + str(untested_models)) + print("Untested neuron models = " + str(untested_models)) + + s = "" for model in models: reference = model[0] @@ -140,35 +291,40 @@ def generate_models_documentation(self, models, allmodels): s += ":doc:`" + model_name + " <" + model_name + ">`" + "\n" s += "-" * len(":doc:`" + model_name + " <" + model_name + ">`") + "\n" - '''s += model_name + "\n" - s += "~" * len(model_name) + "\n" - s += "\n" - s += ":doc:`" + model_name + " <" + testant + ">`" + "\n" - s += "\n"''' + model_doc_title = get_model_doc_title(os.path.join("models", "neurons", model_fname)) + if model_doc_title.startswith(model_name): + model_doc_title = model_doc_title.removeprefix(model_name) + model_doc_title = model_doc_title.removeprefix(" - ") + s += "\n" + model_doc_title + "\n" s += "\n" - s += "Source file: `" + model_fname + " `_\n" + s += "Source file: `" + model_fname + " `_\n" s += "\n" s += ".. list-table::\n" s += "\n" - s += " * - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[" + \ - model_name + "]_synaptic_response_small.png\n" + s += " * - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library" \ + "/nestml_models_library_[" + \ + model_name + "]_synaptic_response_small.png\n" s += " :alt: " + model_name + "\n" s += "\n" - s += " - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[" + \ - model_name + "]_f-I_curve_small.png\n" + s += " - .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library" \ + "/nestml_models_library_[" + \ + model_name + "]_f-I_curve_small.png\n" s += " :alt: " + model_name + "\n" s += "\n" with open(model_name + '_characterisation.rst', 'w') as f: s_ = "Synaptic response\n-----------------\n\n" - s_ += ".. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[" + \ - model_name + "]_synaptic_response.png\n" + s_ += ".. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library" \ + "/nestml_models_library_[" + \ + model_name + "]_synaptic_response.png\n" s_ += " :alt: " + testant + "\n" s_ += "\n" s_ += "f-I curve\n---------\n\n" - s_ += ".. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library/nestml_models_library_[" + \ - model_name + "]_f-I_curve.png\n" + s_ += ".. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/models_library" \ + "/nestml_models_library_[" + \ + model_name + "]_f-I_curve.png\n" s_ += " :alt: " + testant + "\n" s_ += "\n" f.write(s_) @@ -181,15 +337,22 @@ def generate_models_documentation(self, models, allmodels): s += ":doc:`" + model_name + " <" + model_name + ">`" + "\n" s += "-" * len(":doc:`" + model_name + " <" + model_name + ">`") + "\n" + model_doc_title = get_model_doc_title(os.path.join("models", "neurons", model_fname)) + if model_doc_title.startswith(model_name): + model_doc_title = model_doc_title.removeprefix(model_name) + model_doc_title = model_doc_title.removeprefix(" - ") + s += "\n" + model_doc_title + "\n" + s += "\n" - s += "Source file: `" + model_fname + " `_\n" + s += "Source file: `" + model_fname + " `_\n" s += "\n" - with open('models_library.rst', 'w') as f: - f.write(s) + return s - def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001, nest_ref_model_opts=None, custom_model_opts=None): - t_stop = 1000. # [ms] + def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001, + nest_ref_model_opts=None, custom_model_opts=None, model_initial_state=None): + t_stop = 1000. # [ms] I_stim_vec = np.linspace(10E-12, 1E-9, 100) # [A] rate_testant = float("nan") * np.ones_like(I_stim_vec) @@ -199,6 +362,9 @@ def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, toler nest.ResetKernel() neuron1 = nest.Create(referenceModel, params=nest_ref_model_opts) neuron2 = nest.Create(testant, params=custom_model_opts) + if model_initial_state is not None: + nest.SetStatus(neuron1, model_initial_state) + nest.SetStatus(neuron2, model_initial_state) if gsl_error_tol is not None: nest.SetStatus(neuron2, {"gsl_error_tol": gsl_error_tol}) @@ -218,12 +384,18 @@ def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, toler nest.Connect(multimeter1, neuron1) nest.Connect(multimeter2, neuron2) - sd_reference = nest.Create('spike_recorder') + if nest_version.startswith("v2"): + sd_reference = nest.Create('spike_detector') + sd_testant = nest.Create('spike_detector') + else: + sd_reference = nest.Create('spike_recorder') + sd_testant = nest.Create('spike_recorder') + nest.Connect(neuron1, sd_reference) - sd_testant = nest.Create('spike_recorder') nest.Connect(neuron2, sd_testant) nest.Simulate(t_stop) + dmm1 = nest.GetStatus(multimeter1)[0] Vms1 = dmm1["events"][V_m_specifier] ts1 = dmm1["events"]["times"] @@ -232,8 +404,8 @@ def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, toler Vms2 = dmm2["events"][V_m_specifier] ts2 = dmm2["events"]["times"] - rate_testant[i] = sd_testant.n_events / t_stop * 1000 - rate_reference[i] = sd_reference.n_events / t_stop * 1000 + rate_testant[i] = nest.GetStatus(sd_testant)[0]["n_events"] / t_stop * 1000 + rate_reference[i] = nest.GetStatus(sd_reference)[0]["n_events"] / t_stop * 1000 if TEST_PLOTS and False: fig, ax = plt.subplots(2, 1) @@ -244,7 +416,11 @@ def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, toler _ax.grid() fig.suptitle("Rate: " + str(rate_testant[i]) + " Hz") plt.savefig( - "/tmp/nestml_nest_integration_test_subthreshold_[" + referenceModel + "]_[" + testant + "]_[I_stim=" + str(I_stim) + "].png") + "/tmp/nestml_nest_integration_test_subthreshold_[" + referenceModel + "]_[" + testant + "]_[" + "I_stim=" + + str( + I_stim) + "].png") + plt.close(fig) if TEST_PLOTS: if len(I_stim_vec) < 20: @@ -260,6 +436,7 @@ def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, toler _ax.set_ylabel("Firing rate [Hz]") ax[1].set_xlabel("$I_{inj}$ [pA]") plt.savefig("/tmp/nestml_nest_integration_test_subthreshold_[" + referenceModel + "]_[" + testant + "].png") + plt.close(fig) if TEST_PLOTS: if len(I_stim_vec) < 20: @@ -276,10 +453,12 @@ def _test_model_subthreshold(self, referenceModel, testant, gsl_error_tol, toler ax[0].set_xlabel("$I_{inj}$ [pA]") plt.tight_layout() plt.savefig("/tmp/nestml_models_library_[" + referenceModel + "]_f-I_curve" + fname_snip + ".png") + plt.close(fig) print(testant + " PASSED") - def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001, nest_ref_model_opts=None, custom_model_opts=None): + def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001, nest_ref_model_opts=None, + custom_model_opts=None, model_initial_state=None): spike_times = [100.0, 200.0] spike_weights = [1., -1.] @@ -288,8 +467,12 @@ def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001 neuron1 = nest.Create(referenceModel, params=nest_ref_model_opts) neuron2 = nest.Create(testant, params=custom_model_opts) + if model_initial_state is not None: + nest.SetStatus(neuron1, model_initial_state) + nest.SetStatus(neuron2, model_initial_state) + if gsl_error_tol is not None: - neuron2.set({"gsl_error_tol": gsl_error_tol}) + nest.SetStatus(neuron2, {"gsl_error_tol": gsl_error_tol}) spikegenerator = nest.Create('spike_generator', params={'spike_times': spike_times, 'spike_weights': spike_weights}) @@ -301,18 +484,21 @@ def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001 multimeter2 = nest.Create('multimeter') V_m_specifier = 'V_m' # 'delta_V_m' - multimeter1.set({"record_from": [V_m_specifier]}) - multimeter2.set({"record_from": [V_m_specifier]}) + nest.SetStatus(multimeter1, {"record_from": [V_m_specifier]}) + nest.SetStatus(multimeter2, {"record_from": [V_m_specifier]}) nest.Connect(multimeter1, neuron1) nest.Connect(multimeter2, neuron2) nest.Simulate(400.0) - Vms1 = multimeter1.get("events")[V_m_specifier] - ts1 = multimeter1.get("events")["times"] - Vms2 = multimeter2.get("events")[V_m_specifier] - ts2 = multimeter2.get("events")["times"] + dmm1 = nest.GetStatus(multimeter1)[0] + Vms1 = dmm1["events"][V_m_specifier] + ts1 = dmm1["events"]["times"] + + dmm2 = nest.GetStatus(multimeter2)[0] + Vms2 = dmm2["events"][V_m_specifier] + ts2 = dmm2["events"]["times"] if TEST_PLOTS: fig, ax = plt.subplots(2, 1) @@ -322,6 +508,7 @@ def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001 _ax.legend(loc='upper right') _ax.grid() plt.savefig("/tmp/nestml_nest_integration_test_[" + referenceModel + "]_[" + testant + "].png") + plt.close(fig) if TEST_PLOTS: for figsize, fname_snip in zip([(8, 5), (4, 3)], ["", "_small"]): @@ -335,6 +522,7 @@ def _test_model(self, referenceModel, testant, gsl_error_tol, tolerance=0.000001 plt.tight_layout() plt.savefig("/tmp/nestml_models_library_[" + referenceModel + "]_synaptic_response" + fname_snip + ".png") + plt.close(fig) for index in range(0, len(Vms1)): if abs(Vms1[index] - Vms2[index]) > tolerance \ diff --git a/tests/nest_tests/nest_logarithmic_function_test.py b/tests/nest_tests/nest_logarithmic_function_test.py index c96ce9035..2d4f0b932 100644 --- a/tests/nest_tests/nest_logarithmic_function_test.py +++ b/tests/nest_tests/nest_logarithmic_function_test.py @@ -23,7 +23,9 @@ import numpy as np import os import unittest -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +from pynestml.frontend.pynestml_frontend import generate_nest_target +from pynestml.codegeneration.nest_tools import NESTTools class NestLogarithmicFunctionTest(unittest.TestCase): @@ -32,35 +34,43 @@ class NestLogarithmicFunctionTest(unittest.TestCase): def test_logarithmic_function(self): MAX_SSE = 1E-12 - input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources"))) - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - target_path = 'target' - logging_level = 'INFO' - module_name = 'nestmlmodule' - store_log = False - suffix = '_nestml' - dev = True - to_nest(input_path, target_path, logging_level, module_name, store_log, suffix, dev) - install_nest(target_path, nest_path) - nest.set_verbosity("M_ALL") + input_path = [os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "LogarithmicFunctionTest.nestml"))), + os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "LogarithmicFunctionTest_invalid.nestml")))] + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + nest_version = NESTTools.detect_nest_version() + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) nest.ResetKernel() nest.Install("nestmlmodule") nrn = nest.Create("logarithm_function_test_nestml") - mm = nest.Create('multimeter') + mm = nest.Create("multimeter") - ln_state_specifier = 'ln_state' - log10_state_specifier = 'log10_state' - mm.set({"record_from": [ln_state_specifier, log10_state_specifier, "x"]}) + ln_state_specifier = "ln_state" + log10_state_specifier = "log10_state" + nest.SetStatus(mm, {"record_from": [ln_state_specifier, log10_state_specifier, "x"]}) nest.Connect(mm, nrn) nest.Simulate(100.0) - timevec = mm.get("events")["x"] - ln_state_ts = mm.get("events")[ln_state_specifier] - log10_state_ts = mm.get("events")[log10_state_specifier] + if nest_version.startswith("v2"): + timevec = nest.GetStatus(mm, "events")[0]["x"] + ln_state_ts = nest.GetStatus(mm, "events")[0][ln_state_specifier] + log10_state_ts = nest.GetStatus(mm, "events")[0][log10_state_specifier] + else: + timevec = mm.get("events")["x"] + ln_state_ts = mm.get("events")[ln_state_specifier] + log10_state_ts = mm.get("events")[log10_state_specifier] ref_ln_state_ts = np.log(timevec - 1) ref_log10_state_ts = np.log10(timevec - 1) @@ -72,19 +82,24 @@ def test_logarithmic_function(self): nest.ResetKernel() nrn = nest.Create("logarithm_function_test_invalid_nestml") - mm = nest.Create('multimeter') + mm = nest.Create("multimeter") - ln_state_specifier = 'ln_state' - log10_state_specifier = 'log10_state' - mm.set({"record_from": [ln_state_specifier, log10_state_specifier, "x"]}) + ln_state_specifier = "ln_state" + log10_state_specifier = "log10_state" + nest.SetStatus(mm, {"record_from": [ln_state_specifier, log10_state_specifier, "x"]}) nest.Connect(mm, nrn) nest.Simulate(100.0) - timevec = mm.get("events")["x"] - ln_state_ts = mm.get("events")[ln_state_specifier] - log10_state_ts = mm.get("events")[log10_state_specifier] + if nest_version.startswith("v2"): + timevec = nest.GetStatus(mm, "events")[0]["times"] + ln_state_ts = nest.GetStatus(mm, "events")[0][ln_state_specifier] + log10_state_ts = nest.GetStatus(mm, "events")[0][log10_state_specifier] + else: + timevec = mm.get("events")["times"] + ln_state_ts = mm.get("events")[ln_state_specifier] + log10_state_ts = mm.get("events")[log10_state_specifier] ref_ln_state_ts = np.log(timevec - 1) ref_log10_state_ts = np.log10(timevec - 1) diff --git a/tests/nest_tests/nest_loops_integration_test.py b/tests/nest_tests/nest_loops_integration_test.py new file mode 100644 index 000000000..35c96929a --- /dev/null +++ b/tests/nest_tests/nest_loops_integration_test.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# +# nest_loops_integration_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +nest_version = NESTTools.detect_nest_version() + + +class NestLoopsIntegrationTest(unittest.TestCase): + """ + Tests the code generation and working of for and while loops from NESTML to NEST + """ + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_for_and_while_loop(self): + files = ["ForLoop.nestml", "WhileLoop.nestml"] + input_path = [os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", s))) for s in + files] + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install("nestmlmodule") + + nrn = nest.Create("for_loop_nestml") + mm = nest.Create("multimeter") + mm.set({"record_from": ["V_m"]}) + + nest.Connect(mm, nrn) + + nest.Simulate(5.0) + + v_m = mm.get("events")["V_m"] + np.testing.assert_almost_equal(v_m[-1], 16.6) + + nest.ResetKernel() + nrn = nest.Create("while_loop_nestml") + + mm = nest.Create("multimeter") + mm.set({"record_from": ["y"]}) + + nest.Connect(mm, nrn) + + nest.Simulate(5.0) + y = mm.get("events")["y"] + np.testing.assert_almost_equal(y[-1], 5.011) diff --git a/tests/nest_tests/nest_multisynapse_test.py b/tests/nest_tests/nest_multisynapse_test.py index 4590e7f16..a674f4249 100644 --- a/tests/nest_tests/nest_multisynapse_test.py +++ b/tests/nest_tests/nest_multisynapse_test.py @@ -22,7 +22,8 @@ import nest import os import unittest -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +from pynestml.frontend.pynestml_frontend import generate_nest_target try: import matplotlib @@ -37,15 +38,16 @@ class NestMultiSynapseTest(unittest.TestCase): def test_multisynapse(self): input_path = os.path.join(os.path.realpath(os.path.join( os.path.dirname(__file__), "resources", "iaf_psc_exp_multisynapse.nestml"))) - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - target_path = 'target' - logging_level = 'INFO' - module_name = 'nestmlmodule' - store_log = False - suffix = '_nestml' - dev = True - to_nest(input_path, target_path, logging_level, module_name, store_log, suffix, dev) - install_nest(target_path, nest_path) + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) nest.set_verbosity("M_ALL") nest.ResetKernel() @@ -64,11 +66,11 @@ def test_multisynapse(self): sg3 = nest.Create("spike_generator", params={"spike_times": [30., 70.]}) nest.Connect(sg3, neuron, syn_spec={"receptor_type": 3, "weight": 500., "delay": 0.1}) - mm = nest.Create('multimeter', params={'record_from': [ - 'I_kernel1__X__spikes1', 'I_kernel2__X__spikes2', 'I_kernel3__X__spikes3'], 'interval': 0.1}) + mm = nest.Create("multimeter", params={"record_from": [ + "I_kernel1__X__spikes1", "I_kernel2__X__spikes2", "I_kernel3__X__spikes3"], "interval": 0.1}) nest.Connect(mm, neuron) - vm_1 = nest.Create('voltmeter') + vm_1 = nest.Create("voltmeter") nest.Connect(vm_1, neuron) # simulate diff --git a/tests/nest_tests/nest_multithreading_test.py b/tests/nest_tests/nest_multithreading_test.py new file mode 100644 index 000000000..9e22bd2c2 --- /dev/null +++ b/tests/nest_tests/nest_multithreading_test.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# +# nest_multithreading_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +nest_version = NESTTools.detect_nest_version() + + +@pytest.mark.parametrize("number_of_threads", [1, 2, 4]) +class TestNestMultithreading: + neuron_synapse_module = "nestml_stdp_module" + neuron_synapse_target = "/tmp/nestml-stdp" + neuron_synapse_neuron_model = "iaf_psc_exp_nestml__with_stdp_nestml" + neuron_synapse_synapse_model = "stdp_nestml__with_iaf_psc_exp_nestml" + + neuron_module = "nestml_module" + neuron_target = "/tmp/nestml-iaf-psc" + neuron_model = "iaf_psc_exp__nestml" + + @pytest.fixture(autouse=True, + scope="session") + def nestml_generate_target(self) -> None: + """Generate the model code""" + + # Neuron-Synapse model + neuron_path = os.path.join( + os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "models", + "neurons", "iaf_psc_exp.nestml"))) + synapse_path = os.path.join( + os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "models", + "synapses", "stdp_synapse.nestml"))) + generate_nest_target(input_path=[neuron_path, synapse_path], + target_path=self.neuron_synapse_target, + logging_level="INFO", + module_name=self.neuron_synapse_module, + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "stdp", + "post_ports": ["post_spikes"]}]}) + + # Neuron model + generate_nest_target(input_path=neuron_path, + target_path=self.neuron_target, + logging_level="INFO", + module_name=self.neuron_module, + suffix="__nestml", + codegen_opts={"neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h"}) + + nest.Install(self.neuron_module) + nest.Install(self.neuron_synapse_module) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_neuron_multithreading(self, number_of_threads: int) -> None: + nest.ResetKernel() + nest.resolution = 0.1 + nest.local_num_threads = number_of_threads + spike_times = np.array([2., 4., 7., 8., 12., 13., 19., 23., 24., 28., 29., 30., 33., 34., + 35., 36., 38., 40., 42., 46., 51., 53., 54., 55., 56., 59., 63., 64., + 65., 66., 68., 72., 73., 76., 79., 80., 83., 84., 86., 87., 90., 95.]) + sg = nest.Create("spike_generator", + params={"spike_times": spike_times}) + + n = nest.Create(self.neuron_model, 5) + nest.Connect(sg, n) + + multimeter = nest.Create("multimeter", params={"record_from": ["V_m"]}) + nest.Connect(multimeter, n) + + connections = nest.GetConnections() + gid_post = np.unique(np.array(connections.get("target")))[0] + nest.Simulate(100.) + + events = multimeter.get("events") + v_m = events["V_m"] + senders = events["senders"] + v_m_sender = v_m[senders == gid_post] + np.testing.assert_almost_equal(v_m_sender[-1], -69.97074345103816) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_neuron_synapse_multithreading(self, number_of_threads: int) -> None: + pre_spike_times = np.array([2., 4., 7., 8., 12., 13., 19., 23., 24., 28., 29., 30., 33., 34., + 35., 36., 38., 40., 42., 46., 51., 53., 54., 55., 56., 59., 63., 64., + 65., 66., 68., 72., 73.]) + post_spike_times = np.array([4., 5., 6., 7., 10., 11., 12., 16., 17., 18., 19., 20., 22., 23., + 25., 27., 29., 30., 31., 32., 34., 36., 37., 38., 39., 42., 44., 46., + 48., 49., 50., 54., 56., 57., 59., 60., 61., 62., 67., 74.]) + + nest.ResetKernel() + nest.resolution = 0.1 + nest.local_num_threads = number_of_threads + + wr = nest.Create("weight_recorder") + nest.CopyModel(self.neuron_synapse_synapse_model, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0}) + + # Spike generators + pre_sg = nest.Create("spike_generator", 2, + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", 2, + params={"spike_times": post_spike_times, + "allow_offgrid_times": True}) + + pre_neuron = nest.Create(self.neuron_synapse_neuron_model, 2) + post_neuron = nest.Create(self.neuron_synapse_neuron_model, 2) + sr_pre = nest.Create("spike_recorder") + sr_post = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, sr_pre) + nest.Connect(post_neuron, sr_post) + + nest.Simulate(100.) + + connections = nest.GetConnections(synapse_model="stdp_nestml_rec") + gid_post = np.unique(np.array(connections.get("target")))[0] + events = mm.get("events") + senders = events["senders"] + V_m = events["V_m"] + V_m_sender = V_m[senders == gid_post] + np.testing.assert_almost_equal(V_m_sender[-1], -58.64615287) diff --git a/tests/nest_tests/nest_resolution_builtin_test.py b/tests/nest_tests/nest_resolution_builtin_test.py new file mode 100644 index 000000000..62901b738 --- /dev/null +++ b/tests/nest_tests/nest_resolution_builtin_test.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# +# nest_resolution_builtin_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +nest_version = NESTTools.detect_nest_version() + + +class NestResolutionBuiltinTest(unittest.TestCase): + """Check that the ``resolution()`` function returns a meaningful result in all contexts where it is can appear""" + + def setUp(self): + """Generate the model code""" + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + input_files = [os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "iaf_psc_exp_resolution_test.nestml"))), + os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, "valid", "CoCoResolutionLegallyUsed.nestml")))] + generate_nest_target(input_path=input_files, + target_path="target", + logging_level="INFO", + module_name="nestmlmodule", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp_resolution_test", + "synapse": "CoCoResolutionLegallyUsed"}]}) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_resolution_function(self): + nest.set_verbosity("M_ALL") + nest.ResetKernel() + nest.Install("nestmlmodule") + models = nest.Models(mtype="nodes") + neuron_models = [m for m in models if str(nest.GetDefaults(m, "element_type")) == "neuron"] + print(neuron_models) + pre = nest.Create("iaf_psc_exp", 100) + post = nest.Create("iaf_psc_exp_resolution_test_nestml__with_CoCoResolutionLegallyUsed_nestml") + nest.Connect(pre, post, "all_to_all", + syn_spec={'synapse_model': "CoCoResolutionLegallyUsed_nestml__with_iaf_psc_exp_resolution_test_nestml"}) + nest.Simulate(100.0) diff --git a/tests/nest_tests/nest_split_simulation_test.py b/tests/nest_tests/nest_split_simulation_test.py new file mode 100644 index 000000000..0e95ed979 --- /dev/null +++ b/tests/nest_tests/nest_split_simulation_test.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# nest_split_simulation_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + + +import numpy as np +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools + + +try: + import matplotlib + import matplotlib.pyplot as plt + TEST_PLOTS = True +except BaseException: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + + +class NestSplitSimulationTest(unittest.TestCase): + """ + Check that nest.Simulate(100) yields the same behaviour as calling nest.Simulate(50) twice in a row. + + N.B. simulation resolution is not allowed to be changed by NEST between the two calls in the split condition. + """ + + def run_simulation(self, T_sim: float, split: bool): + neuron_model_name = "iaf_psc_exp" + + spike_times = np.arange(10, 100, 9).astype(np.float) + np.random.seed(0) + spike_weights = np.sign(np.random.rand(spike_times.size) - .5) + + nest.ResetKernel() + nest.SetKernelStatus({"resolution": .1}) + neuron = nest.Create(neuron_model_name) + + spikegenerator = nest.Create('spike_generator', + params={'spike_times': spike_times, 'spike_weights': spike_weights}) + + nest.Connect(spikegenerator, neuron) + + multimeter = nest.Create('multimeter') + + multimeter.set({"record_from": ['V_m']}) + + nest.Connect(multimeter, neuron) + + if split: + nest.Simulate(T_sim / 2.) + nest.Simulate(T_sim / 2.) + else: + nest.Simulate(T_sim) + + ts = multimeter.get("events")["times"] + Vms = multimeter.get("events")['V_m'] + + if TEST_PLOTS: + fig, ax = plt.subplots(2, 1) + ax[0].plot(ts, Vms, label='V_m') + for _ax in ax: + _ax.legend(loc='upper right') + _ax.grid() + plt.savefig("/tmp/nestml_nest_split_simulation_test_[T_sim=" + str(T_sim) + "]_[split=" + str(split) + "].png") + + return ts, Vms + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_nest_split_simulation(self): + ts, Vms = self.run_simulation(T_sim=100., split=False) + ts_split, Vms_split = self.run_simulation(T_sim=100., split=True) + np.testing.assert_allclose(Vms, Vms_split) diff --git a/tests/nest_tests/nest_vectors_test.py b/tests/nest_tests/nest_vectors_test.py new file mode 100644 index 000000000..265c12207 --- /dev/null +++ b/tests/nest_tests/nest_vectors_test.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +# +# nest_vectors_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os +import numpy as np +import pytest + +import nest +from nest.lib.hl_api_exceptions import NESTErrors + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +nest_version = NESTTools.detect_nest_version() + + +class TestNestVectorsIntegration: + r""" + Tests the code generation and vector operations from NESTML to NEST. + """ + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_vectors(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "Vectors.nestml"))) + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install("nestmlmodule") + + neuron = nest.Create("vectors_nestml") + multimeter = nest.Create("multimeter") + recordables = list() + recordables.extend(["G_IN_" + str(i + 1) for i in range(0, 20)]) + recordables.extend(["G_EX_" + str(i + 1) for i in range(0, 10)]) + recordables.append("V_m") + multimeter.set({"record_from": recordables}) + nest.Connect(multimeter, neuron) + + nest.Simulate(2.0) + + events = multimeter.get("events") + g_in = events["G_IN_1"] + g_ex = events["G_EX_2"] + print("g_in: {}, g_ex: {}".format(g_in, g_ex)) + np.testing.assert_almost_equal(g_in[-1], 11.) + np.testing.assert_almost_equal(g_ex[-1], -2.) + + v_m = multimeter.get("events")["V_m"] + print("V_m: {}".format(v_m)) + np.testing.assert_almost_equal(v_m[-1], -0.3) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + @pytest.mark.xfail(strict=True, raises=NESTErrors.BadProperty) + def test_vectors_resize(self): + input_path = os.path.join( + os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "VectorsResize.nestml"))) + target_path = "target" + logging_level = "INFO" + module_name = "vectorsmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install(module_name) + + neuron = nest.Create("vector_resize_nestml", params={"N": 200}) + neuron.set(x=[1.0, 1.0, 4.0]) + nest.Simulate(10) diff --git a/tests/nest_tests/neuron_ou_conductance_noise_test.py b/tests/nest_tests/neuron_ou_conductance_noise_test.py index 470c2260a..2026db707 100644 --- a/tests/nest_tests/neuron_ou_conductance_noise_test.py +++ b/tests/nest_tests/neuron_ou_conductance_noise_test.py @@ -19,11 +19,15 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -import nest import numpy as np import os +import pytest import unittest -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target try: import matplotlib @@ -32,12 +36,14 @@ except BaseException: TEST_PLOTS = False +nest_version = NESTTools.detect_nest_version() + class TestOUConductanceNoise(unittest.TestCase): - record_from = ['g_noise_ex', 'g_noise_in'] + record_from = ["g_noise_exc", "g_noise_inh"] def simulate_OU_noise_neuron(self, resolution): - ''' + r""" Simulates a single neuron with OU noise conductances. Parameters @@ -52,28 +58,28 @@ def simulate_OU_noise_neuron(self, resolution): tuple Tuple with the NEST id of the simulated neuron - ''' + """ seed = np.random.randint(0, 2**32 - 1) - print('seed: {}'.format(seed)) - nest.SetKernelStatus({'resolution': resolution, 'grng_seed': seed, 'rng_seeds': [seed + 1]}) + print("seed: {}".format(seed)) + nest.SetKernelStatus({"resolution": resolution, "rng_seed": seed + 1}) input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), - "..", "..", "models", "hh_cond_exp_destexhe.nestml"))) - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - target_path = 'target' - logging_level = 'INFO' - module_name = 'nestmlmodule' - store_log = False - suffix = '_nestml' - dev = True - to_nest(input_path, target_path, logging_level, module_name, store_log, suffix, dev) - install_nest(target_path, nest_path) + os.pardir, os.pardir, "models", "neurons", "hh_cond_exp_destexhe.nestml"))) + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) nest.set_verbosity("M_ALL") - nest.Install('nestmlmodule') - neuron = nest.Create('hh_cond_exp_destexhe_nestml') + nest.Install("nestmlmodule") + neuron = nest.Create("hh_cond_exp_destexhe_nestml") - multi = nest.Create('multimeter', params={'record_from': self.record_from, 'interval': resolution}) + multi = nest.Create("multimeter", params={"record_from": self.record_from, "interval": resolution}) nest.Connect(multi, neuron) nest.Simulate(500000) @@ -81,7 +87,7 @@ def simulate_OU_noise_neuron(self, resolution): return multi.get("events"), neuron def calc_statistics(self, state, neuron): - '''Calculates statistics for the Ornstein-Uhlenbeck-noise conductances. + """Calculates statistics for the Ornstein-Uhlenbeck-noise conductances. Calculates the means and variances of the conductances and compares them with the expected means and variances @@ -89,59 +95,59 @@ def calc_statistics(self, state, neuron): Parameters ---------- state : dict - The state of the multimeter which you get by calling multimeter.get('events') + The state of the multimeter which you get by calling multimeter.get("events") neuron : tuple Tuple with the NEST id of the neuron with the OU noise conductances - ''' + """ MAX_VAR_DIFF_PERC = 5. MAX_MEAN_DIFF_PERC = 1. - print('\n\n======== Noise Conductance Statistics ==============') - times = state['times'] + print("\n\n======== Noise Conductance Statistics ==============") + times = state["times"] # excitatory noise - sigma_ex = neuron.get('sigma_noise_ex') - mean_ex = neuron.get('g_noise_ex0') - tau_ex = neuron.get('tau_syn_ex') - var_ex = sigma_ex**2 / (2 / tau_ex) + sigma_exc = neuron.get("sigma_noise_exc") + mean_exc = neuron.get("g_noise_exc0") + tau_exc = neuron.get("tau_syn_exc") + var_exc = sigma_exc**2 / (2 / tau_exc) # inhibitory noise - sigma_in = neuron.get('sigma_noise_in') - mean_in = neuron.get('g_noise_in0') - tau_in = neuron.get('tau_syn_in') - var_in = sigma_in**2 / (2 / tau_in) + sigma_inh = neuron.get("sigma_noise_inh") + mean_inh = neuron.get("g_noise_inh0") + tau_inh = neuron.get("tau_syn_inh") + var_inh = sigma_inh**2 / (2 / tau_inh) # variances - print('\n____variances_______________________________________') - vex = np.var(state['g_noise_ex']) - vin = np.var(state['g_noise_in']) - vex_trgt = sigma_ex**2 - vin_trgt = sigma_in**2 + print("\n____variances_______________________________________") + vex = np.var(state["g_noise_exc"]) + vin = np.var(state["g_noise_inh"]) + vex_trgt = sigma_exc**2 + vin_trgt = sigma_inh**2 diff_perc_vex = np.abs(1 - vex / vex_trgt) * 100 diff_perc_vin = np.abs(1 - vin / vin_trgt) * 100 - print('ex: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)'.format( + print("ex: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)".format( vex, vex_trgt, np.abs(vex - vex_trgt), diff_perc_vex)) - print('in: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)'.format( + print("in: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)".format( vin, vin_trgt, np.abs(vin - vin_trgt), diff_perc_vin)) assert 0. < diff_perc_vex < MAX_VAR_DIFF_PERC assert 0. < diff_perc_vin < MAX_VAR_DIFF_PERC # means - print('\n____means___________________________________________') - m_ex_data = np.mean(state['g_noise_ex']) - m_in_data = np.mean(state['g_noise_in']) - diff_perc_mex = np.abs(1 - m_ex_data / mean_ex) * 100 - diff_perc_min = np.abs(1 - m_in_data / mean_in) * 100 - print('ex: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)'.format( - m_ex_data, mean_ex, np.abs(m_ex_data - mean_ex), diff_perc_mex)) - print('in: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)\n'.format( - m_in_data, mean_in, np.abs(m_in_data - mean_in), diff_perc_min)) - assert 0. < diff_perc_mex < MAX_MEAN_DIFF_PERC - assert 0. < diff_perc_min < MAX_MEAN_DIFF_PERC + print("\n____means___________________________________________") + m_exc_data = np.mean(state["g_noise_exc"]) + m_inh_data = np.mean(state["g_noise_inh"]) + diff_perc_mexc = np.abs(1 - m_exc_data / mean_exc) * 100 + diff_perc_minh = np.abs(1 - m_inh_data / mean_inh) * 100 + print("ex: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)".format( + m_exc_data, mean_exc, np.abs(m_exc_data - mean_exc), diff_perc_mexc)) + print("in: {:.2f}\ttarget = {:.2f}\tdiff = {:.2f} ({:.2f}%)\n".format( + m_inh_data, mean_inh, np.abs(m_inh_data - mean_inh), diff_perc_minh)) + assert 0. < diff_perc_mexc < MAX_MEAN_DIFF_PERC + assert 0. < diff_perc_minh < MAX_MEAN_DIFF_PERC def plot_results(self, state): - '''Reproduces figures 2A and 2B from Destexhe et al. 2001. + """Reproduces figures 2A and 2B from Destexhe et al. 2001. Produces a plot with the time courses of the total excitatory (top left) and total inhibitory (bottom left) conductances during synaptic background @@ -152,33 +158,35 @@ def plot_results(self, state): ---------- state : dict The state of the multimeter which you get by calling multimeter.get("events") - ''' - times = state['times'] + """ + times = state["times"] fig, ax = plt.subplots(2, 2, constrained_layout=True, figsize=(15, 10)) mask = times <= 1200. for idx, rf in enumerate(self.record_from): ax_cond = ax[idx][0] ax_hist = ax[idx][1] - if 'ex' in rf: + if "ex" in rf: ax_cond.set_ylim(0, 0.04) - ax_cond.set_title('Excitatory Conductance') - ax_hist.set_title('Conductance distribution (excitatory)') + ax_cond.set_title("Excitatory Conductance") + ax_hist.set_title("Conductance distribution (excitatory)") else: ax_cond.set_ylim(0.03, 0.08) - ax_cond.set_title('Inhibitory Conductance') - ax_hist.set_title('Conductance distribution (inhibitory)') + ax_cond.set_title("Inhibitory Conductance") + ax_hist.set_title("Conductance distribution (inhibitory)") ax_cond.plot(times[mask], state[rf][mask] / 1000.) - ax_cond.set_xlabel('time (ms)') - ax_cond.set_ylabel('Conductance (\u03bcS)') + ax_cond.set_xlabel("time (ms)") + ax_cond.set_ylabel("Conductance (\u03bcS)") ax_hist.set_ylim((0, 2800)) ax_hist.hist(state[rf][:19000] / 1000., bins=100, range=(0, 0.1)) - ax_hist.set_xlabel('Conductance (\u03bcS)') + ax_hist.set_xlabel("Conductance (\u03bcS)") - plt.savefig('figure2AB_destexhe2001.pdf') + plt.savefig("figure2AB_destexhe2001.pdf") + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") def test_ou_conductance_noise(self): state, neuron = self.simulate_OU_noise_neuron(resolution=1.) self.calc_statistics(state, neuron) diff --git a/tests/nest_tests/noisy_synapse_test.py b/tests/nest_tests/noisy_synapse_test.py new file mode 100644 index 000000000..9e5e98253 --- /dev/null +++ b/tests/nest_tests/noisy_synapse_test.py @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- +# +# noisy_synapse_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use('Agg') + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + + +class NoisySynapseTest(unittest.TestCase): + + neuron_model_name = "iaf_psc_delta" + synapse_model_name = "noisy_synapse_nestml" + + def setUp(self): + """Generate and build the model code""" + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, os.pardir, 'models', 'synapses', 'noisy_synapse.nestml')))) + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-noisy-synapse", + logging_level="INFO", + module_name="nestml_noisy_synapse_module", + suffix="_nestml") + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_noisy_noisy_synapse_synapse(self): + + fname_snip = "noisy_synapse_test" + + pre_spike_times = np.linspace(1., 100., 10) + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + synapse_model_name=self.synapse_model_name, + resolution=.1, # [ms] + delay=1., # [ms] + pre_spike_times=pre_spike_times, + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + synapse_model_name, + resolution=.1, # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if sim_time is None: + sim_time = np.amax(pre_spike_times) + 5 * delay + + nest.set_verbosity("M_ALL") + nest.ResetKernel() + nest.Install("nestml_noisy_synapse_module") + + print("Pre spike times: " + str(pre_spike_times)) + + nest.set_verbosity("M_WARNING") + + post_weights = {'parrot': []} + + nest.ResetKernel() + nest.SetKernelStatus({'resolution': resolution}) + + wr = nest.Create('weight_recorder') + nest.CopyModel(synapse_model_name, "noisy_synapse_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + + # create parrot neurons and connect spike_generators + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name, {"tau_m": 2.}) + + spikedet_pre = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={'synapse_model': 'noisy_synapse_nestml_rec'}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + + # get noisy_synapse synapse and weight before protocol + syn = nest.GetConnections(source=pre_neuron, synapse_model="noisy_synapse_nestml_rec") + + n_steps = int(np.ceil(sim_time / resolution)) + 1 + t = 0. + t_hist = [] + w_hist = [] + while t <= sim_time: + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + w_hist.append(nest.GetStatus(syn)[0]['w']) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=3) + + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax[0].plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4, label=_lbl) + + timevec = nest.GetStatus(mm, "events")[0]["times"] + V_m = nest.GetStatus(mm, "events")[0]["V_m"] + ax[1].plot(timevec, V_m, label="nestml", alpha=.7, linestyle=":") + ax[1].set_ylabel("V_m") + + ax[2].plot(wr.get('events')['times'], wr.get('events')['weights'], marker="o", label="w") + + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.grid(which="minor", axis="x", linestyle=":", alpha=.4) + # _ax.minorticks_on() + _ax.set_xlim(0., sim_time) + _ax.legend() + + fig.savefig("/tmp/noisy_synapse_synapse_test" + fname_snip + "_V_m.png", dpi=300) diff --git a/tests/nest_tests/non_linear_dendrite_test.py b/tests/nest_tests/non_linear_dendrite_test.py new file mode 100644 index 000000000..87aa6c248 --- /dev/null +++ b/tests/nest_tests/non_linear_dendrite_test.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# +# non_linear_dendrite_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +try: + import matplotlib + matplotlib.use("agg") + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + + +class NestNonLinearDendriteTest(unittest.TestCase): + """ + Test for proper reset of synaptic integration after condition is triggered (here, dendritic spike). + """ + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_non_linear_dendrite(self): + MAX_SSE = 1E-12 + + I_dend_alias_name = "I_dend" # synaptic current + I_dend_internal_name = "I_kernel2__X__I_2" # alias for the synaptic current + + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources")), "iaf_psc_exp_nonlineardendrite.nestml") + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install("nestmlmodule") + + nrn = nest.Create("iaf_psc_exp_nonlineardendrite_nestml") + + sg = nest.Create("spike_generator", params={"spike_times": [10., 20., 30.]}) + nest.Connect(sg, nrn, syn_spec={"receptor_type": 2, "weight": 30., "delay": 1.}) + + mm = nest.Create("multimeter") + mm.set({"record_from": [I_dend_alias_name, I_dend_internal_name, "V_m", "dend_curr_enabled", "I_dend_ap"]}) + nest.Connect(mm, nrn) + + nest.Simulate(100.0) + + timevec = mm.get("events")["times"] + I_dend_alias_ts = mm.get("events")[I_dend_alias_name] + I_dend_internal_ts = mm.get("events")[I_dend_internal_name] + + if TEST_PLOTS: + fig, ax = plt.subplots(3, 1) + ax[0].plot(timevec, I_dend_alias_ts, label="aliased I_dend_syn") + ax[0].plot(timevec, I_dend_internal_ts, label="internal I_dend_syn") + ax[0].legend() + ax_ = ax[0].twinx() + ax_.plot(timevec, mm.get("events")["dend_curr_enabled"]) + ax_.set_ylabel("dend_curr_enabled") + ax[1].plot(timevec, mm.get("events")["I_dend_ap"]) + ax[1].set_ylabel("I_dend_AP") + ax[2].plot(timevec, mm.get("events")["V_m"], label="V_m") + for _ax in ax: + _ax.legend() + _ax.grid() + plt.ylabel("Dendritic current $I_{dend}$") + plt.suptitle("Reset of synaptic integration after dendritic spike") + plt.savefig("/tmp/nestml_triplet_stdp_test.png") + + assert np.all(I_dend_alias_ts == I_dend_internal_ts), "Variable " + str(I_dend_alias_name) + " and (internal) variable " + str(I_dend_internal_name) + " should measure the same thing, but discrepancy in values occurred." + + tidx = np.argmin((timevec - 40)**2) + assert mm.get("events")["I_dend_ap"][tidx] > 0., "Expected a dendritic action potential around t = 40 ms, but dendritic action potential current is zero" + assert mm.get("events")["dend_curr_enabled"][tidx] == 0., "Dendritic synaptic current should be disabled during dendritic action potential" + tidx_ap_end = tidx + np.where(mm.get("events")["dend_curr_enabled"][tidx:] == 1.)[0][0] + assert np.all(I_dend_alias_ts[tidx_ap_end:] == 0.), "After dendritic spike, dendritic current should be reset to 0 and stay at 0." diff --git a/tests/nest_tests/print_function_code_generator_test.py b/tests/nest_tests/print_function_code_generator_test.py new file mode 100644 index 000000000..65b9e7bc6 --- /dev/null +++ b/tests/nest_tests/print_function_code_generator_test.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +# +# print_function_code_generator_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import os +import unittest + +from pynestml.codegeneration.nest_code_generator import NESTCodeGenerator +from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.model_parser import ModelParser +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables + + +class PrintCodeGeneratorTest(unittest.TestCase): + """ + Tests code generated for print and println functions from NESTML to NEST + """ + + def setUp(self) -> None: + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedFunctions.register_functions() + PredefinedVariables.register_variables() + SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + Logger.init_logger(LoggingLevel.INFO) + + self.target_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, 'target')))) + + def test_simple_print_statment(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + 'resources', 'SimplePrintStatement.nestml')))) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + FrontendConfiguration.parse_config(params) + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator() + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + + with open(str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, 'target', 'simple_print_test.cpp')))), 'r') as reader: + self.assertEqual(reader.read().count('std::cout'), 1) + + def test_print_statement_with_variables(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + 'resources', 'PrintStatementWithVariables.nestml')))) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + FrontendConfiguration.parse_config(params) + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator() + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + + with open(str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, 'target', 'print_test_variables.cpp')))), 'r') as reader: + self.assertEqual(reader.read().count('std::cout'), 2) + + def test_print_variables_with_different_units(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + 'resources', 'PrintVariablesWithDifferentButCompatibleUnits.nestml')))) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + FrontendConfiguration.parse_config(params) + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator() + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + + with open(str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, 'target', 'print_variable.cpp')))), 'r') as reader: + self.assertEqual(reader.read().count('std::cout'), 1) + + def test_print_statment_in_function(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + 'resources', 'PrintStatementInFunction.nestml')))) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + FrontendConfiguration.parse_config(params) + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator() + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + + with open(str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, 'target', 'print_test_function.cpp')))), 'r') as reader: + self.assertEqual(reader.read().count('std::cout'), 1) + + def tearDown(self): + import shutil + shutil.rmtree(self.target_path) diff --git a/tests/nest_tests/print_statement_test.py b/tests/nest_tests/print_statement_test.py new file mode 100644 index 000000000..a32bae308 --- /dev/null +++ b/tests/nest_tests/print_statement_test.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# +# print_statement_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import os +import subprocess +import unittest + + +class PrintStatementTest(unittest.TestCase): + """ + Test to validate the output of NEST cout statements converted from the corresponding NESTML print() functions. + """ + + def test_print_statement(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + 'resources', 'print_variable_script.py')))) + self.output_path = "output.txt" + + with open(self.output_path, 'w') as outfile: + subprocess.run(['python', input_path], stdout=outfile) + + with open(self.output_path, 'r') as reader: + lines = list(reader.readlines()) + reader.close() + + matches = [s for s in lines if "print:" in s] + self.assertEqual(matches[0], "print: This is a simple print statement\n") + self.assertEqual(matches[1], "print: Membrane voltage: -0.05 V, threshold: -7e-08 MA Ohm, and V_abs: -50 mV\n") + + def tearDown(self) -> None: + if os.path.exists(self.output_path): + os.remove(self.output_path) diff --git a/tests/nest_tests/recordable_variables_test.py b/tests/nest_tests/recordable_variables_test.py new file mode 100644 index 000000000..773a77063 --- /dev/null +++ b/tests/nest_tests/recordable_variables_test.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# +# recordable_variables_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import unittest +import os + +import nest + +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + import matplotlib.pyplot as plt + + TEST_PLOTS = True +except BaseException: + TEST_PLOTS = False + + +class RecordableVariablesTest(unittest.TestCase): + """ + Test to check the recordable variables: from state and initial_values block and inline expressions in the equations block + """ + + def test_recordable_variables(self): + input_path = os.path.join(os.path.realpath(os.path.join( + os.path.dirname(__file__), "resources", "RecordableVariables.nestml"))) + target_path = "target" + logging_level = "INFO" + module_name = "nestmlmodule" + suffix = "_nestml" + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.Install(module_name) + + neuron = nest.Create("recordable_variables_nestml") + sg = nest.Create("spike_generator", params={"spike_times": [20., 80.]}) + nest.Connect(sg, neuron) + + mm = nest.Create('multimeter', params={'record_from': ['V_ex', 'V_m', 'V_abs', 'I_kernel__X__spikes'], + 'interval': 0.1}) + nest.Connect(mm, neuron) + + nest.Simulate(100.) + + # Get the recordable variables + events = nest.GetStatus(mm)[0]["events"] + V_reset = nest.GetStatus(neuron, "V_reset") + V_m = events["V_m"] + self.assertIsNotNone(V_m) + + V_abs = events["V_abs"] + self.assertIsNotNone(V_abs) + + np.testing.assert_allclose(V_m, V_abs + V_reset) + + V_ex = events["V_ex"] + np.testing.assert_almost_equal(V_ex[-1], -10) diff --git a/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml b/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml index 201509856..2fa1b81d2 100644 --- a/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml +++ b/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml @@ -1,11 +1,38 @@ -/* bi-exponential ("beta function") postsynaptic response */ +""" +BiexponentialPostSynapticResponse.nestml +######################################## + +Description ++++++++++++ + +Bi-exponential ("beta function") postsynaptic response + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron biexp_postsynaptic_response: state: - r integer # counts number of tick during the refractory period - end + r integer = 0 # counts number of tick during the refractory period - initial_values: g_in real = 0 # inputs from the inhibitory conductance g_in$ real = g_I_const * (1 / tau_syn_rise_I - 1 / tau_syn_decay_I) @@ -97,7 +124,7 @@ neuron biexp_postsynaptic_response: spikeExc nS <- spike spikeGap nS <- spike spikeGABA nS <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike diff --git a/tests/nest_tests/resources/CppVariableNames.nestml b/tests/nest_tests/resources/CppVariableNames.nestml new file mode 100644 index 000000000..73eec8380 --- /dev/null +++ b/tests/nest_tests/resources/CppVariableNames.nestml @@ -0,0 +1,47 @@ +""" +CppVariableNames.nestml +####################### + +Contains some C++ keyword-named variables. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cpp_variable_names_test: + state: + static real = 0. + concept real = 0. + end + + parameters: + using real = 0. + end + + equations: + concept' = 1. / s + end + + update: + static = concept + using + integrate_odes() + end +end diff --git a/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml b/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml new file mode 100644 index 000000000..81c16fb81 --- /dev/null +++ b/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml @@ -0,0 +1,48 @@ +""" +DelayBasedVariablesWithAnalyticSolver.nestml +############################################ + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron dde_analytic: + state: + u_bar_plus real = -70. + foo real = 0 + end + + equations: + u_bar_plus' = -u_bar_plus / tau + foo' = u_bar_plus(t - delay) / tau + end + + parameters: + tau ms = 1.5 ms + delay ms = 5. ms + b real = 0. + end + + update: + integrate_odes() + end + +end diff --git a/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml b/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml new file mode 100644 index 000000000..1e8ba5caf --- /dev/null +++ b/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml @@ -0,0 +1,51 @@ +""" +DelayDifferentialEquationsWithMixedSolver.nestml +################################################ + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron dde_mixed: + + state: + x real = 0.01 + z real = 0.01 + end + + equations: + inline eta_act real = (etaX - epsilon) * (1 + etaX**n_act) + x' = etaX - x / ms + z' = epsilon + eta_act / ((1 + x(t - delay)**n_act) * ms) - z + end + + parameters: + etaX integer = 6 + n_act integer = -2 + epsilon real = 0.5 + + # delay parameter + delay integer = 2 + end + + update: + integrate_odes() + end + +end diff --git a/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml b/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml new file mode 100644 index 000000000..c4425bf5b --- /dev/null +++ b/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml @@ -0,0 +1,53 @@ +""" +DelayDifferentialEquationsWithNumericSolver.nestml +################################################## + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron dde_numeric: + + state: + x real = 0 + z real = 0 + end + + equations: + x' = alpha_x / ((1 + x**n_x) * ms) - beta_x * x + z' = alpha_z / ((1 + x(t-delay)**n_z) * ms) - beta_z * z + end + + parameters: + alpha_x real = 0.5 + alpha_z real = 0.3529 + beta_x real = 0.5 + beta_z real = 0.5 + n_x integer = 2 + n_z integer = 2 + + # delay parameter + delay ms = 5.0 ms + end + + update: + integrate_odes() + end + +end \ No newline at end of file diff --git a/tests/nest_tests/resources/FIR_filter.nestml b/tests/nest_tests/resources/FIR_filter.nestml new file mode 100644 index 000000000..8848481f8 --- /dev/null +++ b/tests/nest_tests/resources/FIR_filter.nestml @@ -0,0 +1,70 @@ +""" +FIR_filter.nestml +################ + + +Description ++++++++++++ + +Model for Finite Impulse Response (FIR) filter + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron fir_filter: + + state: + # FIR filter output (to be recorded by NEST multimeter) + y real = 0. + + # circular buffer for input spike count per timestep + x[N] real = 0. + i integer = 0 + end + + parameters: + N integer = 1 # filter order + h[N] real = 1. # filter coefficients + end + + input: + spike_in real <- spike + end + + update: + # circular buffer for input spike count per timestep + x[i] = spike_in + + # compute the new value of y + j integer = 0 + k integer = 0 + y = 0 + for j in 0 ... N step 1: + k = (i - j + N) % N # shift the index due to circular buffer starting position + y += x[k] * h[j] + end + + # Increment i to receive the next input spike + i += 1 + i = i % N + end + +end diff --git a/tests/nest_tests/resources/ForLoop.nestml b/tests/nest_tests/resources/ForLoop.nestml new file mode 100644 index 000000000..a5afdb6fd --- /dev/null +++ b/tests/nest_tests/resources/ForLoop.nestml @@ -0,0 +1,45 @@ +""" +ForLoop.nestml +############## + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron for_loop: + state: + V_m mV = -0.20 mV + end + + parameters: + N integer = 42 + end + + update: + k integer = 0 + j integer = 0 + for j in 0 ... N step 1: + k = j / N + V_m += 0.01 mV + end + end + +end diff --git a/tests/nest_tests/resources/LogarithmicFunctionTest.nestml b/tests/nest_tests/resources/LogarithmicFunctionTest.nestml index 315d203e8..81bfbe2d6 100644 --- a/tests/nest_tests/resources/LogarithmicFunctionTest.nestml +++ b/tests/nest_tests/resources/LogarithmicFunctionTest.nestml @@ -1,27 +1,30 @@ -/** - * - * LogarithmicFunctionTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . -*/ +""" +LogarithmicFunctionTest.nestml +############################## + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron logarithm_function_test: - initial_values: + state: x real = 0. ln_state real = 0. log10_state real = 0. @@ -30,7 +33,7 @@ neuron logarithm_function_test: input: spikeInh nS <- inhibitory spike spikeExc nS <- excitatory spike - currents pA <- current + currents pA <- continuous end update: diff --git a/tests/nest_tests/resources/LogarithmicFunctionTest_invalid.nestml b/tests/nest_tests/resources/LogarithmicFunctionTest_invalid.nestml index 6f287b03c..a7e89e73b 100644 --- a/tests/nest_tests/resources/LogarithmicFunctionTest_invalid.nestml +++ b/tests/nest_tests/resources/LogarithmicFunctionTest_invalid.nestml @@ -1,26 +1,30 @@ -/** - * - * LogarithmicFunctionTest_invalid.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . -*/ +""" +LogarithmicFunctionTest_invalid.nestml +###################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron logarithm_function_test_invalid: - initial_values: + state: x real = 0. ln_state real = 0. log10_state real = 0. @@ -29,7 +33,7 @@ neuron logarithm_function_test_invalid: input: spikeInh nS <- inhibitory spike spikeExc nS <- excitatory spike - currents pA <- current + currents pA <- continuous end update: diff --git a/tests/nest_tests/resources/PrintStatementInFunction.nestml b/tests/nest_tests/resources/PrintStatementInFunction.nestml new file mode 100644 index 000000000..d0fecb967 --- /dev/null +++ b/tests/nest_tests/resources/PrintStatementInFunction.nestml @@ -0,0 +1,36 @@ +""" +PrintStatementInFunction.nestml +############################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron print_test_function: + + function print_function(): + print("A statement inside a function") + return + end + + update: + print_function() + end +end diff --git a/tests/nest_tests/resources/PrintStatementWithVariables.nestml b/tests/nest_tests/resources/PrintStatementWithVariables.nestml new file mode 100644 index 000000000..190765159 --- /dev/null +++ b/tests/nest_tests/resources/PrintStatementWithVariables.nestml @@ -0,0 +1,43 @@ +""" +PrintStatementWithVariables.nestml +################################## + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron print_test_variables: + state: + V_m mV = -50 mV + end + + parameters: + V_thr mV = -55 mV + t_ev ms = 10 ms + end + + update: + if V_m > V_thr: + print("A spike event with membrane voltage: {V_m}, current time t = {t} and t_ev = {t_ev}") + else: + println("Membrane voltage {V_m} is less than the threshold {V_thr}, current time t = {t} and t_ev = {t_ev}") + end + end +end diff --git a/tests/nest_tests/resources/PrintVariables.nestml b/tests/nest_tests/resources/PrintVariables.nestml new file mode 100644 index 000000000..c063e706e --- /dev/null +++ b/tests/nest_tests/resources/PrintVariables.nestml @@ -0,0 +1,38 @@ +""" +PrintVariables.nestml +##################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron print_variable: + state: + V_m V = -50 mV + V_thr MA*Ohm = -70 mV + V_abs mV = 0 mV + end + + update: + V_abs = V_m + println("print: This is a simple print statement") + print("print: Membrane voltage: {V_m}, threshold: {V_thr}, and V_abs: {V_abs}") + end +end diff --git a/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml b/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml new file mode 100644 index 000000000..29552d205 --- /dev/null +++ b/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml @@ -0,0 +1,37 @@ +""" +PrintVariablesWithDifferentButCompatibleUnits.nestml +#################################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron print_variable: + state: + V_m V = -50 mV + V_thr MA*Ohm = -70 mV + V_abs mV = 0 mV + end + + update: + V_abs = V_m + println("Membrane voltage: {V_m}, threshold: {V_thr}, and V_abs: {V_abs}") + end +end diff --git a/tests/nest_tests/resources/RecordableVariables.nestml b/tests/nest_tests/resources/RecordableVariables.nestml new file mode 100644 index 000000000..d1c00e4a2 --- /dev/null +++ b/tests/nest_tests/resources/RecordableVariables.nestml @@ -0,0 +1,69 @@ +""" +RecordableVariables.nestml +########################## + +Description ++++++++++++ + +This model is used to test recording of variables and inline expressions. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron recordable_variables: + state: + V_ex mV = -5 mV + V_abs mV = 0 mV # membrane potential + end + + equations: + kernel I_kernel = exp(-1/tau_syn*t) + inline I_syn pA = convolve(I_kernel, spikes) + recordable inline V_m mV = V_abs + V_reset + V_abs' = -V_abs / tau_m + (I_syn + I_e + I_stim) / C_m + end + + parameters: + tau_m ms = 10 ms + tau_syn ms = 2 ms + I_e pA = 0 pA + C_m pF = 250pF + V_reset mV = -70 mV + V_thr mV = -55 mV + end + + input: + spikes pA <- spike + I_stim pA <- continuous + end + + update: + integrate_odes() + V_ex = -10 mV + + if V_abs >= V_thr: + V_abs = V_reset + emit_spike() + end + end + + output: spike +end diff --git a/tests/nest_tests/resources/SimplePrintStatement.nestml b/tests/nest_tests/resources/SimplePrintStatement.nestml new file mode 100644 index 000000000..8da7b8de3 --- /dev/null +++ b/tests/nest_tests/resources/SimplePrintStatement.nestml @@ -0,0 +1,30 @@ +""" +SimplePrintStatement.nestml +########################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron simple_print_test: + update: + print("This is a simple print statement") + end +end diff --git a/tests/nest_tests/resources/SimpleVectorsModel.nestml b/tests/nest_tests/resources/SimpleVectorsModel.nestml new file mode 100644 index 000000000..28500a57f --- /dev/null +++ b/tests/nest_tests/resources/SimpleVectorsModel.nestml @@ -0,0 +1,36 @@ +""" + +SimpleVectorsModel.nestml +######################### + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . + +""" + +neuron simple_vectors_model: + state: + g_ex [20] real = 1.2 + end + + update: + g_ex[2] = 10.5 + end +end \ No newline at end of file diff --git a/tests/nest_tests/resources/Vectors.nestml b/tests/nest_tests/resources/Vectors.nestml new file mode 100644 index 000000000..8c09371a7 --- /dev/null +++ b/tests/nest_tests/resources/Vectors.nestml @@ -0,0 +1,52 @@ +""" +Vectors.nestml +############## + + +Description ++++++++++++ + +This model is used to test vector operations with NEST. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron vectors: + state: + V_m mV = 0 mV + g_in [20] mV = 11mV + g_ex [ten] mV = 1mV + end + + parameters: + taus [15] ms = 2 ms + V_thr mV = -55 mV + ten integer = 10 + end + + update: + i integer = 0 + g_ex[1] = -2 mV + i = 1 + V_m += -0.03 mV + end +end diff --git a/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml b/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml new file mode 100644 index 000000000..781858c48 --- /dev/null +++ b/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml @@ -0,0 +1,48 @@ +""" + +VectorsDeclarationAndAssignment.nestml +###################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration +are detected. +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . + +""" + +neuron vector_declaration: + state: + g_in [20] mV = 11mV + g_ex [ten] mV = 1mV + end + + parameters: + taus [15] ms = 2 ms + V_thr mV = -55 mV + ten integer = 10 + end +end diff --git a/tests/nest_tests/resources/VectorsResize.nestml b/tests/nest_tests/resources/VectorsResize.nestml new file mode 100644 index 000000000..2564ba571 --- /dev/null +++ b/tests/nest_tests/resources/VectorsResize.nestml @@ -0,0 +1,52 @@ +""" +VectorsResize.nestml +#################### + + +Description ++++++++++++ + +This model is used to test vector operations with NEST. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron vector_resize: + state: + # accumulator for x values + y real = 0. + + x[N] real = 1. + end + + parameters: + N integer = 1 # array size + end + + update: + j integer = 0 + y = 0 + for j in 0 ... N step 1: + y += x[j] + end + print ("y= {y}\n") + end +end diff --git a/tests/nest_tests/resources/WhileLoop.nestml b/tests/nest_tests/resources/WhileLoop.nestml new file mode 100644 index 000000000..8c0865968 --- /dev/null +++ b/tests/nest_tests/resources/WhileLoop.nestml @@ -0,0 +1,46 @@ +""" +WhileLoop.nestml +################ + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron while_loop: + state: + y real = 0.025 + end + + parameters: + N integer = 5 + end + + update: + k integer = 3 + j integer = 0 + while j <= N: + y = max(k, j) + y += 0.011 + j += 1 + end + end + +end diff --git a/tests/nest_tests/resources/cm_default.nestml b/tests/nest_tests/resources/cm_default.nestml new file mode 100644 index 000000000..47a3cc374 --- /dev/null +++ b/tests/nest_tests/resources/cm_default.nestml @@ -0,0 +1,196 @@ +""" +Example compartmental model for NESTML + +Description ++++++++++++ +Corresponds to standard compartmental model implemented in NEST. + +References +++++++++++ + + +See also +++++++++ + + +Author +++++++ +Willem Wybo +""" +neuron cm_default: + + state: + + # the presence of the state variable [v_comp] + # triggers compartment model context + v_comp real = 0 + + ### ion channels ### + # initial values state variables sodium channel + m_Na real = 0.0 + h_Na real = 0.0 + + # initial values state variables potassium channel + n_K real = 0.0 + + end + + + parameters: + ### ion channels ### + # default parameters sodium channel + e_Na real = 50.0 + gbar_Na real = 0.0 + + # default parameters potassium channel + e_K real = -85.0 + gbar_K real = 0.0 + + ### synapses ### + e_AMPA real = 0 mV # Excitatory reversal Potential + tau_r_AMPA real = 0.2 ms # Synaptic Time Constant Excitatory Synapse + tau_d_AMPA real = 3.0 ms # Synaptic Time Constant Excitatory Synapse + + e_GABA real = -80. mV # Inhibitory reversal Potential + tau_r_GABA real = 0.2 ms # Synaptic Time Constant Inhibitory Synapse + tau_d_GABA real = 10.0 ms # Synaptic Time Constant Inhibitory Synapse + + e_NMDA real = 0 mV # NMDA reversal Potential + tau_r_NMDA real = 0.2 ms # Synaptic Time Constant NMDA Synapse + tau_d_NMDA real = 43.0 ms # Synaptic Time Constant NMDA Synapse + + e_AN_AMPA real = 0 mV # Excitatory reversal Potential + tau_r_AN_AMPA real = 0.2 ms # Synaptic Time Constant Excitatory Synapse + tau_d_AN_AMPA real = 3.0 ms # Synaptic Time Constant Excitatory Synapse + e_AN_NMDA real = 0 mV # NMDA reversal Potential + tau_r_AN_NMDA real = 0.2 ms # Synaptic Time Constant NMDA Synapse + tau_d_AN_NMDA real = 43.0 ms # Synaptic Time Constant NMDA Synapse + NMDA_ratio real = 2.0 # NMDA_ratio + end + + equations: + """ + Here, we define the currents that are present in the model. Currents may, + or may not depend on [v_comp]. Each variable in the equation for the currents + must correspond either to a parameter (e.g. [gbar_Na], [e_Na], e_[NMDA], etc...) + or to a state variable (e.g [m_Na], [n_K], [g_r_AMPA], etc...). + + When it is a parameter, it must be configurable from Python, by adding it as + a key: value pair to the dictionary argument of `nest.AddCompartment` for an + ion channel or of `nest.AddReceptor` for a synapse. + + State variables must reoccur in the initial values block and have an associated + equation in the equations block. + + Internally, the model must compute the pair of values (g_val, i_val) for the + integration algorithm. To do so, we need both the equation for current, and + its voltage derivative + + i_X + d(i_X)/dv + + Which we should be able to obtain from sympy trough symbolic differentiation. + Then, + + g_val = d(i_X)/d(v_comp) / 2. + i_val = i_X - d(i_X)/d(v_comp) / 2. + + """ + ### ion channels, recognized by lack of convolutions ### + inline Na real = gbar_Na * m_Na**3 * h_Na**1 * (e_Na - v_comp) + inline K real = gbar_K * n_K * (e_K - v_comp) + + ### synapses, characterized by convolution(s) with spike input ### + kernel g_AMPA = g_norm_AMPA * ( - exp(-t / tau_r_AMPA) + exp(-t / tau_d_AMPA) ) + inline AMPA real = convolve(g_AMPA, spikes_AMPA) * (e_AMPA - v_comp) + + kernel g_GABA = g_norm_GABA * ( - exp(-t / tau_r_GABA) + exp(-t / tau_d_GABA) ) + inline GABA real = convolve(g_GABA, spikes_GABA) * (e_GABA - v_comp ) + + kernel g_NMDA = g_norm_NMDA * ( - exp(-t / tau_r_NMDA) + exp(-t / tau_d_NMDA) ) + inline NMDA real = convolve(g_NMDA, spikes_NMDA) * (e_NMDA - v_comp ) / (1. + 0.3 * exp( -.1 * v_comp )) + + kernel g_AN_AMPA = g_norm_AN_AMPA * ( - exp(-t / tau_r_AN_AMPA) + exp(-t / tau_d_AN_AMPA) ) + kernel g_AN_NMDA = g_norm_AN_NMDA * ( - exp(-t / tau_r_AN_NMDA) + exp(-t / tau_d_AN_NMDA) ) + inline AMPA_NMDA real = convolve(g_AN_AMPA, spikes_AN) * (e_AN_AMPA - v_comp) + NMDA_ratio * \ + convolve(g_AN_NMDA, spikes_AN) * (e_AN_NMDA - v_comp) / (1. + 0.3 * exp( -.1 * v_comp )) + end + + # #sodium + # function m_inf_Na(v_comp real) real: + # return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + # end + + # function tau_m_Na(v_comp real) real: + # return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + # end + + # function h_inf_Na(v_comp real) real: + # return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + # end + + # function tau_h_Na(v_comp real) real: + # return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + # end + + # #potassium + # function n_inf_K(v_comp real) real: + # return 0.02*(v_comp - 25.0)/((1.0 - exp((25.0 - v_comp)/9.0))*((-0.002)*(v_comp - 25.0)/(1.0 - exp((v_comp - 25.0)/9.0)) + 0.02*(v_comp - 25.0)/(1.0 - exp((25.0 - v_comp)/9.0)))) + # end + + # function tau_n_K(v_comp real) real: + # return 0.3115264797507788/((-0.002)*(v_comp - 25.0)/(1.0 - exp((v_comp - 25.0)/9.0)) + 0.02*(v_comp - 25.0)/(1.0 - exp((25.0 - v_comp)/9.0))) + # end + + # functions K + function n_inf_K (v_comp real) real: + return 0.02*(1.0 - exp(0.111111111111111*(25.0 - v_comp)))**(-1)*(-0.002*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(-25.0 + v_comp)))**(-1) + 0.02*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(25.0 - v_comp)))**(-1))**(-1)*(-25.0 + v_comp) + end + function tau_n_K (v_comp real) real: + return 0.311526479750779*(-0.002*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(-25.0 + v_comp)))**(-1) + 0.02*(-25.0 + v_comp)*(1.0 - exp(0.111111111111111*(25.0 - v_comp)))**(-1))**(-1) + end + + # functions Na + function m_inf_Na (v_comp real) real: + return (1.0 - 0.020438532058318*exp(-0.111111111111111*v_comp))**(-1)*((1.0 - 0.020438532058318*exp(-0.111111111111111*v_comp))**(-1)*(6.372366 + 0.182*v_comp) + (1.0 - 48.9271928701465*exp(0.111111111111111*v_comp))**(-1)*(-4.341612 - 0.124*v_comp))**(-1)*(6.372366 + 0.182*v_comp) + end + function tau_m_Na (v_comp real) real: + return 0.311526479750779*((1.0 - 0.020438532058318*exp(-0.111111111111111*v_comp))**(-1)*(6.372366 + 0.182*v_comp) + (1.0 - 48.9271928701465*exp(0.111111111111111*v_comp))**(-1)*(-4.341612 - 0.124*v_comp))**(-1) + end + function h_inf_Na (v_comp real) real: + return 1.0*(1.0 + 35734.4671267926*exp(0.161290322580645*v_comp))**(-1) + end + function tau_h_Na (v_comp real) real: + return 0.311526479750779*((1.0 - 4.52820432639598e-5*exp(-0.2*v_comp))**(-1)*(1.200312 + 0.024*v_comp) + (1.0 - 3277527.87650153*exp(0.2*v_comp))**(-1)*(-0.6826183 - 0.0091*v_comp))**(-1) + end + + internals: + tp_AMPA real = (tau_r_AMPA * tau_d_AMPA) / (tau_d_AMPA - tau_r_AMPA) * ln( tau_d_AMPA / tau_r_AMPA ) + g_norm_AMPA real = 1. / ( -exp( -tp_AMPA / tau_r_AMPA ) + exp( -tp_AMPA / tau_d_AMPA ) ) + + tp_GABA real = (tau_r_GABA * tau_d_GABA) / (tau_d_GABA - tau_r_GABA) * ln( tau_d_GABA / tau_r_GABA ) + g_norm_GABA real = 1. / ( -exp( -tp_GABA / tau_r_GABA ) + exp( -tp_GABA / tau_d_GABA ) ) + + tp_NMDA real = (tau_r_NMDA * tau_d_NMDA) / (tau_d_NMDA - tau_r_NMDA) * ln( tau_d_NMDA / tau_r_NMDA ) + g_norm_NMDA real = 1. / ( -exp( -tp_NMDA / tau_r_NMDA ) + exp( -tp_NMDA / tau_d_NMDA ) ) + + tp_AN_AMPA real = (tau_r_AN_AMPA * tau_d_AN_AMPA) / (tau_d_AN_AMPA - tau_r_AN_AMPA) * ln( tau_d_AN_AMPA / tau_r_AN_AMPA ) + g_norm_AN_AMPA real = 1. / ( -exp( -tp_AN_AMPA / tau_r_AN_AMPA ) + exp( -tp_AN_AMPA / tau_d_AN_AMPA ) ) + + tp_AN_NMDA real = (tau_r_AN_NMDA * tau_d_AN_NMDA) / (tau_d_AN_NMDA - tau_r_AN_NMDA) * ln( tau_d_AN_NMDA / tau_r_AN_NMDA ) + g_norm_AN_NMDA real = 1. / ( -exp( -tp_AN_NMDA / tau_r_AN_NMDA ) + exp( -tp_AN_NMDA / tau_d_AN_NMDA ) ) + end + + input: + spikes_AMPA uS <- spike + spikes_GABA uS <- spike + spikes_NMDA uS <- spike + spikes_AN uS <- spike + end + + output: spike + + update: + end + +end \ No newline at end of file diff --git a/tests/nest_tests/resources/code_options.json b/tests/nest_tests/resources/code_options.json new file mode 100644 index 000000000..906170394 --- /dev/null +++ b/tests/nest_tests/resources/code_options.json @@ -0,0 +1 @@ +{"templates": {"path": "point_neuron", "model_templates": {"neuron": ["@NEURON_NAME@.cpp.jinja2", "@NEURON_NAME@.h.jinja2"], "synapse": []}, "module_templates": ["setup/CMakeLists.txt.jinja2", "setup/@MODULE_NAME@.h.jinja2", "setup/@MODULE_NAME@.cpp.jinja2"]}} \ No newline at end of file diff --git a/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml b/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml index 9e8ade2e3..144806d5f 100644 --- a/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml +++ b/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml @@ -13,10 +13,7 @@ For more information about "multisynapse" models, please refer to the NESTML doc """ neuron iaf_psc_exp_multisynapse_neuron: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0 mV # membrane potential end @@ -57,7 +54,7 @@ neuron iaf_psc_exp_multisynapse_neuron: spikes1 pA <- spike spikes2 pA <- spike spikes3 pA <- spike - I_stim pA <- current + I_stim pA <- continuous end output: spike diff --git a/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml b/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml new file mode 100644 index 000000000..41bc1c6ac --- /dev/null +++ b/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml @@ -0,0 +1,109 @@ +""" +iaf_psc_exp_nonlineardendrite.nestml +#################################### + +Description ++++++++++++ + +Neuron model used in ``non_linear_dendrite_test.py``. + +A dendritic action potential occurs when the net synaptic current exceeds the threshold value ``i_th``. An extra, pulse-shaped dendritic current is then activated with amplitude ``I_dend_ap`` and duration ``T_dend_ap``. + +For more detailed information and references, please see the active dendrite tutorial at ``doc/tutorials/active_dendrite/nestml_active_dendrite_tutorial.ipynb``. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron iaf_psc_exp_nonlineardendrite: + + state: + V_m mV = 0 mV # membrane potential + t_dend_ap ms = 0 ms # dendritic action potential timer + dend_curr_enabled real = 1. # set to 1 to allow synaptic dendritic currents to contribute to V_m integration, 0 otherwise + I_dend_ap pA = 0 pA + end + + equations: + kernel I_kernel1 = exp(-t / tau_syn1) + kernel I_kernel2 = (e / tau_syn2) * t * exp(-t / tau_syn2) + kernel I_kernel3 = exp(-t / tau_syn3) + + recordable inline I_dend pA = convolve(I_kernel2, I_2) + + inline I_syn pA = convolve(I_kernel1, I_1) + dend_curr_enabled * I_dend + I_dend_ap + convolve(I_kernel3, I_3) + I_e + + V_m' = -(V_m - E_L) / tau_m + I_syn / C_m + end + + parameters: + C_m pF = 250 pF # capacity of the membrane + tau_m ms = 20 ms # membrane time constant + tau_syn1 ms = 10 ms # time constant of synaptic current, port 1 + tau_syn2 ms = 10 ms # time constant of synaptic current, port 2 + tau_syn3 ms = 10 ms # time constant of synaptic current, port 3 + V_th mV = 25 mV # action potential threshold + V_reset mV = 0 mV # reset voltage + I_e pA = 0 pA # external current + E_L mV = 0 mV # resting potential + + # dendritic action potential + i_th pA = 60 pA # current-threshold for a dendritic action potential + i_dend_ap pA = 150 pA # current clamp value for I_dend during a dendritic action potential + T_dend_ap ms = 10 ms # time window over which the dendritic current clamp is active + end + + input: + I_1 pA <- spike + I_2 pA <- spike + I_3 pA <- spike + end + + output: spike + + update: + # solve ODEs + integrate_odes() + + if t_dend_ap > 0 ms: + t_dend_ap -= resolution() + if t_dend_ap <= 0 ms: + t_dend_ap = 0 ms + dend_curr_enabled = 1. + I_dend = 0 pA + I_dend' = 0 pA/ms + I_dend_ap = 0 pA + end + end + + if I_dend > i_th: + # current-threshold, emit a dendritic action potential + dend_curr_enabled = 0. + t_dend_ap = T_dend_ap + I_dend_ap = i_dend_ap + end + + # emit somatic action potential + if V_m > V_th: + emit_spike() + V_m = V_reset + end + end +end + diff --git a/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml b/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml new file mode 100644 index 000000000..b294ad921 --- /dev/null +++ b/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml @@ -0,0 +1,71 @@ +""" +iaf_psc_exp_resolution_test +########################### + +Description ++++++++++++ + +Used to test resolution() function. +""" +neuron iaf_psc_exp_resolution_test: + + state: + r integer = 0 # counts number of tick during the refractory period + V_abs mV = 0 mV + a ms = resolution() + end + + equations: + kernel I_kernel_inh = exp(-t/tau_syn_inh) + kernel I_kernel_exc = exp(-t/tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential. + inline I_syn pA = convolve(I_kernel_inh, inh_spikes) + convolve(I_kernel_exc, exc_spikes) + I_e + I_stim + V_abs' = -V_abs / tau_m + I_syn / C_m + end + + parameters: + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of synaptic current + tau_syn_exc ms = 2 ms # Time constant of synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential + V_reset mV = -70 mV - E_L # reset value of the membrane potential + Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!) + # I.e. the real threshold is E_L + Theta + + # constant external input current + I_e pA = 0 pA + b ms = resolution() + end + + internals: + RefractoryCounts integer = steps(t_ref) # refractory time in steps + c ms = resolution() + end + + input: + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous + end + + output: spike + + update: + d ms = resolution() + if r == 0: # neuron not refractory, so evolve V + integrate_odes() + else: + r = r - 1 # neuron is absolute refractory + end + + if V_abs >= Theta: # threshold crossing + r = RefractoryCounts + V_abs = V_reset + emit_spike() + end + + end + +end diff --git a/tests/nest_tests/resources/nest_codegen_opts.json b/tests/nest_tests/resources/nest_codegen_opts.json new file mode 100644 index 000000000..6425aeaa8 --- /dev/null +++ b/tests/nest_tests/resources/nest_codegen_opts.json @@ -0,0 +1,4 @@ +{ + "nest_path": "%NEST_PATH%", + "nest_version": "%NEST_VERSION%" +} diff --git a/tests/nest_tests/resources/print_variable_script.py b/tests/nest_tests/resources/print_variable_script.py new file mode 100644 index 000000000..02d3079d5 --- /dev/null +++ b/tests/nest_tests/resources/print_variable_script.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# print_variable_script.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os +import nest +import shutil + +from pynestml.frontend.pynestml_frontend import generate_nest_target + +input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), "PrintVariables.nestml"))) +target_path = "target" +logging_level = "INFO" +module_name = "nestmlmodule" +suffix = "_nestml" + +generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) +nest.set_verbosity("M_ALL") + +nest.ResetKernel() +nest.Install(module_name) + +neuron = nest.Create("print_variable_nestml") +nest.Simulate(0.1) + +if os.path.exists(target_path): + shutil.rmtree(target_path) diff --git a/tests/nest_tests/stdp_neuromod_test.py b/tests/nest_tests/stdp_neuromod_test.py new file mode 100644 index 000000000..3639be0bb --- /dev/null +++ b/tests/nest_tests/stdp_neuromod_test.py @@ -0,0 +1,341 @@ +# -*- coding: utf-8 -*- +# +# stdp_neuromod_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use("Agg") + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + +sim_mdl = True +sim_ref = True + + +class NestSTDPNeuromodTest(unittest.TestCase): + r""" + Test the neuromodulated (for instance, dopamine-modulated) synapse, by numerically comparing it to the NEST "stdp_dopamine" synapse in a representative simulation run. + """ + + neuron_model_name = "iaf_psc_exp_nestml__with_neuromodulated_stdp_nestml" + synapse_model_name = "neuromodulated_stdp_nestml__with_iaf_psc_exp_nestml" + + ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit" + ref_synapse_model_name = "stdp_dopamine_synapse" + + def setUp(self): + r"""generate code for neuron and synapse and build NEST user module""" + files = [os.path.join("models", "neurons", "iaf_psc_exp.nestml"), + os.path.join("models", "synapses", "neuromodulated_stdp.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "neuromodulated_stdp", + "post_ports": ["post_spikes"], + "vt_ports": ["mod_spikes"]}]}) + + generate_nest_target(input_path=os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, os.pardir, "models", "neurons", "iaf_psc_exp.nestml"))), + target_path="/tmp/nestml-non-jit", + logging_level="INFO", + module_name="nestml_non_jit_module", + suffix="_nestml_non_jit", + codegen_opts={"neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h"}) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_nest_stdp_synapse(self): + + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + vt_spike_times = [14., 23.] # [ms] + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + ref_neuron_model_name=self.ref_neuron_model_name, + synapse_model_name=self.synapse_model_name, + ref_synapse_model_name=self.ref_synapse_model_name, + resolution=.1, # [ms] + delay=1., # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + vt_spike_times=vt_spike_times, + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + ref_neuron_model_name, + synapse_model_name, + ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + vt_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if vt_spike_times is None: + vt_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times, initial=0.), np.amax( + post_spike_times, initial=0.), np.amax(vt_spike_times, initial=0.)) + 5 * delay + + nest.ResetKernel() + # nest.set_verbosity("M_ALL") + nest.set_verbosity("M_ERROR") + nest.SetKernelStatus({"resolution": resolution}) + nest.Install("nestml_jit_module") + nest.Install("nestml_non_jit_module") + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + print("VT spike times: " + str(vt_spike_times)) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times, + "allow_offgrid_times": True}) + vt_sg = nest.Create("spike_generator", + params={"spike_times": vt_spike_times, + "allow_offgrid_times": True}) + + # create volume transmitter + vt = nest.Create("volume_transmitter") + vt_parrot = nest.Create("parrot_neuron") + nest.Connect(vt_sg, vt_parrot) + nest.Connect(vt_parrot, vt, syn_spec={"synapse_model": "static_synapse", + "weight": 1., + "delay": 1.}) # delay is ignored?! + vt_gid = vt.get("global_id") + + # set up custom synapse models + wr = nest.Create("weight_recorder") + wr_ref = nest.Create('weight_recorder') + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": delay, "receptor_type": 0, + "vt": vt_gid}) + nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec", + {"weight_recorder": wr_ref[0], "weight": 1., "delay": delay, "receptor_type": 0, + "vt": vt_gid}) + + # create parrot neurons and connect spike_generators + if sim_mdl: + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if sim_ref: + pre_neuron_ref = nest.Create("parrot_neuron") + post_neuron_ref = nest.Create(ref_neuron_model_name) + + if sim_mdl: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + spikedet_vt = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": ["V_m", "post_tr__for_neuromodulated_stdp_nestml"]}) + + if sim_ref: + spikedet_pre_ref = nest.Create("spike_recorder") + spikedet_post_ref = nest.Create("spike_recorder") + mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + if sim_mdl: + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + nest.Connect(vt_parrot, spikedet_vt) + if sim_ref: + nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", syn_spec={"synapse_model": "stdp_ref_rec"}) + nest.Connect(mm_ref, post_neuron_ref) + nest.Connect(pre_neuron_ref, spikedet_pre_ref) + nest.Connect(post_neuron_ref, spikedet_post_ref) + + # get STDP synapse and weight before protocol + if sim_mdl: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + if sim_ref: + syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model="stdp_ref_rec") + + n_steps = int(np.ceil(sim_time / resolution)) + 1 + t = 0. + t_hist = [] + if sim_mdl: + w_hist = [] + if sim_ref: + w_hist_ref = [] + while t <= sim_time: + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + if sim_ref: + w_hist_ref.append(nest.GetStatus(syn_ref)[0]["weight"]) + if sim_mdl: + w_hist.append(nest.GetStatus(syn)[0]["w"]) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=2) + ax1, ax2 = ax + + if sim_mdl: + timevec = nest.GetStatus(mm, "events")[0]["times"] + V_m = nest.GetStatus(mm, "events")[0]["V_m"] + ax2.plot(timevec, nest.GetStatus(mm, "events")[ + 0]["post_tr__for_neuromodulated_stdp_nestml"], label="post_tr nestml") + ax1.plot(timevec, V_m, label="nestml", alpha=.7, linestyle=":") + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + timevec = nest.GetStatus(mm_ref, "events")[0]["times"] + V_m = nest.GetStatus(mm_ref, "events")[0]["V_m"] + ax1.plot(timevec, V_m, label="nest ref", alpha=.7) + ax1.set_ylabel("V_m") + + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.grid(which="minor", axis="x", linestyle=":", alpha=.4) + # _ax.minorticks_on() + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_synapse_test" + fname_snip + "_V_m.png", dpi=300) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=4) + ax1, ax2, ax3, ax4 = ax + + if sim_mdl: + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + print("Actual pre ref spike times: " + str(pre_ref_spike_times_)) + + if sim_mdl: + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4, label=_lbl) + + if sim_mdl: + post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"] + print("Actual post spike times: " + str(post_spike_times_)) + if sim_ref: + post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"] + print("Actual post ref spike times: " + str(post_ref_spike_times_)) + + if sim_ref: + n_spikes = len(pre_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], + linewidth=2, color="cyan", label=_lbl, alpha=.4) + ax1.set_ylabel("Pre spikes") + + ax2.plot(timevec, nest.GetStatus(mm, "events")[ + 0]["post_tr__for_neuromodulated_stdp_nestml"], label="nestml post tr") + if sim_mdl: + n_spikes = len(post_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax2.plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl) + if sim_ref: + n_spikes = len(post_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax2.plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl) + ax2.set_ylabel("Post spikes") + + if sim_mdl: + vt_spike_times_ = nest.GetStatus(spikedet_vt, "events")[0]["times"] + print("Actual vt spike times: " + str(vt_spike_times_)) + + if sim_mdl: + n_spikes = len(vt_spike_times_) + for i in range(n_spikes): + ax3.plot(2 * [vt_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4) + ax3.set_ylabel("VT spikes") + + if sim_mdl: + ax4.plot(t_hist, w_hist, marker="o", label="nestml") + if sim_ref: + ax4.plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref") + ax4.set_xlabel("Time [ms]") + ax4.set_ylabel("w") + + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_dopa_synapse_test" + fname_snip + ".png", dpi=300) + + # verify + MAX_ABS_ERROR = 1E-6 + assert np.all(np.abs(np.array(w_hist) - np.array(w_hist_ref)) < MAX_ABS_ERROR) diff --git a/tests/nest_tests/stdp_nn_pre_centered_test.py b/tests/nest_tests/stdp_nn_pre_centered_test.py new file mode 100644 index 000000000..de67f42c9 --- /dev/null +++ b/tests/nest_tests/stdp_nn_pre_centered_test.py @@ -0,0 +1,308 @@ +# -*- coding: utf-8 -*- +# +# stdp_nn_pre_centered_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use('Agg') + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + +sim_mdl = True +sim_ref = True + + +class NestSTDPNNSynapseTest(unittest.TestCase): + + neuron_model_name = "iaf_psc_exp_nestml__with_stdp_nn_pre_centered_nestml" + ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit" + + synapse_model_name = "stdp_nn_pre_centered_nestml__with_iaf_psc_exp_nestml" + ref_synapse_model_name = "stdp_nn_pre_centered_synapse" + + def setUp(self): + r"""Generate the neuron model code""" + + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + files = [os.path.join("models", "neurons", "iaf_psc_exp.nestml"), + os.path.join("models", "synapses", "stdp_nn_pre_centered.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "stdp_nn_pre_centered", + "post_ports": ["post_spikes"]}]}) + + # generate the "non-jit" model, that relies on ArchivingNode + + generate_nest_target(input_path=os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, os.pardir, "models", "neurons", "iaf_psc_exp.nestml"))), + target_path="/tmp/nestml-non-jit", + logging_level="INFO", + module_name="nestml_non_jit_module", + suffix="_nestml_non_jit", + codegen_opts={"neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h"}) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_stdp_nn_synapse(self): + + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + + pre_spike_times = np.array([2., 4., 7., 8., 12., 13., 19., 23., 24., 28., 29., 30., 33., 34., + 35., 36., 38., 40., 42., 46., 51., 53., 54., 55., 56., 59., 63., 64., + 65., 66., 68., 72., 73., 76., 79., 80., 83., 84., 86., 87., 90., 95., + 99., 100., 103., 104., 105., 111., 112., 126., 131., 133., 134., 139., 147., 150., + 152., 155., 172., 175., 176., 181., 196., 197., 199., 202., 213., 215., 217., 265.]) + post_spike_times = np.array([4., 5., 6., 7., 10., 11., 12., 16., 17., 18., 19., 20., 22., 23., + 25., 27., 29., 30., 31., 32., 34., 36., 37., 38., 39., 42., 44., 46., + 48., 49., 50., 54., 56., 57., 59., 60., 61., 62., 67., 74., 76., 79., + 80., 81., 83., 88., 93., 94., 97., 99., 100., 105., 111., 113., 114., 115., + 116., 119., 123., 130., 132., 134., 135., 145., 152., 155., 158., 166., 172., 174., + 188., 194., 202., 245., 249., 289., 454.]) + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + ref_neuron_model_name=self.ref_neuron_model_name, + synapse_model_name=self.synapse_model_name, + ref_synapse_model_name=self.ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + ref_neuron_model_name, + synapse_model_name, + ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 5 * delay + + nest.set_verbosity("M_ALL") + nest.ResetKernel() + if sim_mdl: + nest.Install("nestml_jit_module") + if sim_ref: + nest.Install("nestml_non_jit_module") + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + + nest.set_verbosity("M_WARNING") + + post_weights = {'parrot': []} + + nest.ResetKernel() + nest.SetKernelStatus({'resolution': resolution}) + + wr = nest.Create('weight_recorder') + wr_ref = nest.Create('weight_recorder') + if sim_mdl: + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0}) + if sim_ref: + nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec", + {"weight_recorder": wr_ref[0], "weight": 1., "delay": 1., "receptor_type": 0}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times, + 'allow_offgrid_times': True}) + + # create parrot neurons and connect spike_generators + if sim_mdl: + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if sim_ref: + pre_neuron_ref = nest.Create("parrot_neuron") + post_neuron_ref = nest.Create(ref_neuron_model_name) + + if sim_mdl: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": [ + "V_m", "post_trace__for_stdp_nn_pre_centered_nestml"]}) + if sim_ref: + spikedet_pre_ref = nest.Create("spike_recorder") + spikedet_post_ref = nest.Create("spike_recorder") + mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + if sim_mdl: + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={'synapse_model': 'stdp_nestml_rec'}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + if sim_ref: + nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={'synapse_model': ref_synapse_model_name}) + nest.Connect(mm_ref, post_neuron_ref) + nest.Connect(pre_neuron_ref, spikedet_pre_ref) + nest.Connect(post_neuron_ref, spikedet_post_ref) + + # get STDP synapse and weight before protocol + if sim_mdl: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + if sim_ref: + syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model=ref_synapse_model_name) + + n_steps = int(np.ceil(sim_time / resolution)) + 1 + t = 0. + t_hist = [] + if sim_mdl: + w_hist = [] + if sim_ref: + w_hist_ref = [] + while t <= sim_time: + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + if sim_ref: + w_hist_ref.append(nest.GetStatus(syn_ref)[0]['weight']) + if sim_mdl: + w_hist.append(nest.GetStatus(syn)[0]['w']) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=3) + ax1, ax2, ax3 = ax + + if sim_mdl: + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + print("Actual pre ref spike times: " + str(pre_ref_spike_times_)) + + if sim_mdl: + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4, label=_lbl) + + if sim_mdl: + post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"] + print("Actual post spike times: " + str(post_spike_times_)) + if sim_ref: + post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"] + print("Actual post ref spike times: " + str(post_ref_spike_times_)) + + if sim_ref: + n_spikes = len(pre_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], + linewidth=2, color="cyan", label=_lbl, alpha=.4) + ax1.set_ylabel("Pre spikes") + + if sim_mdl: + n_spikes = len(post_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax2.plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl) + if sim_ref: + n_spikes = len(post_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax2.plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl) + if sim_mdl: + ax2.plot(nest.GetStatus(mm, "events")[0]["times"], nest.GetStatus(mm, "events")[ + 0]["post_trace__for_stdp_nn_pre_centered_nestml"], label="nestml post tr") + ax2.set_ylabel("Post spikes") + + if sim_mdl: + ax3.plot(t_hist, w_hist, marker="o", label="nestml") + if sim_ref: + ax3.plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref") + + ax3.set_xlabel("Time [ms]") + ax3.set_ylabel("w") + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_synapse_test" + fname_snip + ".png", dpi=300) + + # verify + MAX_ABS_ERROR = 1E-6 + assert np.all(np.abs(np.array(w_hist) - np.array(w_hist_ref)) < MAX_ABS_ERROR) diff --git a/tests/nest_tests/stdp_nn_restr_symm_test.py b/tests/nest_tests/stdp_nn_restr_symm_test.py new file mode 100644 index 000000000..6b51dbd57 --- /dev/null +++ b/tests/nest_tests/stdp_nn_restr_symm_test.py @@ -0,0 +1,306 @@ +# -*- coding: utf-8 -*- +# +# stdp_nn_restr_symm_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use('Agg') + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + +sim_mdl = True +sim_ref = True + + +class NestSTDPNNRestrSymmSynapseTest(unittest.TestCase): + + neuron_model_name = "iaf_psc_exp_nestml__with_stdp_nn_restr_symm_nestml" + ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit" + + synapse_model_name = "stdp_nn_restr_symm_nestml__with_iaf_psc_exp_nestml" + ref_synapse_model_name = "stdp_nn_restr_synapse" + + def setUp(self): + r"""Generate the neuron model code""" + + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + files = [os.path.join("models", "neurons", "iaf_psc_exp.nestml"), + os.path.join("models", "synapses", "stdp_nn_restr_symm.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "stdp_nn_restr_symm", + "post_ports": ["post_spikes"]}]}) + + # generate the "non-jit" model, that relies on ArchivingNode + generate_nest_target(input_path=os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, os.pardir, "models", "neurons", "iaf_psc_exp.nestml"))), + target_path="/tmp/nestml-non-jit", + logging_level="INFO", + module_name="nestml_non_jit_module", + suffix="_nestml_non_jit", + codegen_opts={"neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h"}) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_stdp_nn_synapse(self): + + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + + pre_spike_times = np.array([2., 4., 7., 8., 12., 13., 19., 23., 24., 28., 29., 30., 33., 34., + 35., 36., 38., 40., 42., 46., 51., 53., 54., 55., 56., 59., 63., 64., + 65., 66., 68., 72., 73., 76., 79., 80., 83., 84., 86., 87., 90., 95., + 99., 100., 103., 104., 105., 111., 112., 126., 131., 133., 134., 139., 147., 150., + 152., 155., 172., 175., 176., 181., 196., 197., 199., 202., 213., 215., 217., 265.]) + post_spike_times = np.array([4., 5., 6., 7., 10., 11., 12., 16., 17., 18., 19., 20., 22., 23., + 25., 27., 29., 30., 31., 32., 34., 36., 37., 38., 39., 42., 44., 46., + 48., 49., 50., 54., 56., 57., 59., 60., 61., 62., 67., 74., 76., 79., + 80., 81., 83., 88., 93., 94., 97., 99., 100., 105., 111., 113., 114., 115., + 116., 119., 123., 130., 132., 134., 135., 145., 152., 155., 158., 166., 172., 174., + 188., 194., 202., 245., 249., 289., 454.]) + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + ref_neuron_model_name=self.ref_neuron_model_name, + synapse_model_name=self.synapse_model_name, + ref_synapse_model_name=self.ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + ref_neuron_model_name, + synapse_model_name, + ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 5 * delay + + nest.set_verbosity("M_ALL") + nest.ResetKernel() + if sim_mdl: + nest.Install("nestml_jit_module") + if sim_ref: + nest.Install("nestml_non_jit_module") + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + + nest.set_verbosity("M_WARNING") + + post_weights = {'parrot': []} + + nest.ResetKernel() + nest.SetKernelStatus({'resolution': resolution}) + + wr = nest.Create('weight_recorder') + wr_ref = nest.Create('weight_recorder') + if sim_mdl: + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0}) + if sim_ref: + nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec", + {"weight_recorder": wr_ref[0], "weight": 1., "delay": 1., "receptor_type": 0}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times, + 'allow_offgrid_times': True}) + + # create parrot neurons and connect spike_generators + if sim_mdl: + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if sim_ref: + pre_neuron_ref = nest.Create("parrot_neuron") + post_neuron_ref = nest.Create(ref_neuron_model_name) + + if sim_mdl: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": ["V_m", "post_trace__for_stdp_nn_restr_symm_nestml"]}) + if sim_ref: + spikedet_pre_ref = nest.Create("spike_recorder") + spikedet_post_ref = nest.Create("spike_recorder") + mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + if sim_mdl: + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={'synapse_model': 'stdp_nestml_rec'}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + if sim_ref: + nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={'synapse_model': ref_synapse_model_name}) + nest.Connect(mm_ref, post_neuron_ref) + nest.Connect(pre_neuron_ref, spikedet_pre_ref) + nest.Connect(post_neuron_ref, spikedet_post_ref) + + # get STDP synapse and weight before protocol + if sim_mdl: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + if sim_ref: + syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model=ref_synapse_model_name) + + n_steps = int(np.ceil(sim_time / resolution)) + 1 + t = 0. + t_hist = [] + if sim_mdl: + w_hist = [] + if sim_ref: + w_hist_ref = [] + while t <= sim_time: + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + if sim_ref: + w_hist_ref.append(nest.GetStatus(syn_ref)[0]['weight']) + if sim_mdl: + w_hist.append(nest.GetStatus(syn)[0]['w']) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=3) + ax1, ax2, ax3 = ax + + if sim_mdl: + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + print("Actual pre ref spike times: " + str(pre_ref_spike_times_)) + + if sim_mdl: + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4, label=_lbl) + + if sim_mdl: + post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"] + print("Actual post spike times: " + str(post_spike_times_)) + if sim_ref: + post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"] + print("Actual post ref spike times: " + str(post_ref_spike_times_)) + + if sim_ref: + n_spikes = len(pre_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], + linewidth=2, color="cyan", label=_lbl, alpha=.4) + ax1.set_ylabel("Pre spikes") + + if sim_mdl: + n_spikes = len(post_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax2.plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl) + if sim_ref: + n_spikes = len(post_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax2.plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl) + if sim_mdl: + ax2.plot(nest.GetStatus(mm, "events")[0]["times"], nest.GetStatus(mm, "events")[ + 0]["post_trace__for_stdp_nn_restr_symm_nestml"], label="nestml post tr") + ax2.set_ylabel("Post spikes") + + if sim_mdl: + ax3.plot(t_hist, w_hist, marker="o", label="nestml") + if sim_ref: + ax3.plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref") + + ax3.set_xlabel("Time [ms]") + ax3.set_ylabel("w") + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_nn_restr_symm_test" + fname_snip + ".png", dpi=300) + + # verify + MAX_ABS_ERROR = 1E-6 + assert np.all(np.abs(np.array(w_hist) - np.array(w_hist_ref)) < MAX_ABS_ERROR) diff --git a/tests/nest_tests/stdp_nn_synapse_test.py b/tests/nest_tests/stdp_nn_synapse_test.py new file mode 100644 index 000000000..1bcaa1c28 --- /dev/null +++ b/tests/nest_tests/stdp_nn_synapse_test.py @@ -0,0 +1,306 @@ +# -*- coding: utf-8 -*- +# +# stdp_nn_synapse_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use('Agg') + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + +sim_mdl = True +sim_ref = True + + +class NestSTDPNNSynapseTest(unittest.TestCase): + + neuron_model_name = "iaf_psc_exp_nestml__with_stdp_nn_symm_nestml" + ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit" + + synapse_model_name = "stdp_nn_symm_nestml__with_iaf_psc_exp_nestml" + ref_synapse_model_name = "stdp_nn_symm_synapse" + + def setUp(self): + """Generate the neuron model code""" + + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + files = [os.path.join("models", "neurons", "iaf_psc_exp.nestml"), + os.path.join("models", "synapses", "stdp_nn_symm.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "stdp_nn_symm", + "post_ports": ["post_spikes"]}]}) + + # generate the "non-jit" model, that relies on ArchivingNode + generate_nest_target(input_path=os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, os.pardir, "models", "neurons", "iaf_psc_exp.nestml"))), + target_path="/tmp/nestml-non-jit", + logging_level="INFO", + module_name="nestml_non_jit_module", + suffix="_nestml_non_jit", + codegen_opts={"neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h"}) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_stdp_nn_synapse(self): + + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + + pre_spike_times = np.array([2., 4., 7., 8., 12., 13., 19., 23., 24., 28., 29., 30., 33., 34., + 35., 36., 38., 40., 42., 46., 51., 53., 54., 55., 56., 59., 63., 64., + 65., 66., 68., 72., 73., 76., 79., 80., 83., 84., 86., 87., 90., 95., + 99., 100., 103., 104., 105., 111., 112., 126., 131., 133., 134., 139., 147., 150., + 152., 155., 172., 175., 176., 181., 196., 197., 199., 202., 213., 215., 217., 265.]) + post_spike_times = np.array([4., 5., 6., 7., 10., 11., 12., 16., 17., 18., 19., 20., 22., 23., + 25., 27., 29., 30., 31., 32., 34., 36., 37., 38., 39., 42., 44., 46., + 48., 49., 50., 54., 56., 57., 59., 60., 61., 62., 67., 74., 76., 79., + 80., 81., 83., 88., 93., 94., 97., 99., 100., 105., 111., 113., 114., 115., + 116., 119., 123., 130., 132., 134., 135., 145., 152., 155., 158., 166., 172., 174., + 188., 194., 202., 245., 249., 289., 454.]) + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + ref_neuron_model_name=self.ref_neuron_model_name, + synapse_model_name=self.synapse_model_name, + ref_synapse_model_name=self.ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + ref_neuron_model_name, + synapse_model_name, + ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 5 * delay + + nest.set_verbosity("M_ALL") + nest.ResetKernel() + if sim_mdl: + nest.Install("nestml_jit_module") + if sim_ref: + nest.Install("nestml_non_jit_module") + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + + nest.set_verbosity("M_WARNING") + + post_weights = {'parrot': []} + + nest.ResetKernel() + nest.SetKernelStatus({'resolution': resolution}) + + wr = nest.Create('weight_recorder') + wr_ref = nest.Create('weight_recorder') + if sim_mdl: + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0}) + if sim_ref: + nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec", + {"weight_recorder": wr_ref[0], "weight": 1., "delay": 1., "receptor_type": 0}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times, + 'allow_offgrid_times': True}) + + # create parrot neurons and connect spike_generators + if sim_mdl: + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if sim_ref: + pre_neuron_ref = nest.Create("parrot_neuron") + post_neuron_ref = nest.Create(ref_neuron_model_name) + + if sim_mdl: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": ["V_m", "post_trace__for_stdp_nn_symm_nestml"]}) + if sim_ref: + spikedet_pre_ref = nest.Create("spike_recorder") + spikedet_post_ref = nest.Create("spike_recorder") + mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + if sim_mdl: + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={'synapse_model': 'stdp_nestml_rec'}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + if sim_ref: + nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={'synapse_model': ref_synapse_model_name}) + nest.Connect(mm_ref, post_neuron_ref) + nest.Connect(pre_neuron_ref, spikedet_pre_ref) + nest.Connect(post_neuron_ref, spikedet_post_ref) + + # get STDP synapse and weight before protocol + if sim_mdl: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + if sim_ref: + syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model=ref_synapse_model_name) + + n_steps = int(np.ceil(sim_time / resolution)) + 1 + t = 0. + t_hist = [] + if sim_mdl: + w_hist = [] + if sim_ref: + w_hist_ref = [] + while t <= sim_time: + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + if sim_ref: + w_hist_ref.append(nest.GetStatus(syn_ref)[0]['weight']) + if sim_mdl: + w_hist.append(nest.GetStatus(syn)[0]['w']) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=3) + ax1, ax2, ax3 = ax + + if sim_mdl: + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + print("Actual pre ref spike times: " + str(pre_ref_spike_times_)) + + if sim_mdl: + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4, label=_lbl) + + if sim_mdl: + post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"] + print("Actual post spike times: " + str(post_spike_times_)) + if sim_ref: + post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"] + print("Actual post ref spike times: " + str(post_ref_spike_times_)) + + if sim_ref: + n_spikes = len(pre_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], + linewidth=2, color="cyan", label=_lbl, alpha=.4) + ax1.set_ylabel("Pre spikes") + + if sim_mdl: + n_spikes = len(post_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax2.plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl) + if sim_ref: + n_spikes = len(post_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax2.plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl) + if sim_mdl: + ax2.plot(nest.GetStatus(mm, "events")[0]["times"], nest.GetStatus(mm, "events")[ + 0]["post_trace__for_stdp_nn_symm_nestml"], label="nestml post tr") + ax2.set_ylabel("Post spikes") + + if sim_mdl: + ax3.plot(t_hist, w_hist, marker="o", label="nestml") + if sim_ref: + ax3.plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref") + + ax3.set_xlabel("Time [ms]") + ax3.set_ylabel("w") + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_synapse_test" + fname_snip + ".png", dpi=300) + + # verify + MAX_ABS_ERROR = 1E-6 + assert np.all(np.abs(np.array(w_hist) - np.array(w_hist_ref)) < MAX_ABS_ERROR) diff --git a/tests/nest_tests/stdp_synapse_test.py b/tests/nest_tests/stdp_synapse_test.py new file mode 100644 index 000000000..d58b0fb17 --- /dev/null +++ b/tests/nest_tests/stdp_synapse_test.py @@ -0,0 +1,351 @@ +# -*- coding: utf-8 -*- +# +# stdp_synapse_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use("Agg") + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + +sim_mdl = True +sim_ref = True + + +class NestSTDPSynapseTest(unittest.TestCase): + + neuron_model_name = "iaf_psc_exp_nestml__with_stdp_nestml" + ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit" + + synapse_model_name = "stdp_nestml__with_iaf_psc_exp_nestml" + ref_synapse_model_name = "stdp_synapse" + + def setUp(self): + """Generate the model code""" + + jit_codegen_opts = {"neuron_synapse_pairs": [{"neuron": "iaf_psc_exp", + "synapse": "stdp", + "post_ports": ["post_spikes"]}]} + if not nest_version.startswith("v2"): + jit_codegen_opts["neuron_parent_class"] = "StructuralPlasticityNode" + jit_codegen_opts["neuron_parent_class_include"] = "structural_plasticity_node.h" + + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + files = [os.path.join("models", "neurons", "iaf_psc_exp.nestml"), + os.path.join("models", "synapses", "stdp_synapse.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + suffix="_nestml", + codegen_opts=jit_codegen_opts) + + if nest_version.startswith("v2"): + non_jit_codegen_opts = {"neuron_parent_class": "Archiving_Node", + "neuron_parent_class_include": "archiving_node.h"} + else: + non_jit_codegen_opts = {"neuron_parent_class": "ArchivingNode", + "neuron_parent_class_include": "archiving_node.h"} + + # generate the "non-jit" model, that relies on ArchivingNode + generate_nest_target(input_path=os.path.realpath(os.path.join(os.path.dirname(__file__), + os.path.join(os.pardir, os.pardir, "models", "neurons", "iaf_psc_exp.nestml"))), + target_path="/tmp/nestml-non-jit", + logging_level="INFO", + module_name="nestml_non_jit_module", + suffix="_nestml_non_jit", + codegen_opts=non_jit_codegen_opts) + + def test_nest_stdp_synapse(self): + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + + pre_spike_times = np.array([2., 4., 7., 8., 12., 13., 19., 23., 24., 28., 29., 30., 33., 34., + 35., 36., 38., 40., 42., 46., 51., 53., 54., 55., 56., 59., 63., 64., + 65., 66., 68., 72., 73., 76., 79., 80., 83., 84., 86., 87., 90., 95., + 99., 100., 103., 104., 105., 111., 112., 126., 131., 133., 134., 139., 147., 150., + 152., 155., 172., 175., 176., 181., 196., 197., 199., 202., 213., 215., 217., 265.]) + post_spike_times = np.array([4., 5., 6., 7., 10., 11., 12., 16., 17., 18., 19., 20., 22., 23., + 25., 27., 29., 30., 31., 32., 34., 36., 37., 38., 39., 42., 44., 46., + 48., 49., 50., 54., 56., 57., 59., 60., 61., 62., 67., 74., 76., 79., + 80., 81., 83., 88., 93., 94., 97., 99., 100., 105., 111., 113., 114., 115., + 116., 119., 123., 130., 132., 134., 135., 145., 152., 155., 158., 166., 172., 174., + 188., 194., 202., 245., 249., 289., 454.]) + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + ref_neuron_model_name=self.ref_neuron_model_name, + synapse_model_name=self.synapse_model_name, + ref_synapse_model_name=self.ref_synapse_model_name, + resolution=.5, # [ms] + delay=1.5, # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + ref_neuron_model_name, + synapse_model_name, + ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 5 * delay + + nest.set_verbosity("M_ALL") + nest.ResetKernel() + nest.Install("nestml_jit_module") + nest.Install("nestml_non_jit_module") + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + + # nest.set_verbosity("M_WARNING") + nest.set_verbosity("M_ERROR") + + post_weights = {"parrot": []} + + nest.ResetKernel() + nest.SetKernelStatus({"resolution": resolution}) + + wr = nest.Create("weight_recorder") + wr_ref = nest.Create("weight_recorder") + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0}) + nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec", + {"weight_recorder": wr_ref[0], "weight": 1., "delay": 1., "receptor_type": 0}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times, + "allow_offgrid_times": True}) + + # create parrot neurons and connect spike_generators + if sim_mdl: + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if sim_ref: + pre_neuron_ref = nest.Create("parrot_neuron") + post_neuron_ref = nest.Create(ref_neuron_model_name) + + if sim_mdl: + if nest_version.startswith("v2"): + spikedet_pre = nest.Create("spike_detector") + spikedet_post = nest.Create("spike_detector") + else: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": [ + "V_m", "post_trace_kernel__for_stdp_nestml__X__post_spikes__for_stdp_nestml"]}) + if sim_ref: + if nest_version.startswith("v2"): + spikedet_pre_ref = nest.Create("spike_detector") + spikedet_post_ref = nest.Create("spike_detector") + else: + spikedet_pre_ref = nest.Create("spike_recorder") + spikedet_post_ref = nest.Create("spike_recorder") + mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + if sim_mdl: + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + if nest_version.startswith("v2"): + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"model": "stdp_nestml_rec"}) + else: + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + if sim_ref: + nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + if nest_version.startswith("v2"): + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={"model": ref_synapse_model_name}) + else: + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={"synapse_model": ref_synapse_model_name}) + nest.Connect(mm_ref, post_neuron_ref) + nest.Connect(pre_neuron_ref, spikedet_pre_ref) + nest.Connect(post_neuron_ref, spikedet_post_ref) + + # get STDP synapse and weight before protocol + if sim_mdl: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + if sim_ref: + syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model=ref_synapse_model_name) + + n_steps = int(np.ceil(sim_time / resolution)) + 1 + t = 0. + t_hist = [] + if sim_mdl: + w_hist = [] + if sim_ref: + w_hist_ref = [] + while t <= sim_time: + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + if sim_ref: + w_hist_ref.append(nest.GetStatus(syn_ref)[0]["weight"]) + if sim_mdl: + w_hist.append(nest.GetStatus(syn)[0]["w"]) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=2) + ax1, ax2 = ax + + if sim_mdl: + timevec = nest.GetStatus(mm, "events")[0]["times"] + V_m = nest.GetStatus(mm, "events")[0]["V_m"] + ax2.plot(timevec, nest.GetStatus(mm, "events")[ + 0]["post_trace_kernel__for_stdp_nestml__X__post_spikes__for_stdp_nestml"], label="post_tr nestml") + ax1.plot(timevec, V_m, label="nestml", alpha=.7, linestyle=":") + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + timevec = nest.GetStatus(mm_ref, "events")[0]["times"] + V_m = nest.GetStatus(mm_ref, "events")[0]["V_m"] + ax1.plot(timevec, V_m, label="nest ref", alpha=.7) + ax1.set_ylabel("V_m") + + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.grid(which="minor", axis="x", linestyle=":", alpha=.4) + # _ax.minorticks_on() + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_synapse_test" + fname_snip + "_V_m.png", dpi=300) + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=3) + ax1, ax2, ax3 = ax + + if sim_mdl: + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + print("Actual pre ref spike times: " + str(pre_ref_spike_times_)) + + if sim_mdl: + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4, label=_lbl) + + if sim_mdl: + post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"] + print("Actual post spike times: " + str(post_spike_times_)) + if sim_ref: + post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"] + print("Actual post ref spike times: " + str(post_ref_spike_times_)) + + if sim_ref: + n_spikes = len(pre_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], + linewidth=2, color="cyan", label=_lbl, alpha=.4) + ax1.set_ylabel("Pre spikes") + + if sim_mdl: + n_spikes = len(post_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax2.plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl) + if sim_ref: + n_spikes = len(post_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax2.plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl) + ax2.plot(timevec, nest.GetStatus(mm, "events")[ + 0]["post_trace_kernel__for_stdp_nestml__X__post_spikes__for_stdp_nestml"], label="nestml post tr") + ax2.set_ylabel("Post spikes") + + if sim_mdl: + ax3.plot(t_hist, w_hist, marker="o", label="nestml") + if sim_ref: + ax3.plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref") + + ax3.set_xlabel("Time [ms]") + ax3.set_ylabel("w") + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_synapse_test" + fname_snip + ".png", dpi=300) + + # verify + MAX_ABS_ERROR = 1E-6 + assert np.any(np.abs(np.array(w_hist) - 1) > MAX_ABS_ERROR), "No change in the weight!" + assert np.all(np.abs(np.array(w_hist) - np.array(w_hist_ref)) < MAX_ABS_ERROR), \ + "Difference between NESTML model and reference model!" diff --git a/tests/nest_tests/stdp_triplet_synapse_test.py b/tests/nest_tests/stdp_triplet_synapse_test.py new file mode 100644 index 000000000..71861d4f5 --- /dev/null +++ b/tests/nest_tests/stdp_triplet_synapse_test.py @@ -0,0 +1,519 @@ +# -*- coding: utf-8 -*- +# +# stdp_triplet_synapse_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import numpy as np +import os +import pytest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use('Agg') + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + + +@pytest.fixture(autouse=True, + scope="module") +def nestml_generate_target(): + r"""Generate the neuron model code""" + + files = [os.path.join("models", "neurons", "iaf_psc_delta.nestml"), + os.path.join("models", "synapses", "stdp_triplet_naive.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-triplet-stdp", + logging_level="INFO", + module_name="nestml_triplet_pair_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_delta", + "synapse": "stdp_triplet", + "post_ports": ["post_spikes"]}]}) + + +def get_trace_at(t, t_spikes, tau, initial=0., increment=1., before_increment=False, extra_debug=False): + if extra_debug: + print("\t-- obtaining trace at t = " + str(t)) + if len(t_spikes) == 0: + return initial + tr = initial + t_sp_prev = 0. + for t_sp in t_spikes: + if t_sp > t: + break + if extra_debug: + _tr_prev = tr + tr *= np.exp(-(t_sp - t_sp_prev) / tau) + if t_sp == t: # exact floating point match! + if before_increment: + if extra_debug: + print("\t [%] exact (before_increment = T), prev trace = " + str(_tr_prev) + " at t = " + str(t_sp_prev) + + ", decayed by dt = " + str(t - t_sp_prev) + ", tau = " + str(tau) + " to t = " + str(t) + ": returning trace: " + str(tr)) + return tr + else: + if extra_debug: + print("\t [%] exact (before_increment = F), prev trace = " + str(_tr_prev) + " at t = " + str(t_sp_prev) + ", decayed by dt = " + str( + t - t_sp_prev) + ", tau = " + str(tau) + " to t = " + str(t) + ": returning trace: " + str(tr + increment)) + return tr + increment + tr += increment + t_sp_prev = t_sp + if extra_debug: + _tr_prev = tr + tr *= np.exp(-(t - t_sp_prev) / tau) + if extra_debug: + print("\t [&] prev trace = " + str(_tr_prev) + " at t = " + str(t_sp_prev) + ", decayed by dt = " + + str(t - t_sp_prev) + ", tau = " + str(tau) + " to t = " + str(t) + ": returning trace: " + str(tr)) + return tr + + +def run_reference_simulation(syn_opts, + sim_time=None, # if None, computed from pre and post spike times + times_spikes_pre=None, + times_spikes_syn_persp=None, + times_spikes_post_syn_persp=None, + fname_snip=""): + + log = {} + weight = syn_opts["w_init"] + + r1 = 0. + r2 = 0. + o1 = 0. + o2 = 0. + last_t_sp = 0. + log[0.] = {"weight": weight, + "r1": r1, + "r2": r2 + } + + for spk_time in np.unique(times_spikes_syn_persp): + import logging + logging.warning("XXX: TODO: before_increment values here are all wrong") + + if spk_time in times_spikes_post_syn_persp: + # print("Post spike --> facilitation") + print("\tgetting pre trace r1") + r1 = get_trace_at(spk_time, times_spikes_pre, + syn_opts["tau_plus"], before_increment=True, extra_debug=True) # F + print("\tgetting post trace o2") + o2 = get_trace_at(spk_time, times_spikes_post_syn_persp, + syn_opts["tau_y"], before_increment=True, extra_debug=True) # T + # print("\tr1 = " + str(r1)) + # print("\to2 = " + str(o2)) + # print("\told weight = " + str(weight)) + old_weight = weight + weight = np.clip(weight + r1 * (syn_opts["A2_plus"] + syn_opts["A3_plus"] + * o2), a_min=syn_opts["w_min"], a_max=syn_opts["w_max"]) + # print("\tnew weight = " + str(weight)) + print("[NESTML] stdp_connection: facilitating from " + str(old_weight) + " to " + + str(weight) + " with pre tr = " + str(r1) + ", post tr = " + str(o2)) + + if spk_time in times_spikes_pre: + # print("Pre spike --> depression") + print("\tgetting post trace o1") + o1 = get_trace_at(spk_time, times_spikes_post_syn_persp, + syn_opts["tau_minus"], before_increment=True, extra_debug=True) # F + print("\tgetting pre trace r2") + r2 = get_trace_at(spk_time, times_spikes_pre, + syn_opts["tau_x"], before_increment=True, extra_debug=True) # T + # print("\to1 = " + str(o1)) + # print("\tr2 = " + str(r2)) + # print("\told weight = " + str(weight)) + old_weight = weight + weight = np.clip(weight - o1 * (syn_opts["A2_minus"] + syn_opts["A3_minus"] + * r2), a_min=syn_opts["w_min"], a_max=syn_opts["w_max"]) + # print("\tnew weight = " + str(weight)) + print("[NESTML] stdp_connection: depressing from " + str(old_weight) + " to " + + str(weight) + " with pre tr = " + str(r2) + ", post tr = " + str(o1)) + + log[spk_time] = {"weight": weight} + + last_t_sp = spk_time + + timevec = np.sort(list(log.keys())) + weight_reference = np.array([log[k]["weight"] for k in timevec]) + + return timevec, weight_reference + + +def run_nest_simulation(neuron_model_name, + synapse_model_name, + neuron_opts, + syn_opts, + nest_modules_to_load=None, + resolution=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times_req=None, + post_spike_times_req=None, + J_ext=10000., + fname_snip=""): + + if pre_spike_times_req is None: + pre_spike_times_req = [] + + if post_spike_times_req is None: + post_spike_times_req = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times_req), np.amax(post_spike_times_req)) + 10. + 3 * syn_opts["delay"] + + nest.set_verbosity("M_ALL") + + # Set parameters of the NEST simulation kernel + nest.ResetKernel() + + try: + if nest_modules_to_load: + for s in nest_modules_to_load: + nest.Install(s) + except Exception: + pass # will fail when run in a loop ("module is already loaded") + + nest.SetKernelStatus({'print_time': False, 'local_num_threads': 1}) + nest.SetKernelStatus({'resolution': resolution}) + + nest.SetDefaults(neuron_model_name, neuron_opts) + + # Create nodes ------------------------------------------------- + + neurons = nest.Create(neuron_model_name, 2) + + print("Requested pre times: " + str(pre_spike_times_req)) + print("Requested post times: " + str(post_spike_times_req)) + + # one more pre spike to obtain updated values at end of simulation + pre_spike_times_req = np.hstack((pre_spike_times_req, [sim_time - syn_opts["delay"]])) + + external_input = nest.Create('spike_generator', params={'spike_times': pre_spike_times_req}) + external_input1 = nest.Create('spike_generator', params={'spike_times': post_spike_times_req}) + + if nest_version.startswith("v2"): + spikes = nest.Create('spike_detector') + else: + spikes = nest.Create('spike_recorder') + weight_recorder_E = nest.Create('weight_recorder') + + # Set models default ------------------------------------------- + + nest.CopyModel('static_synapse', + 'excitatory_noise', + {'weight': J_ext, + 'delay': syn_opts["delay"]}) + + _syn_opts = syn_opts.copy() + _syn_opts['Wmax'] = _syn_opts.pop('w_max') + _syn_opts['Wmin'] = _syn_opts.pop('w_min') + _syn_opts['w'] = _syn_opts.pop('w_init') + _syn_opts.pop('delay') + nest.CopyModel(synapse_model_name, + synapse_model_name + "_rec", + {'weight_recorder': weight_recorder_E[0]}) + nest.SetDefaults(synapse_model_name + "_rec", _syn_opts) + + # Connect nodes ------------------------------------------------ + + if nest_version.startswith("v2"): + nest.Connect([neurons[0]], [neurons[1]], syn_spec={'model': synapse_model_name + "_rec"}) + nest.Connect(external_input, [neurons[0]], syn_spec='excitatory_noise') + nest.Connect(external_input1, [neurons[1]], syn_spec='excitatory_noise') + else: + nest.Connect(neurons[0], neurons[1], syn_spec={'synapse_model': synapse_model_name + "_rec"}) + nest.Connect(external_input, neurons[0], syn_spec='excitatory_noise') + nest.Connect(external_input1, neurons[1], syn_spec='excitatory_noise') + # spike_recorder ignores connection delay; recorded times are times of spike creation rather than spike arrival + nest.Connect(neurons, spikes) + + # Simulate ----------------------------------------------------- + + nest.Simulate(sim_time) + + connections = nest.GetConnections(neurons, neurons) + gid_pre = nest.GetStatus(connections, 'source')[0] + gid_post = nest.GetStatus(connections, 'target')[0] + + events = nest.GetStatus(spikes, 'events')[0] + times_spikes = np.array(events['times']) + senders_spikes = events['senders'] + + events = nest.GetStatus(weight_recorder_E, 'events')[0] + times_weights = events['times'] + weight_simulation = events['weights'] + return times_weights, weight_simulation, gid_pre, gid_post, times_spikes, senders_spikes, sim_time + + +def compare_results(timevec, weight_reference, times_weights, weight_simulation): + """ + Compare (timevec, weight_reference) and (times_weights, weight_simulation), where the former may contain more entries than the latter. + """ + + idx = [np.where(np.abs(timevec - i) < 1E-9)[0][0] for i in times_weights] + timevec_pruned = timevec[idx] + weight_reference_pruned = weight_reference[idx] + + np.testing.assert_allclose(timevec_pruned, times_weights) + + w_ref_vec = [] + for idx_w_sim, t_sim in enumerate(times_weights): + w_sim = weight_simulation[idx_w_sim] + idx_w_ref = np.where(timevec == t_sim)[0][0] + w_ref = weight_reference[idx_w_ref] + w_ref_vec.append(w_ref) + + np.testing.assert_allclose(weight_simulation, w_ref_vec, atol=1E-6, rtol=1E-6) + print("Test passed!") + + +def plot_comparison(syn_opts, times_spikes_pre, times_spikes_post, times_spikes_post_syn_persp, timevec, weight_reference, times_weights, weight_simulation, sim_time): + fig, ax = plt.subplots(nrows=4) + fig.suptitle("Triplet STDP") + + _r1 = [get_trace_at(t, times_spikes_pre, syn_opts["tau_plus"]) for t in timevec] + _r2 = [get_trace_at(t, times_spikes_pre, syn_opts["tau_x"]) for t in timevec] + ax[0].plot(timevec, _r1, label="r1") + ax[0].scatter(timevec, _r1, s=40, marker="o") + ax[0].plot(timevec, _r2, label="r2") + ax[0].scatter(timevec, _r2, s=40, marker="o") + ax[0].set_ylabel("Soma & syn\ntrace (PRE)") + _ylim = ax[0].get_ylim() + for t_sp in times_spikes_pre: + ax[0].plot([t_sp, t_sp], _ylim, linewidth=2, color=(.25, .5, 1.)) + ax[0].legend() + + _o1 = [get_trace_at(t, times_spikes_post, syn_opts["tau_minus"]) for t in timevec] + _o2 = [get_trace_at(t, times_spikes_post, syn_opts["tau_y"]) for t in timevec] + ax[1].plot(timevec, _o1, label="o1") + ax[1].scatter(timevec, _o1, s=40, marker="o") + ax[1].plot(timevec, _o2, label="o2") + ax[1].scatter(timevec, _o2, s=40, marker="o") + _ylim = ax[1].get_ylim() + for t_sp in times_spikes_post: + ax[1].plot([t_sp, t_sp], _ylim, linewidth=2, color=(.25, .5, 1.)) + ax[1].set_ylabel("Soma trace\n(POST)") + ax[1].legend() + + _high_resolution_timevec = np.linspace(0, sim_time, 1000) + _o1 = [get_trace_at(t, times_spikes_post_syn_persp, syn_opts["tau_minus"]) for t in _high_resolution_timevec] + ax[2].plot(_high_resolution_timevec, _o1, label="o1", alpha=.333, color="blue") + _o2 = [get_trace_at(t, times_spikes_post_syn_persp, syn_opts["tau_y"]) for t in _high_resolution_timevec] + ax[2].plot(_high_resolution_timevec, _o2, label="o2", alpha=.333, color="orange") + + _o1 = [get_trace_at(t, times_spikes_post_syn_persp, syn_opts["tau_minus"]) for t in timevec] + _o2 = [get_trace_at(t, times_spikes_post_syn_persp, syn_opts["tau_y"]) for t in timevec] + ax[2].plot(timevec, _o1, label="o1", color="blue") + ax[2].scatter(timevec, _o1, s=40, marker="o") + ax[2].plot(timevec, _o2, label="o2", color="orange") + ax[2].scatter(timevec, _o2, s=40, marker="o") + _ylim = ax[2].get_ylim() + for t_sp in times_spikes_post_syn_persp: + ax[2].plot([t_sp, t_sp], _ylim, linewidth=2, color=(.25, .5, 1.)) + ax[2].set_ylabel("Syn trace\n(POST)") + ax[2].legend() + + ax[-1].plot(timevec, weight_reference, label="Py ref") + ax[-1].set_ylabel("Weight") + + ax[-1].scatter(times_weights, weight_simulation, s=40, marker="o", + label="NEST", facecolor="none", edgecolor="black") + ax[-1].legend() + + for _ax in ax: + _ax.grid(True) + _ax.set_xlim(0., sim_time) + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + if not _ax == ax[-1]: + _ax.set_xticklabels([]) + + ax[-1].set_xlabel("Time [ms]") + + plt.savefig("/tmp/stdp_triplets_[delay=" + "%.3f" % syn_opts["delay"] + "].png", dpi=150.) + +# @pytest.mark.parametrize('delay', [1., 5., 14.3]) +# @pytest.mark.parametrize('spike_times_len', [1, 10, 100]) +# @pytest.mark.parametrize('spike_times_len', [10]) + + +def _test_stdp_triplet_synapse(delay, spike_times_len): + print("Running test for delay = " + str(delay) + ", spike_times_len = " + str(spike_times_len)) + + experiment = "test_nestml_pair_synapse" + syn_opts = { + 'delay': delay, + 'tau_minus': 33.7, + 'tau_plus': 16.8, + 'tau_x': 101., + 'tau_y': 125., + 'A2_plus': 7.5e-10, + 'A3_plus': 9.3e-3, + 'A2_minus': 7e-3, + 'A3_minus': 2.3e-4, + 'w_max': 50., + 'w_min': 0., + 'w_init': 1. + } + + if experiment == "test_nestml_pair_synapse": + nest_modules_to_load = ["nestml_triplet_pair_module"] + + neuron_model_name = "iaf_psc_delta_nestml__with_stdp_triplet_nestml" + neuron_opts = {'tau_minus__for_stdp_triplet_nestml': syn_opts['tau_minus'], + 'tau_y__for_stdp_triplet_nestml': syn_opts['tau_y']} + + synapse_model_name = "stdp_triplet_nestml__with_iaf_psc_delta_nestml" + nest_syn_opts = {'the_delay': delay} + nest_syn_opts.update(syn_opts) + nest_syn_opts.pop('tau_minus') # these have been moved to the neuron + nest_syn_opts.pop('tau_y') + elif experiment == "test_nest_triplet_synapse": + nest_modules_to_load = None + + tau_m = 40.0 # Membrane time constant (mV) + V_th = 20.0 # Spike threshold (mV) + C_m = 250.0 # Membrane capacitance (pF) + t_ref = 2.0 # Refractory period (ms) + E_L = 0.0 # Resting membrane potential (mV) + V_reset = 10.0 # Reset potential after spike (mV) + + neuron_model_name = 'iaf_psc_delta' + neuron_opts = {"tau_m": tau_m, + "t_ref": t_ref, + "C_m": C_m, + "V_reset": V_reset, + "E_L": E_L, + "V_m": E_L, + "V_th": V_th, + "tau_minus": syn_opts['tau_minus'], + "tau_minus_triplet": syn_opts['tau_y']} + + synapse_model_name = "stdp_triplet" + nest_syn_opts = {'delay': delay, + 'tau_plus': syn_opts['tau_plus'], + 'tau_plus_triplet': syn_opts['tau_x'], + 'Aplus': syn_opts['A2_plus'], + 'Aplus_triplet': syn_opts['A3_plus'], + 'Aminus': syn_opts['A2_minus'], + 'Aminus_triplet': syn_opts['A3_minus'], + 'Wmax': syn_opts["w_max"], + 'weight': syn_opts["w_init"]} + + fname_snip = "_experiment=[" + experiment + "]" + + pre_spike_times = np.array([2., 3., 7., 8., 9., 10., 12., 17., 19., 21., 22., 24., 25., 26., + 28., 30., 36., 37., 38., 40., 43., 46., 47., 48., 49., 50., 51., 52., + 53., 55., 58., 59., 60., 62., 64., 65., 66., 67., 68., 69., 71., 72., + 76., 77., 78., 82., 83., 84., 85., 86., 87., 88., 92., 96., 99., 105., + 113., 114., 121., 122., 124., 129., 135., 140., 152., 161., 167., 170., 183., 186., + 192., 202., 218., 224., 303., 311.]) + post_spike_times = np.array([2., 4., 5., 8., 9., 12., 13., 14., 17., 18., 19., 21., 24., 25., + 26., 28., 30., 32., 34., 37., 38., 40., 42., 44., 45., 46., 49., 50., + 51., 53., 55., 56., 60., 61., 67., 68., 72., 73., 74., 76., 77., 78., + 79., 81., 82., 84., 87., 88., 93., 95., 96., 98., 99., 100., 109., 110., + 111., 115., 116., 118., 120., 121., 124., 125., 127., 128., 140., 144., 149., 150., + 152., 155., 156., 157., 163., 164., 168., 172., 204., 206., 216., 239., 243.]) + + # pre_spike_times = 1 + 5 * np.arange(spike_times_len).astype(float) + # post_spike_times = 1 + 5 * np.arange(spike_times_len).astype(float) + + nestml_timevec, nestml_w, gid_pre, gid_post, times_spikes, senders_spikes, sim_time = \ + run_nest_simulation(neuron_model_name=neuron_model_name, + synapse_model_name=synapse_model_name, + neuron_opts=neuron_opts, + syn_opts=nest_syn_opts, + nest_modules_to_load=nest_modules_to_load, + resolution=.1, # [ms] + sim_time=None, # 20., + pre_spike_times_req=pre_spike_times, + post_spike_times_req=post_spike_times, + fname_snip=fname_snip) + + # n.b. spike times here refer to the **somatic** spike time + + idx = np.argsort(times_spikes) + senders_spikes = senders_spikes[idx] + times_spikes = times_spikes[idx] + + times_spikes_pre = times_spikes[senders_spikes == gid_pre] + times_spikes_post = times_spikes[senders_spikes == gid_post] + + print("Actual pre spike times: " + str(times_spikes_pre)) + print("Actual post spike times: " + str(times_spikes_post)) + + # convert somatic spike times to synaptic perspective: add post dendritic delay + + times_spikes_syn_persp = np.copy(times_spikes) + times_spikes_syn_persp[senders_spikes == gid_post] += syn_opts["delay"] + + times_spikes_post_syn_persp = times_spikes_syn_persp[senders_spikes == gid_post] + times_spikes_syn_persp = np.sort(times_spikes_syn_persp) + + print("Actual post spike times (syn. pers.): " + str(times_spikes_post_syn_persp)) + + ref_timevec, ref_w = \ + run_reference_simulation(syn_opts=syn_opts, + sim_time=sim_time, + times_spikes_pre=times_spikes_pre, + times_spikes_syn_persp=times_spikes_syn_persp, + times_spikes_post_syn_persp=times_spikes_post_syn_persp, + fname_snip=fname_snip) + + if TEST_PLOTS: + plot_comparison(syn_opts, times_spikes_pre, times_spikes_post, times_spikes_post_syn_persp, + ref_timevec, ref_w, nestml_timevec, nestml_w, sim_time) + + compare_results(ref_timevec, ref_w, nestml_timevec, nestml_w) + + +# @pytest.mark.parametrize('spike_times_len', [1, 10, 100]) +@pytest.mark.parametrize('spike_times_len', [10]) +def test_stdp_triplet_synapse_delay_1(spike_times_len): + delay = 1. + _test_stdp_triplet_synapse(delay, spike_times_len) + +# import logging;logging.warning("XXX: TODO: xfail test due to https://github.com/nest/nestml/issues/661") +# @pytest.mark.xfail(strict=True, raises=Exception) +# @pytest.mark.parametrize('spike_times_len', [1, 10, 100]) + + +@pytest.mark.parametrize('spike_times_len', [10]) +def test_stdp_triplet_synapse_delay_5(spike_times_len): + delay = 5. + _test_stdp_triplet_synapse(delay, spike_times_len) + +# import logging;logging.warning("XXX: TODO: xfail test due to https://github.com/nest/nestml/issues/661") +# @pytest.mark.xfail(strict=True, raises=Exception) +# @pytest.mark.parametrize('spike_times_len', [1, 10, 100]) + + +nest_version = NESTTools.detect_nest_version() + + +@pytest.mark.parametrize('spike_times_len', [10]) +def test_stdp_triplet_synapse_delay_10(spike_times_len): + delay = 10. + _test_stdp_triplet_synapse(delay, spike_times_len) diff --git a/tests/nest_tests/stdp_window_test.py b/tests/nest_tests/stdp_window_test.py new file mode 100644 index 000000000..064ee53ee --- /dev/null +++ b/tests/nest_tests/stdp_window_test.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +# +# stdp_window_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use("Agg") + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + + +@pytest.fixture(autouse=True, + scope="module") +def nestml_generate_target(): + r"""Generate the neuron model code""" + + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + files = [os.path.join("models", "neurons", "iaf_psc_delta.nestml"), + os.path.join("models", "synapses", "stdp_synapse.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_delta", + "synapse": "stdp", + "post_ports": ["post_spikes"]}]}) + nest.Install("nestml_jit_module") + + +def run_stdp_network(pre_spike_time, post_spike_time, + neuron_model_name, + synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + fname_snip="", + custom_synapse_properties=None): + + print("Pre spike time: " + str(pre_spike_time)) + print("Post spike time: " + str(post_spike_time)) + + nest.set_verbosity("M_ALL") + + nest.ResetKernel() + nest.SetKernelStatus({"resolution": resolution}) + + wr = nest.Create("weight_recorder") + if "__with" in synapse_model_name: + weight_variable_name = "w" + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], weight_variable_name: 1., "delay": delay, "the_delay": delay, "receptor_type": 0, "mu_minus": 0., "mu_plus": 0.}) + else: + weight_variable_name = "weight" + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], weight_variable_name: 1., "delay": delay, "receptor_type": 0, "mu_minus": 0., "mu_plus": 0.}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": [pre_spike_time, sim_time - 10.]}) + post_sg = nest.Create("spike_generator", + params={"spike_times": [post_spike_time], + "allow_offgrid_times": True}) + + # create parrot neurons and connect spike_generators + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if nest_version.startswith("v2"): + spikedet_pre = nest.Create("spike_detector") + spikedet_post = nest.Create("spike_detector") + else: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + if nest_version.startswith("v2"): + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"model": "stdp_nestml_rec"}) + else: + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"}) + + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + + # get STDP synapse and weight before protocol + if custom_synapse_properties: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + nest.SetStatus(syn, custom_synapse_properties) + + initial_weight = nest.GetStatus(syn)[0][weight_variable_name] + np.testing.assert_allclose(initial_weight, 1) + nest.Simulate(sim_time) + updated_weight = nest.GetStatus(syn)[0][weight_variable_name] + + actual_t_pre_sp = nest.GetStatus(spikedet_pre)[0]["events"]["times"][0] + actual_t_post_sp = nest.GetStatus(spikedet_post)[0]["events"]["times"][0] + + dt = actual_t_post_sp - actual_t_pre_sp + dw = updated_weight - initial_weight + print("Returning " + str((dt, dw))) + + return dt, dw + + +@pytest.mark.parametrize("neuron_model_name", ["iaf_psc_delta_nestml__with_stdp_nestml"]) +@pytest.mark.parametrize("synapse_model_name", ["stdp_nestml__with_iaf_psc_delta_nestml"]) +def test_nest_stdp_synapse(neuron_model_name: str, synapse_model_name: str, fname_snip: str = ""): + fname = "stdp_window_test" + if len(fname_snip) > 0: + fname += "_" + fname_snip + + sim_time = 1000. # [ms] + pre_spike_time = 100. # sim_time / 2 # [ms] + delay = 10. # [ms] + + # plot + if TEST_PLOTS: + fig, ax = plt.subplots() + + dt_vec = [] + dw_vec = [] + for post_spike_time in np.arange(25, 175).astype(float) - delay: + dt, dw = run_stdp_network(pre_spike_time, post_spike_time, + neuron_model_name, + synapse_model_name, + resolution=1., # [ms] + delay=delay, # [ms] + sim_time=sim_time, # if None, computed from pre and post spike times + fname_snip=fname_snip, + custom_synapse_properties={"lambda": 1E-6, "alpha": 1.}) + + dt_vec.append(dt) + dw_vec.append(dw) + + # plot + if TEST_PLOTS: + ax.scatter(dt_vec, dw_vec) + ax.set_xlabel(r"t_post - t_pre") + ax.set_ylabel(r"$\Delta w$") + + for _ax in [ax]: + _ax.grid(which="major", axis="both") + _ax.grid(which="minor", axis="x", linestyle=":", alpha=.4) + + fig.savefig("/tmp/stdp_synapse_test" + fname_snip + "_window.png", dpi=300) diff --git a/tests/nest_tests/synapse_priority_test.py b/tests/nest_tests/synapse_priority_test.py new file mode 100644 index 000000000..c8465be30 --- /dev/null +++ b/tests/nest_tests/synapse_priority_test.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# +# synapse_priority_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import numpy as np +import os +import pytest +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use('Agg') + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + + +class NestSynapsePriorityTest(unittest.TestCase): + + def setUp(self): + r"""Generate the model code""" + files = [os.path.join("models", "neurons", "iaf_psc_delta.nestml"), + os.path.join("tests", "resources", "synapse_event_priority_test.nestml"), + os.path.join("tests", "resources", "synapse_event_inv_priority_test.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-synapse-event-priority-test", + logging_level="INFO", + module_name="nestml_module", + suffix="_nestml", + codegen_opts={"neuron_parent_class": "StructuralPlasticityNode", + "neuron_parent_class_include": "structural_plasticity_node.h", + "neuron_synapse_pairs": [{"neuron": "iaf_psc_delta", + "synapse": "synapse_event_priority_test", + "post_ports": ["post_spikes"]}, + {"neuron": "iaf_psc_delta", + "synapse": "synapse_event_inv_priority_test", + "post_ports": ["post_spikes"]}]}) + + @pytest.mark.skipif(nest_version.startswith("v2"), + reason="This test does not support NEST 2") + def test_synapse_event_priority(self): + + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(100 * np.sort(np.abs(np.random.randn(100)))))) # [ms] + + # one additional pre spike to ensure processing of post spikes in the intermediate interval + pre_spike_times = np.array([3., 50.]) + post_spike_times = np.array([2.]) + + self.run_synapse_test( + resolution=.5, # [ms] + delay=1., # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + def run_nest_simulation(self, neuron_model_name, + synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 5 * delay + + nest.set_verbosity("M_ALL") + # nest.set_verbosity("M_WARNING") + nest.ResetKernel() + try: + nest.Install("nestml_module") + except Exception: + pass + nest.SetKernelStatus({'resolution': resolution}) + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + + # wr = nest.Create('weight_recorder') + nest.CopyModel(synapse_model_name, "syn_nestml", + {"d": delay}) + # {"weight_recorder": wr[0], "d": delay}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times}) + + # create parrot neurons and connect spike_generators + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + # mm = nest.Create("multimeter", params={"record_from" : ["V_m", "post_trace_kernel__for_stdp_nestml__X__post_spikes__for_stdp_nestml"]}) + + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={'synapse_model': 'syn_nestml'}) + # nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + + # get STDP synapse + syn = nest.GetConnections(source=pre_neuron, synapse_model="syn_nestml") + + nest.Simulate(sim_time) + + return syn.get("tr") + + def run_synapse_test(self, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + neuron_model_name = "iaf_psc_delta_nestml__with_synapse_event_priority_test_nestml" + synapse_model_name = "synapse_event_priority_test_nestml__with_iaf_psc_delta_nestml" + tr = self.run_nest_simulation(neuron_model_name=neuron_model_name, + synapse_model_name=synapse_model_name, + resolution=resolution, + delay=delay, + sim_time=sim_time, + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + neuron_model_name = "iaf_psc_delta_nestml__with_synapse_event_inv_priority_test_nestml" + synapse_model_name = "synapse_event_inv_priority_test_nestml__with_iaf_psc_delta_nestml" + tr_inv = self.run_nest_simulation(neuron_model_name=neuron_model_name, + synapse_model_name=synapse_model_name, + resolution=resolution, + delay=delay, + sim_time=sim_time, + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + fname_snip=fname_snip) + + np.testing.assert_allclose(tr, 7.28318) + np.testing.assert_allclose(tr_inv, 5.14159) diff --git a/tests/nest_tests/terub_stn_test.py b/tests/nest_tests/terub_stn_test.py index c60cf08dc..9ac6431e7 100644 --- a/tests/nest_tests/terub_stn_test.py +++ b/tests/nest_tests/terub_stn_test.py @@ -20,10 +20,13 @@ # along with NEST. If not, see . import os -import nest import unittest import numpy as np -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target try: import matplotlib @@ -32,6 +35,8 @@ except ImportError: TEST_PLOTS = False +nest_version = NESTTools.detect_nest_version() + class NestSTNExpTest(unittest.TestCase): @@ -41,19 +46,16 @@ def test_terub_stn(self): os.makedirs("target") input_path = os.path.join(os.path.realpath(os.path.join( - os.path.dirname(__file__), "../../models", "terub_stn.nestml"))) + os.path.dirname(__file__), os.pardir, os.pardir, "models", "neurons", "terub_stn.nestml"))) target_path = "target" - module_name = 'terub_stn_module' - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - suffix = '_nestml' - - to_nest(input_path=input_path, - target_path=target_path, - logging_level="INFO", - suffix=suffix, - module_name=module_name) + module_name = "terub_stn_module" + suffix = "_nestml" - install_nest(target_path, nest_path) + generate_nest_target(input_path, + target_path=target_path, + logging_level="INFO", + suffix=suffix, + module_name=module_name) nest.Install(module_name) model = "terub_stn_nestml" @@ -65,12 +67,14 @@ def test_terub_stn(self): neuron = nest.Create(model) parameters = nest.GetDefaults(model) - - neuron.set({'I_e': 10.0}) + nest.SetStatus(neuron, {"I_e": 10.0}) multimeter = nest.Create("multimeter") - multimeter.set({"record_from": ["V_m"], - "interval": dt}) - spike_recorder = nest.Create("spike_recorder") + nest.SetStatus(multimeter, {"record_from": ["V_m"], + "interval": dt}) + if nest_version.startswith("v2"): + spike_recorder = nest.Create("spike_detector") + else: + spike_recorder = nest.Create("spike_recorder") nest.Connect(multimeter, neuron) nest.Connect(neuron, spike_recorder) nest.Simulate(t_simulation) @@ -78,8 +82,8 @@ def test_terub_stn(self): dmm = nest.GetStatus(multimeter)[0] Voltages = dmm["events"]["V_m"] tv = dmm["events"]["times"] - dSD = nest.GetStatus(spike_recorder, keys='events')[0] - spikes = dSD['senders'] + dSD = nest.GetStatus(spike_recorder, keys="events")[0] + spikes = dSD["senders"] ts = dSD["times"] firing_rate = len(spikes) / t_simulation * 1000 @@ -93,7 +97,7 @@ def test_terub_stn(self): fig, ax = plt.subplots(2, figsize=(8, 4), sharex=True) ax[0].plot(tv, Voltages, lw=2, color="k") - ax[1].plot(ts, spikes, 'ko') + ax[1].plot(ts, spikes, "ko") ax[1].set_xlabel("Time [ms]") ax[1].set_xlim(0, t_simulation) ax[1].set_ylabel("Spikes") @@ -103,8 +107,7 @@ def test_terub_stn(self): for i in ts: ax[0].axvline(x=i, lw=1., ls="--", color="gray") - plt.savefig("resources/terub_stn.png") - # plt.show() + plt.savefig("terub_stn.png") if __name__ == "__main__": diff --git a/tests/nest_tests/third_factor_stdp_synapse_test.py b/tests/nest_tests/third_factor_stdp_synapse_test.py new file mode 100644 index 000000000..c1d594e01 --- /dev/null +++ b/tests/nest_tests/third_factor_stdp_synapse_test.py @@ -0,0 +1,329 @@ +# -*- coding: utf-8 -*- +# +# third_factor_stdp_synapse_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import numpy as np +import os +import unittest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +try: + import matplotlib + matplotlib.use("Agg") + import matplotlib.ticker + import matplotlib.pyplot as plt + TEST_PLOTS = True +except Exception: + TEST_PLOTS = False + +nest_version = NESTTools.detect_nest_version() + + +sim_mdl = True +sim_ref = False + + +class NestThirdFactorSTDPSynapseTest(unittest.TestCase): + + neuron_model_name = "iaf_psc_exp_dend__with_third_factor_stdp" + ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit" + + synapse_model_name = "third_factor_stdp__with_iaf_psc_exp_dend" + ref_synapse_model_name = "third_factor_stdp_synapse" + + post_trace_var = "I_dend" + + def setUp(self): + r"""Generate the neuron model code""" + + codegen_opts = {"neuron_synapse_pairs": [{"neuron": "iaf_psc_exp_dend", + "synapse": "third_factor_stdp", + "post_ports": ["post_spikes", + ["I_post_dend", "I_dend"]]}]} + + if not nest_version.startswith("v2"): + codegen_opts["neuron_parent_class"] = "StructuralPlasticityNode" + codegen_opts["neuron_parent_class_include"] = "structural_plasticity_node.h" + + # generate the "jit" model (co-generated neuron and synapse), that does not rely on ArchivingNode + files = [os.path.join("models", "neurons", "iaf_psc_exp_dend.nestml"), + os.path.join("models", "synapses", "third_factor_stdp_synapse.nestml")] + input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, os.pardir, s))) for s in files] + generate_nest_target(input_path=input_path, + target_path="/tmp/nestml-jit", + logging_level="INFO", + module_name="nestml_jit_module", + codegen_opts=codegen_opts) + + def test_nest_stdp_synapse(self): + + fname_snip = "" + + pre_spike_times = [1., 11., 21.] # [ms] + post_spike_times = [6., 16., 26.] # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(10 * np.sort(np.abs(np.random.randn(10)))))) # [ms] + + post_spike_times = np.sort(np.unique(1 + np.round(500 * np.sort(np.abs(np.random.randn(500)))))) # [ms] + pre_spike_times = np.sort(np.unique(1 + np.round(500 * np.sort(np.abs(np.random.randn(500)))))) # [ms] + + self.run_synapse_test(neuron_model_name=self.neuron_model_name, + ref_neuron_model_name=self.ref_neuron_model_name, + synapse_model_name=self.synapse_model_name, + ref_synapse_model_name=self.ref_synapse_model_name, + resolution=.5, # [ms] + delay=1.5, # [ms] + pre_spike_times=pre_spike_times, + post_spike_times=post_spike_times, + sim_time=400., + fname_snip=fname_snip) + + def run_synapse_test(self, neuron_model_name, + ref_neuron_model_name, + synapse_model_name, + ref_synapse_model_name, + resolution=1., # [ms] + delay=1., # [ms] + sim_time=None, # if None, computed from pre and post spike times + pre_spike_times=None, + post_spike_times=None, + fname_snip=""): + + if pre_spike_times is None: + pre_spike_times = [] + + if post_spike_times is None: + post_spike_times = [] + + if sim_time is None: + sim_time = max(np.amax(pre_spike_times), np.amax(post_spike_times)) + 5 * delay + + nest.set_verbosity("M_ALL") + nest.ResetKernel() + nest.Install("nestml_jit_module") + + print("Pre spike times: " + str(pre_spike_times)) + print("Post spike times: " + str(post_spike_times)) + + nest.set_verbosity("M_WARNING") + + nest.ResetKernel() + nest.SetKernelStatus({"resolution": resolution}) + + wr = nest.Create("weight_recorder") + wr_ref = nest.Create("weight_recorder") + nest.CopyModel(synapse_model_name, "stdp_nestml_rec", + {"weight_recorder": wr[0], "w": 1., "the_delay": 1., "receptor_type": 0, "lambda": .001}) + if sim_ref: + nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec", + {"weight_recorder": wr_ref[0], "weight": 1., "delay": 1., "receptor_type": 0, "lambda": .001}) + + # create spike_generators with these times + pre_sg = nest.Create("spike_generator", + params={"spike_times": pre_spike_times}) + post_sg = nest.Create("spike_generator", + params={"spike_times": post_spike_times, + "allow_offgrid_times": True}) + + # create parrot neurons and connect spike_generators + if sim_mdl: + pre_neuron = nest.Create("parrot_neuron") + post_neuron = nest.Create(neuron_model_name) + + if sim_ref: + pre_neuron_ref = nest.Create("parrot_neuron") + post_neuron_ref = nest.Create(ref_neuron_model_name) + + if sim_mdl: + if nest_version.startswith("v2"): + spikedet_pre = nest.Create("spike_detector") + spikedet_post = nest.Create("spike_detector") + else: + spikedet_pre = nest.Create("spike_recorder") + spikedet_post = nest.Create("spike_recorder") + mm = nest.Create("multimeter", params={"record_from": ["V_m", self.post_trace_var]}) + if sim_ref: + if nest_version.startswith("v2"): + spikedet_pre_ref = nest.Create("spike_detector") + spikedet_post_ref = nest.Create("spike_detector") + else: + spikedet_pre_ref = nest.Create("spike_recorder") + spikedet_post_ref = nest.Create("spike_recorder") + mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]}) + + if sim_mdl: + nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + if nest_version.startswith("v2"): + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"model": "stdp_nestml_rec"}) + else: + nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"}) + nest.Connect(mm, post_neuron) + nest.Connect(pre_neuron, spikedet_pre) + nest.Connect(post_neuron, spikedet_post) + if sim_ref: + nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.}) + nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.}) + if nest_version.startswith("v2"): + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={"model": ref_synapse_model_name}) + else: + nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all", + syn_spec={"synapse_model": ref_synapse_model_name}) + nest.Connect(mm_ref, post_neuron_ref) + nest.Connect(pre_neuron_ref, spikedet_pre_ref) + nest.Connect(post_neuron_ref, spikedet_post_ref) + + # get STDP synapse and weight before protocol + if sim_mdl: + syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec") + if sim_ref: + syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model=ref_synapse_model_name) + + t = 0. + t_hist = [] + if sim_mdl: + w_hist = [] + if sim_ref: + w_hist_ref = [] + state = 0 + while t <= sim_time: + if t > sim_time / 6. and state == 0: + nest.SetStatus(post_neuron, {"I_dend": 1.}) + state = 1 + if t > 2 * sim_time / 6 and state == 1: + nest.SetStatus(post_neuron, {"I_dend": 1.}) + if t > 2 * sim_time / 3. and state == 1: + state = 2 + nest.Simulate(resolution) + t += resolution + t_hist.append(t) + if sim_ref: + w_hist_ref.append(nest.GetStatus(syn_ref)[0]["weight"]) + if sim_mdl: + w_hist.append(nest.GetStatus(syn)[0]["w"]) + + third_factor_trace = nest.GetStatus(mm, "events")[0][self.post_trace_var] + timevec = nest.GetStatus(mm, "events")[0]["times"] + + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=2) + ax1, ax2 = ax + + if sim_mdl: + V_m = nest.GetStatus(mm, "events")[0]["V_m"] + ax2.plot(timevec, third_factor_trace, label="I_dend_post") + ax1.plot(timevec, V_m, alpha=.7, linestyle=":") + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + timevec_ = nest.GetStatus(mm_ref, "events")[0]["times"] + V_m_ = nest.GetStatus(mm_ref, "events")[0]["V_m"] + ax1.plot(timevec_, V_m_, label="nest ref", alpha=.7) + ax1.set_ylabel("V_m") + + for _ax in ax: + _ax.grid(which="major", axis="both") + _ax.grid(which="minor", axis="x", linestyle=":", alpha=.4) + # _ax.minorticks_on() + _ax.set_xlim(0., sim_time) + _ax.legend() + fig.savefig("/tmp/stdp_triplet_synapse_test" + fname_snip + "_V_m.png", dpi=300) + + if TEST_PLOTS: + fig, ax = plt.subplots(nrows=5) + ax1, ax2, ax3, ax4, ax5 = ax + + if sim_mdl: + pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"] + print("Actual pre spike times: " + str(pre_spike_times_)) + if sim_ref: + pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"] + print("Actual pre ref spike times: " + str(pre_ref_spike_times_)) + + if sim_mdl: + n_spikes = len(pre_spike_times_) + for i in range(n_spikes): + ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4) + + if sim_mdl: + post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"] + print("Actual post spike times: " + str(post_spike_times_)) + if sim_ref: + post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"] + print("Actual post ref spike times: " + str(post_ref_spike_times_)) + + if sim_ref: + n_spikes = len(pre_ref_spike_times_) + for i in range(n_spikes): + ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], linewidth=2, color="cyan", alpha=.4) + ax1.set_ylabel("Pre spikes") + + if sim_mdl: + n_spikes = len(post_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nestml" + else: + _lbl = None + ax[-4].plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl) + if sim_ref: + n_spikes = len(post_ref_spike_times_) + for i in range(n_spikes): + if i == 0: + _lbl = "nest ref" + else: + _lbl = None + ax[-4].plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl) + ax[-4].set_ylabel("Post spikes") + + ax[-3].plot(timevec, third_factor_trace) + ax[-3].set_ylabel("3rd factor") + + ax[-2].plot(t_hist[:-1], np.diff(w_hist), marker="o", label=u"Δw") + ax[-2].set_ylabel(u"Δw") + + ax[-1].plot(t_hist, w_hist, marker="o") + if sim_ref: + ax[-1].plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref") + ax[-1].set_ylabel("w") + + ax[-1].set_xlabel("Time [ms]") + for _ax in ax: + if not _ax == ax[-1]: + _ax.set_xticklabels([]) + _ax.grid(which="major", axis="both") + _ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time)))) + _ax.set_xlim(0., sim_time) + fig.savefig("/tmp/stdp_third_factor_synapse_test" + fname_snip + ".png", dpi=300) + + # verify + MAX_ABS_ERROR = 1E-6 + idx = np.where(np.abs(third_factor_trace) < 1E-3)[0] # find where third_factor_place is (almost) zero + times_dw_should_be_zero = timevec[idx] + for time_dw_should_be_zero in times_dw_should_be_zero: + _idx = np.argmin((time_dw_should_be_zero - np.array(t_hist))**2) + assert np.abs(np.diff(w_hist)[_idx]) < MAX_ABS_ERROR + + assert np.any(np.abs(np.array(w_hist) - 1) > MAX_ABS_ERROR), "No change in the weight!" diff --git a/tests/nest_tests/traub_cond_multisyn_test.py b/tests/nest_tests/traub_cond_multisyn_test.py index da5dcd266..367dedbff 100644 --- a/tests/nest_tests/traub_cond_multisyn_test.py +++ b/tests/nest_tests/traub_cond_multisyn_test.py @@ -19,11 +19,9 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import numpy as np import os -import nest import unittest -import numpy as np -from pynestml.frontend.pynestml_frontend import to_nest, install_nest try: import matplotlib @@ -32,6 +30,13 @@ except BaseException: TEST_PLOTS = False +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +nest_version = NESTTools.detect_nest_version() + class NestWBCondExpTest(unittest.TestCase): @@ -41,19 +46,16 @@ def test_traub_cond_multisyn(self): os.makedirs("target") input_path = os.path.join(os.path.realpath(os.path.join( - os.path.dirname(__file__), "../../models", "traub_cond_multisyn.nestml"))) + os.path.dirname(__file__), os.pardir, os.pardir, "models", "neurons", "traub_cond_multisyn.nestml"))) target_path = "target" - module_name = 'nestmlmodule' - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - suffix = '_nestml' + module_name = "nestmlmodule" + suffix = "_nestml" - to_nest(input_path=input_path, - target_path=target_path, - logging_level="INFO", - suffix=suffix, - module_name=module_name) - - install_nest(target_path, nest_path) + generate_nest_target(input_path, + target_path=target_path, + logging_level="INFO", + suffix=suffix, + module_name=module_name) nest.Install("nestmlmodule") model = "traub_cond_multisyn_nestml" @@ -63,30 +65,42 @@ def test_traub_cond_multisyn(self): nest.SetKernelStatus({"resolution": dt}) neuron1 = nest.Create(model, 1) - neuron1.set({'I_e': 100.0}) + nest.SetStatus(neuron1, {"I_e": 100.0}) neuron2 = nest.Create(model) - neuron2.set({"tau_AMPA_1": 0.1, - "tau_AMPA_2": 2.4, - "AMPA_g_peak": 0.1}) + nest.SetStatus(neuron2, {"tau_AMPA_1": 0.1, + "tau_AMPA_2": 2.4, + "AMPA_g_peak": 0.1}) multimeter = nest.Create("multimeter", 2) - multimeter[0].set({"record_from": ["V_m"], - "interval": dt}) + if nest_version.startswith("v2"): + nest.SetStatus([multimeter[0]], {"record_from": ["V_m"], + "interval": dt}) + else: + nest.SetStatus(multimeter[0], {"record_from": ["V_m"], + "interval": dt}) record_from = ["V_m", "I_syn_ampa", "I_syn_nmda", "I_syn_gaba_a", "I_syn_gaba_b"] - multimeter[1].set({"record_from": record_from, - "interval": dt}) - # {'AMPA': 1, 'NMDA': 2, 'GABA_A': 3, 'GABA_B': 4} + if nest_version.startswith("v2"): + nest.SetStatus([multimeter[1]], {"record_from": record_from, + "interval": dt}) + else: + nest.SetStatus(multimeter[1], {"record_from": record_from, + "interval": dt}) + # {"AMPA": 1, "NMDA": 2, "GABA_A": 3, "GABA_B": 4} nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 1}) # AMPA nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 2}) # NMDA nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 3}) # GABAA nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 4}) # GABAB - nest.Connect(multimeter[0], neuron1, "one_to_one") - nest.Connect(multimeter[1], neuron2) - - spike_recorder = nest.Create("spike_recorder") + if nest_version.startswith("v2"): + nest.Connect([multimeter[0]], neuron1, "one_to_one") + nest.Connect([multimeter[1]], neuron2) + spike_recorder = nest.Create("spike_detector") + else: + nest.Connect(multimeter[0], neuron1, "one_to_one") + nest.Connect(multimeter[1], neuron2) + spike_recorder = nest.Create("spike_recorder") nest.Connect(neuron1, spike_recorder) nest.Simulate(t_simulation) @@ -94,8 +108,8 @@ def test_traub_cond_multisyn(self): Voltages = dmm["events"]["V_m"] tv = dmm["events"]["times"] - dSD = nest.GetStatus(spike_recorder, keys='events')[0] - spikes = dSD['senders'] + dSD = nest.GetStatus(spike_recorder, keys="events")[0] + spikes = dSD["senders"] ts = dSD["times"] firing_rate = len(spikes) / t_simulation * 1000 @@ -116,7 +130,7 @@ def test_traub_cond_multisyn(self): ax[1].plot(tv, g, lw=2, label=labels[j]) j += 1 - ax[2].plot(ts, spikes, 'k.') + ax[2].plot(ts, spikes, "k.") ax[2].set_xlabel("Time [ms]") ax[2].set_xlim(0, t_simulation) ax[2].set_ylabel("Spikes") @@ -125,8 +139,7 @@ def test_traub_cond_multisyn(self): ax[1].set_ylabel("I_syn") ax[1].legend(frameon=False, loc="upper right") - plt.savefig("resources/traub_cond_multisyn.png") - # plt.show() + plt.savefig("traub_cond_multisyn.png") if __name__ == "__main__": diff --git a/tests/nest_tests/traub_psc_alpha_test.py b/tests/nest_tests/traub_psc_alpha_test.py index c04e62726..cf44b23a8 100644 --- a/tests/nest_tests/traub_psc_alpha_test.py +++ b/tests/nest_tests/traub_psc_alpha_test.py @@ -19,11 +19,14 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import numpy as np import os -import nest import unittest -import numpy as np -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target try: import matplotlib @@ -32,6 +35,8 @@ except BaseException: TEST_PLOTS = False +nest_version = NESTTools.detect_nest_version() + class NestWBCondExpTest(unittest.TestCase): @@ -41,19 +46,16 @@ def test_traub_psc_alpha(self): os.makedirs("target") input_path = os.path.join(os.path.realpath(os.path.join( - os.path.dirname(__file__), "../../models", "traub_psc_alpha.nestml"))) + os.path.dirname(__file__), os.pardir, os.pardir, "models", "neurons", "traub_psc_alpha.nestml"))) target_path = "target" - module_name = 'nestmlmodule' - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - suffix = '_nestml' + module_name = "nestmlmodule" + suffix = "_nestml" - to_nest(input_path=input_path, - target_path=target_path, - logging_level="INFO", - suffix=suffix, - module_name=module_name) - - install_nest(target_path, nest_path) + generate_nest_target(input_path, + target_path=target_path, + logging_level="INFO", + suffix=suffix, + module_name=module_name) nest.Install("nestmlmodule") model = "traub_psc_alpha_nestml" @@ -63,13 +65,15 @@ def test_traub_psc_alpha(self): nest.SetKernelStatus({"resolution": dt}) neuron = nest.Create(model) - parameters = nest.GetDefaults(model) - neuron.set({'I_e': 130.0}) + nest.SetStatus(neuron, {"I_e": 130.0}) multimeter = nest.Create("multimeter") - multimeter.set({"record_from": ["V_m"], - "interval": dt}) - spike_recorder = nest.Create("spike_recorder") + nest.SetStatus(multimeter, {"record_from": ["V_m"], + "interval": dt}) + if nest_version.startswith("v2"): + spike_recorder = nest.Create("spike_detector") + else: + spike_recorder = nest.Create("spike_recorder") nest.Connect(multimeter, neuron) nest.Connect(neuron, spike_recorder) nest.Simulate(t_simulation) @@ -77,8 +81,8 @@ def test_traub_psc_alpha(self): dmm = nest.GetStatus(multimeter)[0] Voltages = dmm["events"]["V_m"] tv = dmm["events"]["times"] - dSD = nest.GetStatus(spike_recorder, keys='events')[0] - spikes = dSD['senders'] + dSD = nest.GetStatus(spike_recorder, keys="events")[0] + spikes = dSD["senders"] ts = dSD["times"] firing_rate = len(spikes) / t_simulation * 1000 @@ -86,13 +90,12 @@ def test_traub_psc_alpha(self): expected_value = np.abs(firing_rate - 50) tolerance_value = 5 # Hz - self.assertLessEqual(expected_value, tolerance_value) + assert expected_value <= tolerance_value if TEST_PLOTS: - fig, ax = plt.subplots(2, figsize=(8, 6), sharex=True) ax[0].plot(tv, Voltages, lw=2, color="k") - ax[1].plot(ts, spikes, 'ko') + ax[1].plot(ts, spikes, "ko") ax[1].set_xlabel("Time [ms]") ax[1].set_xlim(0, t_simulation) ax[1].set_ylabel("Spikes") @@ -102,8 +105,7 @@ def test_traub_psc_alpha(self): for i in ts: ax[0].axvline(x=i, lw=1., ls="--", color="gray") - plt.savefig("resources/traub_psc_alpha.png") - # plt.show() + plt.savefig("traub_psc_alpha.png") if __name__ == "__main__": diff --git a/tests/nest_tests/vector_code_generator_test.py b/tests/nest_tests/vector_code_generator_test.py new file mode 100644 index 000000000..74b20eb51 --- /dev/null +++ b/tests/nest_tests/vector_code_generator_test.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# +# vector_code_generator_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import os +import unittest + +from pynestml.codegeneration.nest_code_generator import NESTCodeGenerator +from pynestml.frontend.pynestml_frontend import generate_nest_target + +from pynestml.utils.model_parser import ModelParser + +from pynestml.frontend.frontend_configuration import FrontendConfiguration + +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_units import PredefinedUnits + + +class VectorCodeGenerationTest(unittest.TestCase): + """ + Tests code generator for vectors + """ + + def setUp(self): + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedFunctions.register_functions() + PredefinedVariables.register_variables() + SymbolTable.initialize_symbol_table( + ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + Logger.init_logger(LoggingLevel.INFO) + + self.target_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + os.pardir, 'target')))) + + def test_vector_code_generation(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join( + 'resources', 'VectorsDeclarationAndAssignment.nestml')))) + + params = list() + params.append('--input_path') + params.append(input_path) + params.append('--logging_level') + params.append('INFO') + params.append('--target_path') + params.append(self.target_path) + params.append('--dev') + FrontendConfiguration.parse_config(params) + + compilation_unit = ModelParser.parse_model(input_path) + + nestCodeGenerator = NESTCodeGenerator() + nestCodeGenerator.generate_code(compilation_unit.get_neuron_list()) + + def test_vector_code_generation_and_build(self): + input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", + "SimpleVectorsModel.nestml"))) + generate_nest_target(input_path=input_path, + target_path=self.target_path, + logging_level="INFO") + + def tearDown(self) -> None: + import shutil + shutil.rmtree(self.target_path) diff --git a/tests/nest_tests/wb_cond_exp_test.py b/tests/nest_tests/wb_cond_exp_test.py index 836188930..527d96a50 100644 --- a/tests/nest_tests/wb_cond_exp_test.py +++ b/tests/nest_tests/wb_cond_exp_test.py @@ -21,7 +21,7 @@ try: import matplotlib as mpl - mpl.use('agg') + mpl.use("agg") import matplotlib.pyplot as plt TEST_PLOTS = True except BaseException: @@ -29,10 +29,15 @@ import os -import nest import unittest import numpy as np -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +import nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + +nest_version = NESTTools.detect_nest_version() class NestWBCondExpTest(unittest.TestCase): @@ -43,19 +48,16 @@ def test_wb_cond_exp(self): os.makedirs("target") input_path = os.path.join(os.path.realpath(os.path.join( - os.path.dirname(__file__), "../../models", "wb_cond_exp.nestml"))) + os.path.dirname(__file__), os.pardir, os.pardir, "models", "neurons", "wb_cond_exp.nestml"))) target_path = "target" - module_name = 'nestmlmodule' - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - suffix = '_nestml' - - to_nest(input_path=input_path, - target_path=target_path, - logging_level="INFO", - suffix=suffix, - module_name=module_name) + module_name = "nestmlmodule" + suffix = "_nestml" - install_nest(target_path, nest_path) + generate_nest_target(input_path, + target_path=target_path, + logging_level="INFO", + suffix=suffix, + module_name=module_name) nest.Install(module_name) model = "wb_cond_exp_nestml" @@ -65,13 +67,15 @@ def test_wb_cond_exp(self): nest.SetKernelStatus({"resolution": dt}) neuron = nest.Create(model) - parameters = nest.GetDefaults(model) - neuron.set({'I_e': 75.0}) + nest.SetStatus(neuron, {"I_e": 75.0}) multimeter = nest.Create("multimeter") - multimeter.set({"record_from": ["V_m"], - "interval": dt}) - spike_recorder = nest.Create("spike_recorder") + nest.SetStatus(multimeter, {"record_from": ["V_m"], + "interval": dt}) + if nest_version.startswith("v2"): + spike_recorder = nest.Create("spike_detector") + else: + spike_recorder = nest.Create("spike_recorder") nest.Connect(multimeter, neuron) nest.Connect(neuron, spike_recorder) nest.Simulate(t_simulation) @@ -79,8 +83,8 @@ def test_wb_cond_exp(self): dmm = nest.GetStatus(multimeter)[0] Voltages = dmm["events"]["V_m"] tv = dmm["events"]["times"] - dSD = nest.GetStatus(spike_recorder, keys='events')[0] - spikes = dSD['senders'] + dSD = nest.GetStatus(spike_recorder, keys="events")[0] + spikes = dSD["senders"] ts = dSD["times"] firing_rate = len(spikes) / t_simulation * 1000 @@ -91,7 +95,7 @@ def test_wb_cond_exp(self): if TEST_PLOTS: fig, ax = plt.subplots(2, figsize=(8, 6), sharex=True) ax[0].plot(tv, Voltages, lw=2, color="k") - ax[1].plot(ts, spikes, 'ko') + ax[1].plot(ts, spikes, "ko") ax[1].set_xlabel("Time [ms]") ax[1].set_xlim(0, t_simulation) ax[1].set_ylabel("Spikes") @@ -101,8 +105,7 @@ def test_wb_cond_exp(self): for i in ts: ax[0].axvline(x=i, lw=1., ls="--", color="gray") - plt.savefig("resources/wb_cond_exp.png") - # plt.show() + plt.savefig("wb_cond_exp.png") self.assertLessEqual(expected_value, tolerance_value) diff --git a/tests/nest_tests/wb_cond_multisyn_test.py b/tests/nest_tests/wb_cond_multisyn_test.py index 7710b5628..b3bea0df1 100644 --- a/tests/nest_tests/wb_cond_multisyn_test.py +++ b/tests/nest_tests/wb_cond_multisyn_test.py @@ -19,6 +19,10 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import numpy as np +import os +import unittest + try: import matplotlib as mpl mpl.use("Agg") @@ -28,11 +32,13 @@ TEST_PLOTS = False -import os import nest -import unittest -import numpy as np -from pynestml.frontend.pynestml_frontend import to_nest, install_nest + +from pynestml.codegeneration.nest_tools import NESTTools +from pynestml.frontend.pynestml_frontend import generate_nest_target + + +nest_version = NESTTools.detect_nest_version() class NestWBCondExpTest(unittest.TestCase): @@ -43,19 +49,16 @@ def test_wb_cond_multisyn(self): os.makedirs("target") input_path = os.path.join(os.path.realpath(os.path.join( - os.path.dirname(__file__), "../../models", "wb_cond_multisyn.nestml"))) + os.path.dirname(__file__), os.pardir, os.pardir, "models", "neurons", "wb_cond_multisyn.nestml"))) target_path = "target" - module_name = 'nestmlmodule' - nest_path = nest.ll_api.sli_func("statusdict/prefix ::") - suffix = '_nestml' - - to_nest(input_path=input_path, - target_path=target_path, - logging_level="INFO", - suffix=suffix, - module_name=module_name) + module_name = "nestmlmodule" + suffix = "_nestml" - install_nest(target_path, nest_path) + generate_nest_target(input_path, + target_path=target_path, + logging_level="INFO", + suffix=suffix, + module_name=module_name) nest.Install("nestmlmodule") model = "wb_cond_multisyn_nestml" @@ -65,13 +68,15 @@ def test_wb_cond_multisyn(self): nest.SetKernelStatus({"resolution": dt}) neuron = nest.Create(model) - parameters = nest.GetDefaults(model) - neuron.set({'I_e': 75.0}) + nest.SetStatus(neuron, {"I_e": 75.0}) multimeter = nest.Create("multimeter") - multimeter.set({"record_from": ["V_m"], - "interval": dt}) - spike_recorder = nest.Create("spike_recorder") + nest.SetStatus(multimeter, {"record_from": ["V_m"], + "interval": dt}) + if nest_version.startswith("v2"): + spike_recorder = nest.Create("spike_detector") + else: + spike_recorder = nest.Create("spike_recorder") nest.Connect(multimeter, neuron) nest.Connect(neuron, spike_recorder) nest.Simulate(t_simulation) @@ -79,8 +84,8 @@ def test_wb_cond_multisyn(self): dmm = nest.GetStatus(multimeter)[0] Voltages = dmm["events"]["V_m"] tv = dmm["events"]["times"] - dSD = nest.GetStatus(spike_recorder, keys='events')[0] - spikes = dSD['senders'] + dSD = nest.GetStatus(spike_recorder, keys="events")[0] + spikes = dSD["senders"] ts = dSD["times"] firing_rate = len(spikes) / t_simulation * 1000 @@ -91,7 +96,7 @@ def test_wb_cond_multisyn(self): if TEST_PLOTS: fig, ax = plt.subplots(2, figsize=(8, 6), sharex=True) ax[0].plot(tv, Voltages, lw=2, color="k") - ax[1].plot(ts, spikes, 'ko') + ax[1].plot(ts, spikes, "ko") ax[1].set_xlabel("Time [ms]") ax[1].set_xlim(0, t_simulation) ax[1].set_ylabel("Spikes") @@ -101,8 +106,7 @@ def test_wb_cond_multisyn(self): for i in ts: ax[0].axvline(x=i, lw=1., ls="--", color="gray") - plt.savefig("resources/wb_cond_multisyn.png") - # plt.show() + plt.savefig("wb_cond_multisyn.png") self.assertLessEqual(expected_value, tolerance_value) diff --git a/tests/nestml_printer_test.py b/tests/nestml_printer_test.py index daaedcc1d..89aea299b 100644 --- a/tests/nestml_printer_test.py +++ b/tests/nestml_printer_test.py @@ -21,80 +21,76 @@ import unittest -from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.codegeneration.printers.nestml_printer import NESTMLPrinter from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.predefined_units import PredefinedUnits from pynestml.symbols.predefined_variables import PredefinedVariables -from pynestml.utils.ast_nestml_printer import ASTNestMLPrinter +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.model_parser import ModelParser -# setups the infrastructure -PredefinedUnits.register_units() -PredefinedTypes.register_types() -PredefinedFunctions.register_functions() -PredefinedVariables.register_variables() -SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) -Logger.init_logger(LoggingLevel.INFO) - class NestMLPrinterTest(unittest.TestCase): """ - Tests if the NestML printer works as intended. + Tests if NESTMLPrinter works as intended. """ + def setUp(self): + # setups the infrastructure + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedFunctions.register_functions() + PredefinedVariables.register_variables() + SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + Logger.init_logger(LoggingLevel.INFO) + def test_block_with_variables_with_comments(self): - block = '\n' \ - '/* pre1\n' \ - '* pre2\n' \ - '*/\n' \ + block = '# pre1\n' \ + '# pre2\n' \ 'state: # in\n' \ 'end\n' \ - '/* post1\n' \ - '* post2\n' \ - '*/\n\n' + '# post1\n' \ + '# post2\n\n' model = ModelParser.parse_block_with_variables(block) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(block, model_printer.print_node(model)) def test_block_with_variables_without_comments(self): block = 'state:\n' \ 'end' model = ModelParser.parse_block_with_variables(block) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(block, model_printer.print_node(model)) def test_assignment_with_comments(self): - assignment = '\n' \ - '/* pre */\n' \ - 'a = b # in\n' \ - '/* post */\n' \ + assignment = ' # pre\n' \ + ' a = b # in\n' \ + ' # post\n' \ '\n' - model = ModelParser.parse_assignment(assignment) - model_printer = ASTNestMLPrinter() + model = ModelParser.parse_block(assignment) + model_printer = NESTMLPrinter() self.assertEqual(assignment, model_printer.print_node(model)) def test_assignment_without_comments(self): assignment = 'a = b\n' model = ModelParser.parse_assignment(assignment) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(assignment, model_printer.print_node(model)) def test_function_with_comments(self): - t_function = '\n' \ - '/*pre func*/\n' \ - 'function test(Tau_1 ms) real: # in func\n\n' \ - ' /* decl pre */\n' \ + t_function = '# pre func\n' \ + 'function test(Tau_1 ms) real: # in func\n' \ + ' # decl pre\n' \ ' exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms # decl in\n' \ - ' /* decl post */\n' \ + ' # decl post\n' \ '\n' \ ' return normalisation_factor\n' \ 'end\n' \ - '/*post func*/\n\n' + '# post func\n\n' model = ModelParser.parse_function(t_function) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(t_function, model_printer.print_node(model)) def test_function_without_comments(self): @@ -103,133 +99,144 @@ def test_function_without_comments(self): ' return normalisation_factor\n' \ 'end\n' model = ModelParser.parse_function(t_function) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(t_function, model_printer.print_node(model)) def test_function_call_with_comments(self): - function_call = '\n/* pre */\n' \ - 'min(1,2) # in\n' \ - '/* post */\n\n' - model = ModelParser.parse_stmt(function_call) - model_printer = ASTNestMLPrinter() + function_call = ' # pre\n' \ + ' min(1,2) # in\n' \ + ' # post\n\n' + model = ModelParser.parse_block(function_call) + model_printer = NESTMLPrinter() self.assertEqual(function_call, model_printer.print_node(model)) def test_function_call_without_comments(self): function_call = 'min(1,2)\n' model = ModelParser.parse_stmt(function_call) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(function_call, model_printer.print_node(model)) def test_neuron_with_comments(self): - neuron = '\n/*pre*/\n' \ + neuron = '# pre\n' \ 'neuron test: # in\n' \ 'end\n' \ - '/*post*/\n\n' - model = ModelParser.parse_neuron(neuron) - model_printer = ASTNestMLPrinter() + '# post\n\n' + model = ModelParser.parse_nestml_compilation_unit(neuron) + model_printer = NESTMLPrinter() self.assertEqual(neuron, model_printer.print_node(model)) - def test_neuron_without_comments(self): - neuron = 'neuron test:\n' \ + def test_neuron_with_comments(self): + neuron = '# pre\n' \ + 'neuron test: # in\n' \ + 'end\n' \ + '# post\n\n' + model = ModelParser.parse_nestml_compilation_unit(neuron) + model_printer = NESTMLPrinter() + self.assertEqual(neuron, model_printer.print_node(model)) + + def test_neuron_with_docstring(self): + neuron = '"""hello, world\n' \ + '\n' \ + '3.141592653589793"""\n' \ + 'neuron test:\n' \ 'end\n' model = ModelParser.parse_neuron(neuron) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(neuron, model_printer.print_node(model)) def test_declaration_with_comments(self): - declaration = '\n' \ - '/*pre*/\n' \ - 'test mV = 10mV # in\n' \ - '/*post*/\n\n' - model = ModelParser.parse_declaration(declaration) - model_printer = ASTNestMLPrinter() + declaration = ' # pre\n' \ + ' test mV = 10mV # in\n' \ + ' # post\n\n' + model = ModelParser.parse_block(declaration) + model_printer = NESTMLPrinter() self.assertEqual(declaration, model_printer.print_node(model)) def test_declaration_without_comments(self): declaration = 'test mV = 10mV\n' model = ModelParser.parse_declaration(declaration) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(declaration, model_printer.print_node(model)) def test_equations_block_with_comments(self): - block = '\n/*pre*/\n' \ + block = '# pre\n' \ 'equations: # in\n' \ 'end\n' \ - '/*post*/\n\n' + '# post\n\n' model = ModelParser.parse_equations_block(block) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(block, model_printer.print_node(model)) def test_equations_block_without_comments(self): block = 'equations:\n' \ 'end\n' model = ModelParser.parse_equations_block(block) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(block, model_printer.print_node(model)) def test_for_stmt_with_comments(self): - stmt = '\n/*pre*/\n' \ - 'for i in 10 - 3.14...10 + 3.14 step -1: # in\n' \ - 'end\n' \ - '/*post*/\n\n' - model = ModelParser.parse_for_stmt(stmt) - model_printer = ASTNestMLPrinter() + stmt = ' # pre\n' \ + ' for i in 10 - 3.14...10 + 3.14 step -1: # in\n' \ + ' end\n' \ + ' # post\n\n' + model = ModelParser.parse_block(stmt) + model_printer = NESTMLPrinter() self.assertEqual(stmt, model_printer.print_node(model)) def test_for_stmt_without_comments(self): stmt = 'for i in 10 - 3.14...10 + 3.14 step -1: # in\n' \ 'end\n' model = ModelParser.parse_for_stmt(stmt) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(stmt, model_printer.print_node(model)) def test_while_stmt_with_comments(self): - stmt = '\n/*pre*/\n' \ - 'while true: # in \n' \ - 'end\n' \ - '/*post*/\n\n' - model = ModelParser.parse_while_stmt(stmt) - model_printer = ASTNestMLPrinter() + stmt = ' # pre\n' \ + ' while true: # in \n' \ + ' end\n' \ + ' # post\n\n' + model = ModelParser.parse_block(stmt) + model_printer = NESTMLPrinter() self.assertEqual(stmt, model_printer.print_node(model)) def test_while_stmt_without_comments(self): stmt = 'while true:\n' \ 'end\n' model = ModelParser.parse_while_stmt(stmt) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(stmt, model_printer.print_node(model)) def test_update_block_with_comments(self): - block = '\n/*pre*/\n' \ + block = '# pre\n' \ 'update: # in\n' \ 'end\n' \ - '/*post*/\n\n' + '# post\n\n' model = ModelParser.parse_update_block(block) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(block, model_printer.print_node(model)) def test_update_block_without_comments(self): block = 'update:\n' \ 'end\n' model = ModelParser.parse_update_block(block) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(block, model_printer.print_node(model)) def test_variable(self): var = 'V_m' model = ModelParser.parse_variable(var) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(var, model_printer.print_node(model)) def test_unit_type(self): unit = '1/(mV*kg**2)' model = ModelParser.parse_unit_type(unit) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(unit, model_printer.print_node(model)) def test_unary_operator(self): ops = {'-', '+', '~'} for op in ops: model = ModelParser.parse_unary_operator(op) - model_printer = ASTNestMLPrinter() + model_printer = NESTMLPrinter() self.assertEqual(op, model_printer.print_node(model)) diff --git a/tests/pynestml_frontend_test.py b/tests/pynestml_frontend_test.py index 3300b3e00..06d72b81a 100644 --- a/tests/pynestml_frontend_test.py +++ b/tests/pynestml_frontend_test.py @@ -18,6 +18,7 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + import os import pytest import sys @@ -39,85 +40,106 @@ class PyNestMLFrontendTest(unittest.TestCase): Tests if the frontend works as intended and is able to process handed over arguments. """ - def test_codegeneration_for_single_model(self): + def test_codegeneration_autodoc(self): path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), - os.path.join('..', 'models', 'iaf_psc_exp.nestml')))) + os.path.join(os.pardir, "models", "neurons", "iaf_psc_exp.nestml")))) params = list() - params.append('nestml') - params.append('--input_path') + params.append("nestml") + params.append("--input_path") params.append(path) - params.append('--logging_level') - params.append('INFO') - params.append('--target_path') - params.append('target/models') - params.append('--store_log') - params.append('--dev') + params.append("--target_platform") + params.append("autodoc") + params.append("--logging_level") + params.append("INFO") + params.append("--target_path") + params.append("target_autodoc") + params.append("--store_log") + params.append("--dev") + exit_code = None - with patch.object(sys, 'argv', params): + with patch.object(sys, "argv", params): exit_code = main() self.assertTrue(exit_code == 0) def test_module_name_parsing_right_module_name_specified(self): - path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join('..', 'models')))) + path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(os.pardir, "models")))) params = list() - params.append('--input_path') + params.append("--input_path") params.append(path) - params.append('--module_name') - params.append('xyzzymodule') + params.append("--module_name") + params.append("xyzzymodule") FrontendConfiguration.parse_config(params) assert FrontendConfiguration.module_name == 'xyzzymodule' def test_module_name_parsing_wrong_module_name_specified(self): with pytest.raises(Exception): - path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join('..', 'models')))) + path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(os.pardir, "models")))) + + params = list() + params.append("--input_path") + params.append(path) + params.append("--module_name") + params.append("xyzzy") + FrontendConfiguration.parse_config(params) + + def test_input_path_handling_empty_dir(self): + with pytest.raises(Exception): + path = tempfile.mkdtemp(prefix="nestml-") params = list() - params.append('--input_path') + params.append("--input_path") params.append(path) - params.append('--module_name') - params.append('xyzzy') + params.append("--logging_level") + params.append("INFO") FrontendConfiguration.parse_config(params) - def test_module_name_parsing_input_path_is_file(self): - h, path = tempfile.mkstemp(prefix='nestml') - basename = os.path.basename(os.path.normpath(path)) + def test_input_path_handling_dir_one_file(self): + path = tempfile.mkdtemp(prefix="nestml-") + fd, fpath = tempfile.mkstemp(dir=path, suffix=".nestml") + with open(fpath, "w") as f: + f.write("neuron foo:\nend\n") + os.close(fd) params = list() - params.append('--input_path') + params.append("--input_path") params.append(path) + params.append("--logging_level") + params.append("INFO") FrontendConfiguration.parse_config(params) - assert FrontendConfiguration.module_name == 'nestmlmodule' - def test_module_name_parsing_input_path_is_dir(self): - path = tempfile.mkdtemp(prefix='nestml') - basename = os.path.basename(os.path.normpath(path)) + assert len(FrontendConfiguration.paths_to_compilation_units) == 1 + + def test_input_path_handling_dir_two_files(self): + path = tempfile.mkdtemp(prefix="nestml-") + fd, fpath = tempfile.mkstemp(dir=path, suffix=".nestml") + with open(fpath, "w") as f: + f.write("neuron foo:\nend\n") + os.close(fd) + fd, fpath = tempfile.mkstemp(dir=path, suffix=".nestml") + with open(fpath, "w") as f: + f.write("neuron bar:\nend\n") + os.close(fd) params = list() - params.append('--input_path') + params.append("--input_path") params.append(path) - params.append('--logging_level') - params.append('INFO') + params.append("--logging_level") + params.append("INFO") FrontendConfiguration.parse_config(params) - assert FrontendConfiguration.module_name == basename + 'module' - - def test_module_name_parsing_input_path_is_wrong_dir(self): - with pytest.raises(Exception): - path = tempfile.mkdtemp(prefix='nestml-') - params = list() - params.append('--input_path') - params.append(path) - params.append('--logging_level') - params.append('INFO') - FrontendConfiguration.parse_config(params) + assert len(FrontendConfiguration.paths_to_compilation_units) == 2 def tearDown(self): # clean up import shutil - shutil.rmtree(FrontendConfiguration.target_path) + if FrontendConfiguration.target_path: + try: + shutil.rmtree(FrontendConfiguration.target_path) + except Exception: + pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/random_number_generators_test.py b/tests/random_number_generators_test.py index 327462b9c..b5848fe57 100644 --- a/tests/random_number_generators_test.py +++ b/tests/random_number_generators_test.py @@ -44,7 +44,7 @@ def setUp(self): PredefinedVariables.register_variables() PredefinedFunctions.register_functions() - def test_invalid_element_defined_after_usage(self): + def test_random_number_generators(self): model = ModelParser.parse_model( os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'random_number_generators_test.nestml')) diff --git a/tests/resources/BlockTest.nestml b/tests/resources/BlockTest.nestml index 1bce2673b..82262f876 100644 --- a/tests/resources/BlockTest.nestml +++ b/tests/resources/BlockTest.nestml @@ -1,31 +1,39 @@ -/** - * - * BlockTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if all non-actively used types of blocks are readable, and if the corresponding AST - * can be created. It is used to test the following part of the grammar: - * forStmt : 'for' var=NAME 'in' vrom=expression '...' - * to=expression 'step' step=signedNumericLiteral BLOCK_OPEN block BLOCK_CLOSE; - * whileStmt : 'while' expression BLOCK_OPEN block BLOCK_CLOSE; -*/ +""" +BlockTest.nestml +################ + + +Description ++++++++++++ + +This model is used to test if all non-actively used types of blocks are readable, and if the corresponding AST +can be created. It is used to test the following part of the grammar: + +forStmt : 'for' var=NAME 'in' vrom=expression '...' + to=expression 'step' step=signedNumericLiteral BLOCK_OPEN block BLOCK_CLOSE; +whileStmt : 'while' expression BLOCK_OPEN block BLOCK_CLOSE; + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: update: while j < 3.14 and j>0 or False==true: diff --git a/tests/resources/CommentTest.nestml b/tests/resources/CommentTest.nestml index b533a008b..2d9ef1e51 100644 --- a/tests/resources/CommentTest.nestml +++ b/tests/resources/CommentTest.nestml @@ -1,34 +1,39 @@ -/** - * - * CommentTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test whether comments are detected and processed as such. Moreover, it tests - * if all comments are attached to their respective elements. -*/ +""" +CommentTest.nestml +################## +Description ++++++++++++ + +This model is used to test whether comments are detected and processed as such. Moreover, it tests +if all comments are attached to their respective elements. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron commentTest: - #init_values comment ok - initial_values: + #state comment ok + state: #pre comment not ok #pre comment 1 ok @@ -73,4 +78,4 @@ neuron commentTest: end -end \ No newline at end of file +end diff --git a/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml b/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml index eb8d3dd1e..c251f5e98 100644 --- a/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,31 @@ -/** - * - * CompoundAssignmentWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +CompoundAssignmentWithDifferentButCompatibleUnits.nestml +######################################################## + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: - lhs V + lhs V = 0 V end update: diff --git a/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml b/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml index fb97b9adb..dc8a28aeb 100644 --- a/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml +++ b/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml @@ -1,25 +1,28 @@ -/** - * - * DeclarationWithDifferentButCompatibleUnitMagnitude.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +DeclarationWithDifferentButCompatibleUnitMagnitude.nestml +######################################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: lhs mV = 10V diff --git a/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml b/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml index 00e82ebde..6fae28698 100644 --- a/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml @@ -1,25 +1,28 @@ -/** - * - * DeclarationWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +DeclarationWithDifferentButCompatibleUnits.nestml +################################################# + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: V_m mV = (10 pA) / (100 pF) * (1 ms) diff --git a/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml b/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml index d69ca6a03..a308233e2 100644 --- a/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml +++ b/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml @@ -1,25 +1,28 @@ -/** - * - * DeclarationWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +DeclarationWithDifferentButCompatibleUnits.nestml +################################################# + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: V mV = -70. mV diff --git a/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml b/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml index 3bc760811..a17ef4ce2 100644 --- a/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml +++ b/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml @@ -1,28 +1,31 @@ -/** - * - * DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml +############################################################ + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: - lhs mV + lhs mV = 0 mV end update: diff --git a/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml b/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml index 9ae658cd5..4cb8c40f3 100644 --- a/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,31 @@ -/** - * - * DirectAssignmentWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +DirectAssignmentWithDifferentButCompatibleUnits.nestml +###################################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: - lhs mV + lhs mV = 0 mV end update: diff --git a/tests/resources/ExpressionCollection.nestml b/tests/resources/ExpressionCollection.nestml index db31d8b98..840a79d27 100644 --- a/tests/resources/ExpressionCollection.nestml +++ b/tests/resources/ExpressionCollection.nestml @@ -1,28 +1,16 @@ -/* - * - * ExpressionCollection.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This test neuron is used to test if parsing of expression works as required. - * For more details see ExpressionParserTest.py. It is used to test the following part of the grammar: - * expression : leftParentheses='(' term=expression rightParentheses=')' +""" +ExpressionCollection.nestml +########################### + + +Description ++++++++++++ + +This test neuron is used to test if parsing of expression works as required. + +For more details see ExpressionParserTest.py. It is used to test the following part of the grammar: + +expression : leftParentheses='(' term=expression rightParentheses=')' | left=expression powOp='**' right=expression | unaryOperator term=expression | left=expression (timesOp='*' | divOp='/' | moduloOp='%') right=expression @@ -34,15 +22,145 @@ | condition=expression '?' ifTrue=expression ':' ifNot=expression | simpleExpression ; - * and the respective sub-rules. -*/ +and the respective sub-rules. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron ExpressionCollection: - update: + state: + r integer = 2 # counts number of tick during the refractory period + I_syn_ex pA = -0.5 pA # inputs from the exc spikes + I_syn_ex' pA/ms = 0.12 pA/ms # inputs from the exc spikes + I_syn_in pA = 0.055 pA # inputs from the inh spikes + I_syn_in' pA/ms = 0.01 pA/ms # inputs from the inh spikes + r_potassium integer = 1 + g_spike boolean = false + + g_AMPA nS = 0. + g_NMDA nS = 0. + g_GABAA nS = 0. + g_GABAB nS = 0. + IKNa_D nS = 0. + IT_m nS = 0. + IT_h nS = 0. + Ih_m nS = 0. + + g_AMPA' nS/ms = 0. + g_NMDA' nS/ms = 0. + g_GABAA' nS/ms = 0. + g_GABAB' nS/ms = 0. + end + + parameters: #neuron aeif_cond_alpha_neuron testA ms**2 = 1 testB 1/ms = 12 testC ms**-2 = 1 + + test11 pF = 281.0pF ## Membrane Capacitance in pF + test12 ms = 0.0ms ## Refractory period in ms + test13 mV = -60.0mV ## Reset Potential in mV + test14 nS = 30.0nS ## Leak Conductance in nS + test15 mV = -70.6mV ## Leak reversal Potential (aka resting potential) in mV + test16 pA = 0pA + + beta real = 1. # check for conflict with sympy built-in functions like beta() + + #hh_cond_exp_traub_neuron + test70 nS = 0nS # Inhibitory synaptic conductance + + # synapses: exponential conductance + g_Na nS = 20000.0nS # Threshold Potential in mV + g_K nS = 6000.0nS # K Conductance + g_L nS = 10nS # Leak Conductance + C_m pF = 200.0pF # Membrane Capacitance in pF + E_Na mV = 50mV # Reversal potentials + E_K mV = -90.mV # Potassium reversal potential + E_L mV = -60.mV # Leak reversal Potential (aka resting potential) in mV + V_T mV = -63.0mV # Voltage offset that controls dynamics. For default + # parameters, V_T = -63mV results in a threshold around -50mV. + tau_syn_ex ms = 5.0ms # Synaptic Time Constant Excitatory Synapse in ms + tau_syn_in ms = 10.0ms # Synaptic Time Constant for Inhibitory Synapse in ms + I_e pA = 0pA # Constant Current in pA + E_exc mV = 0.0 mV # Excitatory synaptic reversal potential + E_inh mV = -80.0mV # Inhibitory synaptic reversal potential + V_m mV = E_L # Membrane potential + g_in nS = 0nS # Inhibitory synaptic conductance + g_ex nS = 0nS # Excitatory synaptic conductance + + # Act-h' + t_ref ms = 2.0 ms # Refractory period + RefractoryCounts integer = steps(t_ref) + U_old mV = V_m + + # hr_neuron_nestml + Theta mV = Theta_eq # Threshold + + # Synapses + Tau_m ms = 16.0ms # membrane time constant applying to all currents but repolarizing K-current (see [1, p 1677]) + Theta_eq mV = -51.0mV # equilibrium value + Tau_theta ms = 2.0ms # time constant + Tau_spike ms = 1.75ms # membrane time constant applying to repolarizing K-current + + # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA + AMPA_g_peak nS = 0.1nS # peak conductance + AMPA_E_rev mV = 0.0mV # reversal potential + AMPA_Tau_1 ms = 0.5ms # rise time + AMPA_Tau_2 ms = 2.4ms # decay time, Tau_1 < Tau_2 + NMDA_g_peak nS = 0.075nS # peak conductance + NMDA_Tau_1 ms = 4.0ms # rise time + NMDA_Tau_2 ms = 40.0ms # decay time, Tau_1 < Tau_2 + NMDA_E_rev mV = 0.0mV # reversal potential + NMDA_Vact mV = -58.0mV # inactive for V << Vact, inflection of sigmoid + NMDA_Sact mV = 2.5mV # scale of inactivation + GABA_A_g_peak nS = 0.33nS # peak conductance + GABA_A_Tau_1 ms = 1.0ms # rise time + GABA_A_Tau_2 ms = 7.0ms # decay time, Tau_1 < Tau_2 + GABA_A_E_rev mV = -70.0mV # reversal potential + GABA_B_g_peak nS = 0.0132nS # peak conductance + GABA_B_Tau_1 ms = 60.0ms # rise time + GABA_B_Tau_2 ms = 200.0ms # decay time, Tau_1 < Tau_2 + GABA_B_E_rev mV = -90.0mV # reversal potential for intrinsic current + + # parameters for intrinsic currents + NaP_g_peak nS = 1.0nS # peak conductance for intrinsic current + NaP_E_rev mV = 30.0mV # reversal potential for intrinsic current + KNa_g_peak nS = 1.0nS # peak conductance for intrinsic current + KNa_E_rev mV = -90.0mV # reversal potential for intrinsic current + T_g_peak nS = 1.0nS # peak conductance for intrinsic current + T_E_rev mV = 0.0mV # reversal potential for intrinsic current + h_g_peak nS = 1.0nS # peak conductance for intrinsic current + h_E_rev mV = -40.0mV # reversal potential for intrinsic current + KNa_D_EQ pA = 0.001pA + + # clip and hyperbolic functions + Vclip mV = clip(V_m, -120 mV, 0 mV) + testsinh real = sinh(0.) + testcosh real = cosh(0.) + testtanh real = tanh(0.) + end + + equations: + #neuron aeif_cond_alpha_neuron test0 = E_L test1 = 0pA test2 = min(V_m, V_peak) @@ -50,21 +168,16 @@ neuron ExpressionCollection: test4 = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) test5 = (V_bounded-V_th)/Delta_T test6 = g_L*Delta_T*exp(exp_arg) - test7 = convolve(g_ex, spikesExc) * ( V_bounded - E_ex ) - test8 = convolve(g_in, spikesInh) * ( V_bounded - E_in ) + test7 = convolve(g_ex, exc_spikes) * ( V_bounded - E_exc ) + test8 = convolve(g_in, inh_spikes) * ( V_bounded - E_inh ) test9 = ( -g_L*( V_bounded - E_L ) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim ) / C_m test10 = (a*(V_m - E_L) - w)/tau_w - test11 = 281.0pF ## Membrane Capacitance in pF - test12 = 0.0ms ## Refractory period in ms - test13 = -60.0mV ## Reset Potential in mV - test14 = 30.0nS ## Leak Conductance in nS - test15 = -70.6mV ## Leak reversal Potential (aka resting potential) in mV - test16 = 0pA test17 = nS * e / tau_syn_ex test18 = nS * e / tau_syn_in test19 = steps(t_ref) test20 = r > 0 test21 = V_m >= V_peak + #neuron aeif_cond_exp_neuron test22 = E_L # Membrane potential test23= 0 pA # Spike-adaptation current @@ -73,8 +186,8 @@ neuron ExpressionCollection: test26 = exp(-1/tau_syn_ex*t) test27 = (V_bounded-V_th)/Delta_T test28 = g_L*Delta_T*exp(exp_arg) - test29 = convolve(g_ex, spikeExc) * ( V_bounded - E_ex ) - test30 = convolve(g_in, spikeInh) * ( V_bounded - E_in ) + test29 = convolve(g_ex, spikeExc) * ( V_bounded - E_exc ) + test30 = convolve(g_in, spikeInh) * ( V_bounded - E_inh ) test31 = ( -g_L*( V_bounded - E_L ) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim ) / C_m test32 = (a*(V_bounded - E_L) - w)/tau_w test33 = 281.0pF # Membrane Capacitance in pF @@ -100,37 +213,33 @@ neuron ExpressionCollection: test53 = V_m >= V_peak # threshold crossing detection test54 = RefractoryCounts + 1 test55 = V_reset # clamp potential - test56 += b - test57 = emit_spike() + test58 = min(V_m, V_peak) # prevent exponential divergence test59' = -g_in/tau_syn_in test60 = -g_ex/tau_syn_ex test61 = (V_bounded-V_th)/Delta_T test62 = g_L*Delta_T*exp(exp_arg) - test63 = convolve(g_ex, spikeExc) * ( V_bounded - E_ex ) - test64 = convolve(g_in, spikeInh) * ( V_bounded - E_in ) + test63 = convolve(g_ex, spikeExc) * ( V_bounded - E_exc ) + test64 = convolve(g_in, spikeInh) * ( V_bounded - E_inh ) test65 = ( -g_L*( V_bounded - E_L ) + I_spike - I_syn_exc - I_syn_inh - w + I_e + I_stim ) / C_m test66 = (a*(V_bounded - E_L) - w)/tau_w - test67 += spikeExc * nS - test68 += spikeInh * nS + #hh_cond_exp_traub_neuron - test69 mV = E_L # Membrane potential - test70 = 0nS # Inhibitory synaptic conductance - test71 1/ms = 0.032/(ms* mV ) * ( 15. mV - V_m) / ( exp( ( 15. mV - V_m) / 5. mV ) - 1. ) + test69 = E_L # Membrane potential + test71 = 0.032/(ms* mV ) * ( 15. mV - V_m) / ( exp( ( 15. mV - V_m) / 5. mV ) - 1. ) inline test72 1/ms = 0.5 /ms * exp( ( 10. mV - V_m ) / 40. mV ) inline test73 1/ms = 0.32/(ms* mV ) * ( 13. mV - V_m) / ( exp( ( 13. mV - V_m) / 4. mV ) - 1. ) inline test74 1/ms = 0.28/(ms* mV ) * ( V_m - 40. mV ) / ( exp( ( V_m - 40. mV ) / 5. mV ) - 1. ) inline test75 1/ms = 0.128/ms * exp( ( 17. mV - V_m) / 18. mV ) inline test76 1/ms = ( 4. / ( 1. + exp( ( 40. mV - V_m ) / 5. mV) ) ) / ms - test77 real = alpha_m_init / ( alpha_m_init + beta_m_init ) - test78 real = alpha_h_init / ( alpha_h_init + beta_h_init ) - test78 real = alpha_n_init / ( alpha_n_init + beta_n_init ) + inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * ( V_m - E_Na ) inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) - inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_inh ) V_m' =( -I_Na - I_K - I_L - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m + # channel dynamics inline V_rel mV = V_m - V_T inline alpha_n 1/ms = 0.032/(ms* mV ) * ( 15. mV - V_rel) / ( exp( ( 15. mV - V_rel) / 5. mV ) - 1. ) @@ -142,46 +251,29 @@ neuron ExpressionCollection: Act_m' = ( alpha_m - ( alpha_m + beta_m ) * Act_m ) Act_h' = ( alpha_h - ( alpha_h + beta_h ) * Act_h ) Inact_n' = ( alpha_n - ( alpha_n + beta_n ) * Inact_n ) + # synapses: exponential conductance g_ex' = -g_ex / tau_syn_ex g_in' = -g_in / tau_syn_in - g_Na nS = 20000.0nS # Threshold Potential in mV - g_K nS = 6000.0nS # K Conductance - g_L nS = 10nS # Leak Conductance - C_m pF = 200.0pF # Membrane Capacitance in pF - E_Na mV = 50mV # Reversal potentials - E_K mV = -90.mV # Potassium reversal potential - E_L mV = -60.mV # Leak reversal Potential (aka resting potential) in mV - V_T mV = -63.0mV # Voltage offset that controls dynamics. For default - # parameters, V_T = -63mV results in a threshold around -50mV. - tau_syn_ex ms = 5.0ms # Synaptic Time Constant Excitatory Synapse in ms - tau_syn_in ms = 10.0ms # Synaptic Time Constant for Inhibitory Synapse in ms - I_e pA = 0pA # Constant Current in pA - E_ex mV = 0.0 mV # Excitatory synaptic reversal potential - E_in mV = -80.0mV # Inhibitory synaptic reversal potential - RefractoryCounts integer = 20 - g_ex += spikeExc * nS - g_in += spikeInh * nS test79 = V_m > V_T + 30mV and U_old > V_m - V_m mV = E_L # Membrane potential - g_in nS = 0nS # Inhibitory synaptic conductance - g_ex nS = 0nS # Excitatory synaptic conductance inline alpha_n_init 1/ms = 0.032/(ms* mV ) * ( 15. mV - V_m) / ( exp( ( 15. mV - V_m) / 5. mV ) - 1. ) inline beta_n_init 1/ms = 0.5 /ms * exp( ( 10. mV - V_m ) / 40. mV ) inline alpha_m_init 1/ms = 0.32/(ms* mV ) * ( 13. mV - V_m) / ( exp( ( 13. mV - V_m) / 4. mV ) - 1. ) inline beta_m_init 1/ms = 0.28/(ms* mV ) * ( V_m - 40. mV ) / ( exp( ( V_m - 40. mV ) / 5. mV ) - 1. ) inline alpha_h_init 1/ms = 0.128/ms * exp( ( 17. mV - V_m) / 18. mV ) inline beta_h_init 1/ms = ( 4. / ( 1. + exp( ( 40. mV - V_m ) / 5. mV) ) ) / ms - Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) - Act_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) - Inact_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) - r integer # counts number of tick during the refractory period + Act_m = alpha_m_init / ( alpha_m_init + beta_m_init ) + Act_h = alpha_h_init / ( alpha_h_init + beta_h_init ) + Inact_n = alpha_n_init / ( alpha_n_init + beta_n_init ) + + # synapses: exponential conductance inline I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * ( V_m - E_Na ) inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) - inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_ex ) - inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_in ) + inline I_syn_exc pA = convolve(g_ex, spikeExc) * ( V_m - E_exc ) + inline I_syn_inh pA = convolve(g_in, spikeInh) * ( V_m - E_inh ) V_m' =( -I_Na - I_K - I_L - I_syn_exc - I_syn_inh + I_e + I_stim ) / C_m + # channel dynamics inline V_rel mV = V_m - V_T inline alpha_n 1/ms = 0.032/(ms* mV ) * ( 15. mV - V_rel) / ( exp( ( 15. mV - V_rel) / 5. mV ) - 1. ) @@ -193,34 +285,7 @@ neuron ExpressionCollection: Act_m' = ( alpha_m - ( alpha_m + beta_m ) * Act_m ) Act_h' = ( alpha_h - ( alpha_h + beta_h ) * Act_h ) Inact_n' = ( alpha_n - ( alpha_n + beta_n ) * Inact_n ) - # synapses: exponential conductance - g_ex' = -g_ex / tau_syn_ex - g_in' = -g_in / tau_syn_in - g_Na nS = 20000.0nS # Threshold Potential in mV - g_K nS = 6000.0nS # K Conductance - g_L nS = 10nS # Leak Conductance - C_m pF = 200.0pF # Membrane Capacitance in pF - E_Na mV = 50mV # Reversal potentials - E_K mV = -90.mV # Potassium reversal potential - E_L mV = -60.mV # Leak reversal Potential (aka resting potential) in mV - V_T mV = -63.0mV # Voltage offset that controls dynamics. For default - # parameters, V_T = -63mV results in a threshold around -50mV. - tau_syn_ex ms = 5.0ms # Synaptic Time Constant Excitatory Synapse in ms - tau_syn_in ms = 10.0ms # Synaptic Time Constant for Inhibitory Synapse in ms - I_e pA = 0pA # Constant Current in pA - E_ex mV = 0.0 mV # Excitatory synaptic reversal potential - E_in mV = -80.0mV # Inhibitory synaptic reversal potential - V_m mV = -65. mV # Membrane potential - inline alpha_n_init real = ( 0.01 * ( V_m / mV + 55. ) ) / ( 1. - exp( -( V_m / mV + 55. ) / 10. ) ) - inline beta_n_init real = 0.125 * exp( -( V_m / mV + 65. ) / 80. ) - inline alpha_m_init real = ( 0.1 * ( V_m / mV + 40. ) ) / ( 1. - exp( -( V_m / mV + 40. ) / 10. ) ) - inline beta_m_init real = 4. * exp( -( V_m / mV + 65. ) / 18. ) - inline alpha_h_init real = 0.07 * exp( -( V_m / mV + 65. ) / 20. ) - inline beta_h_init real = 1. / ( 1. + exp( -( V_m / mV + 35. ) / 10. ) ) - Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m - Act_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) # Activation variable h - Inact_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) # Inactivation variable n - r integer # number of steps in the current refractory phase + # synapses: alpha functions I_syn_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in) I_syn_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex) @@ -230,54 +295,31 @@ neuron ExpressionCollection: inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) V_m' =( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_inh + I_syn_exc ) / C_m + # Inact_n inline alpha_n real = ( 0.01 * ( V_m / mV + 55. ) ) / ( 1. - exp( -( V_m / mV + 55. ) / 10. ) ) inline beta_n real = 0.125 * exp( -( V_m / mV + 65. ) / 80. ) Inact_n' = ( alpha_n * ( 1 - Inact_n ) - beta_n * Inact_n ) / ms # n-variable + # Act_m inline alpha_m real = ( 0.1 * ( V_m / mV + 40. ) ) / ( 1. - exp( -( V_m / mV + 40. ) / 10. ) ) inline beta_m real = 4. * exp( -( V_m / mV + 65. ) / 18. ) Act_m' = ( alpha_m * ( 1 - Act_m ) - beta_m * Act_m ) / ms # m-variable + # Act_h' inline alpha_h real = 0.07 * exp( -( V_m / mV + 65. ) / 20. ) inline beta_h real = 1. / ( 1. + exp( -( V_m / mV + 35. ) / 10. ) ) Act_h' = ( alpha_h * ( 1 - Act_h ) - beta_h * Act_h ) / ms # h-variable - t_ref ms = 2.0 ms # Refractory period - g_Na nS = 12000.0nS # Sodium peak conductance - g_K nS = 3600.0nS # Potassium peak conductance - g_L nS = 30nS # Leak conductance - C_m pF = 100.0pF # Membrane Capacitance - E_Na mV = 50mV # Sodium reversal potential - E_K mV = -77.mV # Potassium reversal potentia - E_L mV = -54.402mV # Leak reversal Potential (aka resting potential) in mV - tau_syn_ex ms = 0.2ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 2.0ms # Rise time of the inhibitory synaptic alpha function - I_e pA = 0pA # Constant Current in pA - RefractoryCounts integer = steps(t_ref) - U_old mV = V_m - integrate_odes() - # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... - if r > 0: # is refractory? - r -= 1 - elif V_m > 0 mV and U_old > V_m: # threshold && maximum - r = RefractoryCounts - emit_spike() - end - V_m mV = -65. mV # Membrane potential - I_syn_ex pA # inputs from the exc spikes - I_syn_ex' pA/ms # inputs from the exc spikes - I_syn_in pA # inputs from the inh spikes - I_syn_in' pA/ms # inputs from the inh spikes inline alpha_n_init real = ( 0.01 * ( V_m / mV + 55. ) ) / ( 1. - exp( -( V_m / mV + 55. ) / 10. ) ) inline beta_n_init real = 0.125 * exp( -( V_m / mV + 65. ) / 80. ) inline alpha_m_init real = ( 0.1 * ( V_m / mV + 40. ) ) / ( 1. - exp( -( V_m / mV + 40. ) / 10. ) ) inline beta_m_init real = 4. * exp( -( V_m / mV + 65. ) / 18. ) inline alpha_h_init real = 0.07 * exp( -( V_m / mV + 65. ) / 20. ) inline beta_h_init real = 1. / ( 1. + exp( -( V_m / mV + 35. ) / 10. ) ) - Act_m real = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m - Act_h real = alpha_h_init / ( alpha_h_init + beta_h_init ) # Activation variable h - Inact_n real = alpha_n_init / ( alpha_n_init + beta_n_init ) # Inactivation variable n - r integer # number of steps in the current refractory phase + Act_m = alpha_m_init / ( alpha_m_init + beta_m_init ) # Activation variable m + Act_h = alpha_h_init / ( alpha_h_init + beta_h_init ) # Activation variable h + Inact_n = alpha_n_init / ( alpha_n_init + beta_n_init ) # Inactivation variable n + # synapses: alpha functions I_syn_in' = I_syn_in' I_syn_in'' = (-2/tau_syn_in) * I_syn_in'-(1/tau_syn_in**2) * I_syn_in @@ -290,76 +332,69 @@ neuron ExpressionCollection: inline I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) inline I_L pA = g_L * ( V_m - E_L ) V_m' =( -( I_Na + I_K + I_L ) + I_e + I_stim + I_syn_inh + I_syn_exc ) / C_m + # Inact_n inline alpha_n real = ( 0.01 * ( V_m / mV + 55. ) ) / ( 1. - exp( -( V_m / mV + 55. ) / 10. ) ) inline beta_n real = 0.125 * exp( -( V_m / mV + 65. ) / 80. ) Inact_n' = ( alpha_n * ( 1 - Inact_n ) - beta_n * Inact_n ) / ms # n-variable + # Act_m inline alpha_m real = ( 0.1 * ( V_m / mV + 40. ) ) / ( 1. - exp( -( V_m / mV + 40. ) / 10. ) ) inline beta_m real = 4. * exp( -( V_m / mV + 65. ) / 18. ) Act_m' = ( alpha_m * ( 1 - Act_m ) - beta_m * Act_m ) / ms # m-variable + # Act_h' inline alpha_h real = 0.07 * exp( -( V_m / mV + 65. ) / 20. ) inline beta_h real = 1. / ( 1. + exp( -( V_m / mV + 35. ) / 10. ) ) Act_h' = ( alpha_h * ( 1 - Act_h ) - beta_h * Act_h ) / ms # h-variable - t_ref ms = 2.0 ms # Refractory period - g_Na nS = 12000.0nS # Sodium peak conductance - g_K nS = 3600.0nS # Potassium peak conductance - g_L nS = 30nS # Leak conductance - C_m pF = 100.0pF # Membrane Capacitance - E_Na mV = 50mV # Sodium reversal potential - E_K mV = -77.mV # Potassium reversal potentia - E_L mV = -54.402mV # Leak reversal Potential (aka resting potential) in mV - tau_syn_ex ms = 0.2ms # Rise time of the excitatory synaptic alpha function i - tau_syn_in ms = 2.0ms # Rise time of the inhibitory synaptic alpha function - I_e pA = 0pA # Constant Current in pA + # Impulse to add to DG_EXC on spike arrival to evoke unit-amplitude # conductance excursion. - PSConInit_E pA/ms = pA * e / tau_syn_ex + PSConInit_E = pA * e / tau_syn_ex + # Impulse to add to DG_INH on spike arrival to evoke unit-amplitude # conductance excursion. - PSConInit_I pA/ms = pA * e / tau_syn_in - RefractoryCounts integer = steps(t_ref) - U_old mV = V_m - integrate_odes() + PSConInit_I = pA * e / tau_syn_in + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... g = r > 0 - r -= 1 p = V_m > 0 mV and U_old > V_m # threshold && maximum r = RefractoryCounts u = emit_spike() - I_syn_ex' += spikeExc * PSConInit_E - I_syn_in' += spikeInh * PSConInit_I + I_syn_ex' = spikeExc * PSConInit_E + I_syn_in' = spikeInh * PSConInit_I + ######################## ##ht_neuron_nestml###### ######################## - V_m mV = ( g_NaL * E_Na + g_KL * E_K ) / ( g_NaL + g_KL ) # membrane potential - Theta mV = Theta_eq # Threshold - g_AMPA, g_NMDA, g_GABAA, g_GABAB, IKNa_D, IT_m, IT_h, Ih_m nS - g_AMPA', g_NMDA', g_GABAA', g_GABAB' nS/ms - r_potassium integer - g_spike boolean = false + V_m = ( g_NaL * E_Na + g_KL * E_K ) / ( g_NaL + g_KL ) # membrane potential inline I_syn_ampa pA = -g_AMPA * ( V_m - AMPA_E_rev ) inline I_syn_nmda pA = -g_NMDA * ( V_m - NMDA_E_rev ) / ( 1 + exp( ( NMDA_Vact - V_m ) / NMDA_Sact ) ) inline I_syn_gaba_a pA = -g_GABAA * ( V_m - GABA_A_E_rev ) inline I_syn_gaba_b pA = -g_GABAB * ( V_m - GABA_B_E_rev ) inline I_syn pA = I_syn_ampa + I_syn_nmda + I_syn_gaba_a + I_syn_gaba_b + # I_Na(p), m_inf^3 according to Compte et al, J Neurophysiol 2003 89:2707 inline INaP_thresh mV = -55.7 pA inline INaP_slope mV = 7.7 pA inline m_inf_NaP real = 1.0 / ( 1.0 + exp( -( V_m - INaP_thresh ) / INaP_slope ) ) + # Persistent Na current; member only to allow recording - recordable function I_NaP pA = -NaP_g_peak * pow( m_inf_NaP, 3.0 )* ( V_m - NaP_E_rev ) + recordable inline I_NaP pA = -NaP_g_peak * pow( m_inf_NaP, 3.0 )* ( V_m - NaP_E_rev ) inline d_half real = 0.25 inline m_inf_KNa real = 1.0 / ( 1.0 + pow( d_half / IKNa_D, 3.5 ) ) + # Depol act. K current; member only to allow recording - recordable function I_KNa pA = -KNa_g_peak * m_inf_KNa * ( V_m - KNa_E_rev ) + recordable inline I_KNa pA = -KNa_g_peak * m_inf_KNa * ( V_m - KNa_E_rev ) + # Low-thresh Ca current; member only to allow recording recordable inline I_T pA = -T_g_peak * IT_m * IT_m * IT_h * ( V_m - T_E_rev ) recordable inline I_h pA = -h_g_peak * Ih_m * ( V_m - h_E_rev ) + # The spike current is only activate immediately after a spike. inline I_spike mV = (g_spike) ? -( V_m - E_K ) / Tau_spike : 0 V_m' = ( ( I_Na + I_K + I_syn + I_NaP + I_KNa + I_T + I_h + I_e + I_stim ) / Tau_m + I_spike * pA/(ms * mV) ) * s/nF + ############# # Intrinsic currents ############# @@ -367,6 +402,7 @@ neuron ExpressionCollection: inline m_inf_T real = 1.0 / ( 1.0 + exp( -( V_m / mV + 59.0 ) / 6.2 ) ) inline h_inf_T real = 1.0 / ( 1.0 + exp( ( V_m / mV + 83.0 ) / 4 ) ) inline tau_m_h real = 1.0 / ( exp( -14.59 - 0.086 * V_m / mV ) + exp( -1.87 + 0.0701 * V_m / mV ) ) + # I_KNa inline D_influx_peak real = 0.025 inline tau_D real = 1250.0 # yes, 1.25s @@ -376,6 +412,7 @@ neuron ExpressionCollection: inline I_Na pA = -g_NaL * ( V_m - E_Na ) inline I_K pA = -g_KL * ( V_m - E_K ) Theta' = -( Theta - Theta_eq ) / Tau_theta + # equation modified from y[](1-D_eq) to (y[]-D_eq), since we'd not # be converging to equilibrium otherwise IKNa_D' = ( D_influx_peak * D_influx * nS - ( IKNa_D - KNa_D_EQ / mV ) / tau_D ) / ms @@ -386,6 +423,7 @@ neuron ExpressionCollection: IT_m' = ( m_inf_T * nS - IT_m ) / tau_m_T / ms IT_h' = ( h_inf_T * nS - IT_h ) / tau_h_T / ms Ih_m' = ( m_inf_h * nS - Ih_m ) / tau_m_h / ms + ############# # Synapses ############# @@ -397,59 +435,21 @@ neuron ExpressionCollection: g_GABAA' = g_GABAA' - g_GABAA / GABA_A_Tau_2 g_GABAB'' = -g_GABAB' / GABA_B_Tau_1 g_GABAB' = g_GABAB' - g_GABAB /GABA_B_Tau_2 - E_Na mV = 30.0mV - E_K mV = -90.0mV - g_NaL nS = 0.2nS - g_KL nS = 1.0nS # 1.0 - 1.85 - Tau_m ms = 16.0ms # membrane time constant applying to all currents but repolarizing K-current (see [1, p 1677]) - Theta_eq mV = -51.0mV # equilibrium value - Tau_theta ms = 2.0ms # time constant - Tau_spike ms = 1.75ms # membrane time constant applying to repolarizing K-current - t_spike ms = 2.0ms # duration of re-polarizing potassium current - # Parameters for synapse of type AMPA, GABA_A, GABA_B and NMDA - AMPA_g_peak nS = 0.1nS # peak conductance - AMPA_E_rev mV = 0.0mV # reversal potential - AMPA_Tau_1 ms = 0.5ms # rise time - AMPA_Tau_2 ms = 2.4ms # decay time, Tau_1 < Tau_2 - NMDA_g_peak nS = 0.075nS # peak conductance - NMDA_Tau_1 ms = 4.0ms # rise time - NMDA_Tau_2 ms = 40.0ms # decay time, Tau_1 < Tau_2 - NMDA_E_rev mV = 0.0mV # reversal potential - NMDA_Vact mV = -58.0mV # inactive for V << Vact, inflection of sigmoid - NMDA_Sact mV = 2.5mV # scale of inactivation - GABA_A_g_peak nS = 0.33nS # peak conductance - GABA_A_Tau_1 ms = 1.0ms # rise time - GABA_A_Tau_2 ms = 7.0ms # decay time, Tau_1 < Tau_2 - GABA_A_E_rev mV = -70.0mV # reversal potential - GABA_B_g_peak nS = 0.0132nS # peak conductance - GABA_B_Tau_1 ms = 60.0ms # rise time - GABA_B_Tau_2 ms = 200.0ms # decay time, Tau_1 < Tau_2 - GABA_B_E_rev mV = -90.0mV # reversal potential for intrinsic current - # parameters for intrinsic currents - NaP_g_peak nS = 1.0nS # peak conductance for intrinsic current - NaP_E_rev mV = 30.0mV # reversal potential for intrinsic current - KNa_g_peak nS = 1.0nS # peak conductance for intrinsic current - KNa_E_rev mV = -90.0mV # reversal potential for intrinsic current - T_g_peak nS = 1.0nS # peak conductance for intrinsic current - T_E_rev mV = 0.0mV # reversal potential for intrinsic current - h_g_peak nS = 1.0nS # peak conductance for intrinsic current - h_E_rev mV = -40.0mV # reversal potential for intrinsic current - KNa_D_EQ pA = 0.001pA - AMPAInitialValue real = compute_synapse_constant( AMPA_Tau_1, AMPA_Tau_2, AMPA_g_peak ) - NMDAInitialValue real = compute_synapse_constant( NMDA_Tau_1, NMDA_Tau_2, NMDA_g_peak ) - GABA_AInitialValue real = compute_synapse_constant( GABA_A_Tau_1, GABA_A_Tau_2, GABA_A_g_peak ) - GABA_BInitialValue real = compute_synapse_constant( GABA_B_Tau_1, GABA_B_Tau_2, GABA_B_g_peak ) - PotassiumRefractoryCounts integer = steps(t_spike) - integrate_odes() + + AMPAInitialValue = compute_synapse_constant( AMPA_Tau_1, AMPA_Tau_2, AMPA_g_peak ) + NMDAInitialValue = compute_synapse_constant( NMDA_Tau_1, NMDA_Tau_2, NMDA_g_peak ) + GABA_AInitialValue = compute_synapse_constant( GABA_A_Tau_1, GABA_A_Tau_2, GABA_A_g_peak ) + GABA_BInitialValue = compute_synapse_constant( GABA_B_Tau_1, GABA_B_Tau_2, GABA_B_g_peak ) + # Deactivate potassium current after spike time have expired test = (r_potassium > 0) and (r_potassium-1 == 0) g_spike = false # Deactivate potassium current. - r_potassium -= 1 - g_AMPA' += AMPAInitialValue * AMPA * nS/ms - g_NMDA' += NMDAInitialValue * NMDA * nS/ms - g_GABAA' += GABA_AInitialValue * GABA_A * nS/ms - g_GABAB' += GABA_BInitialValue * GABA_B * nS/ms + g_AMPA' = AMPAInitialValue * AMPA * nS/ms + g_NMDA' = NMDAInitialValue * NMDA * nS/ms + g_GABAA' = GABA_AInitialValue * GABA_A * nS/ms + g_GABAB' = GABA_BInitialValue * GABA_B * nS/ms lop = (not g_spike) and V_m >= Theta + # Set V and Theta to the sodium reversal potential. V_m = E_Na Theta = E_Na @@ -457,17 +457,39 @@ neuron ExpressionCollection: g_spike = true g_spike = false r_potassium = PotassiumRefractoryCounts - emit_spike() - exact_integration_adjustment real = ( ( 1 / Tau_2 ) - ( 1 / Tau_1 ) ) * ms - t_peak real = ( Tau_2 * Tau_1 ) * log10( Tau_2 / Tau_1 ) / ( Tau_2 - Tau_1 ) / ms - t_peak123 real = ( Tau_2 * Tau_1 ) * ln( Tau_2 / Tau_1 ) / ( Tau_2 - Tau_1 ) / ms - normalisation_factor real = 1 / ( exp( -t_peak / Tau_1 ) - exp( -t_peak / Tau_2 ) ) + + exact_integration_adjustment = ( ( 1 / Tau_2 ) - ( 1 / Tau_1 ) ) * ms + t_peak = ( Tau_2 * Tau_1 ) * log10( Tau_2 / Tau_1 ) / ( Tau_2 - Tau_1 ) / ms + t_peak123 = ( Tau_2 * Tau_1 ) * ln( Tau_2 / Tau_1 ) / ( Tau_2 - Tau_1 ) / ms + normalisation_factor = 1 / ( exp( -t_peak / Tau_1 ) - exp( -t_peak / Tau_2 ) ) test = g_peak * normalisation_factor * exact_integration_adjustment - # clip and hyperbolic functions - Vclip mV = clip(V_m, -120 mV, 0 mV) - testsinh real = sinh(0.) - testcosh real = cosh(0.) - testtanh real = tanh(0.) + end + + update: + test56 += b + test67 += spikeExc * nS + test68 += spikeInh * nS + + g_ex += spikeExc * nS + g_in += spikeInh * nS + + r -= 1 + r_potassium -= 1 + + test72 integer = (r - r_potassium) % r + + test77 real = alpha_m_init / ( alpha_m_init + beta_m_init ) + test78 real = alpha_h_init / ( alpha_h_init + beta_h_init ) + test79 real = alpha_n_init / ( alpha_n_init + beta_n_init ) + + integrate_odes() + # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... + if r > 0: # is refractory? + r -= 1 + elif V_m > 0 mV and U_old > V_m: # threshold && maximum + r = RefractoryCounts + test57 = emit_spike() + end end end diff --git a/tests/resources/ExpressionTypeTest.nestml b/tests/resources/ExpressionTypeTest.nestml index 230ef8abb..c34d9d98b 100644 --- a/tests/resources/ExpressionTypeTest.nestml +++ b/tests/resources/ExpressionTypeTest.nestml @@ -1,25 +1,12 @@ -/** - * - * ExpressionTypeTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * This test is used to test the resolution of symbols. +""" +ExpressionTypeTest.nestml +######################### + + +Description ++++++++++++ + +This test is used to test the resolution of symbols. expression : leftParentheses='(' term=expression rightParentheses=')' | left=expression powOp='**' right=expression | unaryOperator term=expression @@ -31,22 +18,42 @@ | left=expression logicalOperator right=expression | condition=expression '?' ifTrue=expression ':' ifNot=expression | simpleExpression -*/ +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron expressionType_test: state: - time s - resist Ohm - amps A - volts V - charge C - mass kg - distance m - force N - testint integer - timesquared s**2 - velocity m/s + time s = 2 s + resist Ohm = 1 Ohm + amps A = 0.1 A + volts V = -0.5 V + charge C = 0.03 C + mass kg = 0.15 kg + distance m = 0.33 m + force N = 1.5 N + testint integer = 8 + testint2 integer = 3 + timesquared s**2 = 1.44 s**2 + velocity m/s = 23.5 m/s end function foo(_mass kg, _dist m, _time s) N : @@ -55,6 +62,7 @@ neuron expressionType_test: update: #time = (charge/amps) + testint = testint % testint2 testint = 2 timesquared = time**2 velocity = distance/time @@ -66,6 +74,5 @@ neuron expressionType_test: force = foo(mass,distance,time) force = 1 kg * distance/(time**2) force = kg*m/(s**2) - force = volts*amps # this is expected to yield an error end end diff --git a/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml b/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml index 95aa93724..405b31495 100644 --- a/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml @@ -1,25 +1,28 @@ -/** - * - * FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml +################################################################# + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: function foo(bar mV)V: return bar diff --git a/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml b/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml index 56be03cf1..fa606776d 100644 --- a/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml @@ -1,25 +1,28 @@ -/** - * - * FunctionCallWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +FunctionCallWithDifferentButCompatibleUnits.nestml +################################################## + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: function foo(bar mV): return diff --git a/tests/resources/FunctionParameterTemplatingTest.nestml b/tests/resources/FunctionParameterTemplatingTest.nestml index 8f936ca51..7911087bf 100644 --- a/tests/resources/FunctionParameterTemplatingTest.nestml +++ b/tests/resources/FunctionParameterTemplatingTest.nestml @@ -1,31 +1,38 @@ -/** - * - * FunctionParameterTemplatingTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * This test is used to test the correct derivation of types when functions use templated type parameters. -*/ +""" +FunctionParameterTemplatingTest.nestml +###################################### + +Description ++++++++++++ + +This test is used to test the correct derivation of types when functions use templated type parameters. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron templated_function_parameters_type_test: state: - force N - foo real + force N = 1.5 N + foo real = 10 end update: diff --git a/tests/resources/MagnitudeCompatibilityTest.nestml b/tests/resources/MagnitudeCompatibilityTest.nestml index 368cbc597..2185ac8aa 100644 --- a/tests/resources/MagnitudeCompatibilityTest.nestml +++ b/tests/resources/MagnitudeCompatibilityTest.nestml @@ -1,33 +1,40 @@ -/** - * - * ExpressionTypeTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * Test the implicit conversions between units of matching base types. - */ +""" +ExpressionTypeTest.nestml +######################### + +Description ++++++++++++ + +Test the implicit conversions between units of matching base types. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron expressionType_test: state: - volts V - milliVolts mV - bigComplexUnit V/C - smallComplelxUnit mV/C + volts V = 2 V + milliVolts mV = -70 mV + bigComplexUnit V/C = -0.1 V/C + smallComplelxUnit mV/C = -22 mV/C end update: diff --git a/tests/resources/NestMLPrinterTest.nestml b/tests/resources/NestMLPrinterTest.nestml index 33625259f..ea7794813 100644 --- a/tests/resources/NestMLPrinterTest.nestml +++ b/tests/resources/NestMLPrinterTest.nestml @@ -1,118 +1,118 @@ -/** - * - * NestMLPrinterTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * Test whether the NestML printer and beautifier works as intended. - */ - /*neuron pre*/ +""" +NestMLPrinterTest.nestml +######################## + + +Description ++++++++++++ + +Test whether the NestML printer and beautifier works as intended. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +# neuron pre neuron aeif_cond_alpha_implicit: - /*state pre*/ + # state pre state: # state in - /*state var decl pre*/ + # state var decl pre r integer # state var decl comment - /*state var decl post*/ - end - /*state post*/ - - /*initial val pre*/ - initial_values: # initial val in - /*init val pre*/ - V_m mV = 10mV # init val in - /*init val post*/ + # state var decl post end - /*initial val post*/ + # state post - /*eq pre*/ + # eq pre equations: # eq in - /*inline pre*/ + # inline pre inline V_bounded mV = min(0,1) # inline in - /*inline post*/ + # inline post - /*kernel pre*/ + # kernel pre kernel V_M'' = 1 # kernel in - /*kernel post*/ + # kernel post - /*ode pre*/ + # ode pre V_m'= 1 # ode in - /*ode post*/ + # ode post end - /*eq post*/ + # eq post - /*parameters pre*/ + # parameters pre parameters: # parameters in - /*par decl pre*/ + # par decl pre C_m pF = 281.0pF # par decl in - /*par decl post*/ + # par decl post end - /*parameters post*/ + # parameters post - /*int pre*/ + # int pre internals: # int in - /*int decl pre*/ + # int decl pre RefractoryCounts integer = steps(1) # int decl in - /*int decl post*/ + # int decl post end - /*int post*/ + # int post - /*input pre*/ + # input pre input: - /*input decl pre*/ - spikesInh nS <-inhibitory spike # input decl in - /*input decl post*/ + # input decl pre + inh_spikes nS <- inhibitory spike # input decl in + # input decl post end - /*input post*/ + # input post - /*output pre*/ + # output pre output: spike # output in - /*output post*/ + # output post - /*update pre*/ + # update pre update: # update in - /*stmt1 pre*/ + # stmt1 pre integrate_odes() # stmt1 in - /*stmt1 post*/ + # stmt1 post - /*stmt2 pre*/ + # stmt2 pre if r > 0: # stmt2 in - /*stmt2 post*/ + # stmt2 post - /*stmt3 pre*/ + # stmt3 pre r -= 1 # stmt3 in - /*stmt3 post*/ + # stmt3 post - /*stmt4 pre*/ + # stmt4 pre elif V_m >= V_peak: # stmt4 in - /*stmt5 pre*/ + # stmt5 pre r = RefractoryCounts # stmt5 pre - /*stmt5 pre*/ + # stmt5 pre end - /*stmt2 post*/ + # stmt2 post end - /*update post*/ + # update post end -/*neuron post*/ +# neuron post diff --git a/tests/resources/ResolutionTest.nestml b/tests/resources/ResolutionTest.nestml index bdaedc8cc..669d3e08f 100644 --- a/tests/resources/ResolutionTest.nestml +++ b/tests/resources/ResolutionTest.nestml @@ -1,27 +1,34 @@ -/** - * - * BlockTest.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * This test is used to test the resolution of symbols. -*/ +""" +ResolutionTest.nestml +##################### + +Description ++++++++++++ + +This test is used to test the resolution of symbols. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron resolution_test: state: test1 integer = 10 diff --git a/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml b/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml index 755de76df..6701e9b7e 100644 --- a/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,31 @@ -/** - * - * RhsFunctionCallWithDifferentButCompatibleUnits.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * -*/ +""" +RhsFunctionCallWithDifferentButCompatibleUnits.nestml +##################################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron BlockTest: state: - lhs mV + lhs mV = 0 mV end function foo(bar mV) mV: diff --git a/tests/resources/SynapseEventSequenceTest.nestml b/tests/resources/SynapseEventSequenceTest.nestml new file mode 100644 index 000000000..928a20f60 --- /dev/null +++ b/tests/resources/SynapseEventSequenceTest.nestml @@ -0,0 +1,50 @@ +""" +SynapseEventSequenceTest.nestml +################ + + +Description ++++++++++++ + +This model is used to test the sequencing of event handlers in synapse models. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse SynapseEventSequenceTest: + state: + tr real = 1. + end + + input: + pre_spikes real <- spike + post_spikes real <- spike + end + + onReceive(pre_spikes, priority=1): + tr += 1. + end + + onReceive(post_spikes, priority=2): + tr *= 3.14159 + end + +end diff --git a/tests/resources/random_number_generators_test.nestml b/tests/resources/random_number_generators_test.nestml index f8e4f173e..f2a04e724 100644 --- a/tests/resources/random_number_generators_test.nestml +++ b/tests/resources/random_number_generators_test.nestml @@ -1,26 +1,30 @@ -/** - * - * random_number_generators_test.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . -*/ +""" +random_number_generators_test.nestml +#################################### + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron test_random: - initial_values: + state: p mV = random_normal(500 mV, 25 mV) q real = random_normal(500, 25) r real = random_uniform(0, 1) @@ -33,9 +37,9 @@ neuron test_random: end input: - ex_spikes nS <- excitatory spike - in_spikes nS <- inhibitory spike - currents pA <- current + exc_spikes nS <- excitatory spike + inh_spikes nS <- inhibitory spike + currents pA <- continuous end update: diff --git a/tests/resources/synapse_event_inv_priority_test.nestml b/tests/resources/synapse_event_inv_priority_test.nestml new file mode 100644 index 000000000..f4f98249b --- /dev/null +++ b/tests/resources/synapse_event_inv_priority_test.nestml @@ -0,0 +1,55 @@ +""" +synapse_event_inv_priority_test.nestml +###################################### + + +Description ++++++++++++ + +This model is used to test the sequencing of event handlers in synapse models. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse synapse_event_inv_priority_test: + state: + tr real = 1. + end + + parameters: + d ms = 1. ms @nest::delay + end + + input: + pre_spikes real <- spike + post_spikes real <- spike + end + + onReceive(pre_spikes, priority=2): + tr += 1. + deliver_spike(1., d) + end + + onReceive(post_spikes, priority=1): + tr *= 3.14159 + end + +end diff --git a/tests/resources/synapse_event_priority_test.nestml b/tests/resources/synapse_event_priority_test.nestml new file mode 100644 index 000000000..15f42cd69 --- /dev/null +++ b/tests/resources/synapse_event_priority_test.nestml @@ -0,0 +1,55 @@ +""" +synapse_event_priority_test +########################### + + +Description ++++++++++++ + +This model is used to test the sequencing of event handlers in synapse models. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse synapse_event_priority_test: + state: + tr real = 1. + end + + parameters: + d ms = 1. ms @nest::delay + end + + input: + pre_spikes real <- spike + post_spikes real <- spike + end + + onReceive(pre_spikes, priority=1): + tr += 1. + deliver_spike(1., d) + end + + onReceive(post_spikes, priority=2): + tr *= 3.14159 + end + +end diff --git a/tests/special_block_parser_builder_test.py b/tests/special_block_parser_builder_test.py index 0ceef8164..b978e4a1e 100644 --- a/tests/special_block_parser_builder_test.py +++ b/tests/special_block_parser_builder_test.py @@ -57,16 +57,21 @@ def test(self): os.path.join(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'BlockTest.nestml'))) lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() + # parse the file parser = PyNestMLParser(stream) - # print('done') + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + compilation_unit = parser.nestMLCompilationUnit() ast_builder_visitor = ASTBuilderVisitor(stream.tokens) ast = ast_builder_visitor.visit(compilation_unit) - # print('done') self.assertTrue(isinstance(ast, ASTNestMLCompilationUnit)) diff --git a/tests/symbol_table_builder_test.py b/tests/symbol_table_builder_test.py index acc63913c..5b0f3ee5e 100644 --- a/tests/symbol_table_builder_test.py +++ b/tests/symbol_table_builder_test.py @@ -53,16 +53,25 @@ def test(self): input_file = FileStream( os.path.join(os.path.dirname(__file__), os.path.join(os.path.join('..', 'models'), filename))) lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() + # parse the file parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + # process the comments compilation_unit = parser.nestMLCompilationUnit() + # create a new visitor and return the new AST ast_builder_visitor = ASTBuilderVisitor(stream.tokens) ast = ast_builder_visitor.visit(compilation_unit) + # update the corresponding symbol tables SymbolTable.initialize_symbol_table(ast.get_source_position()) symbol_table_visitor = ASTSymbolTableVisitor() diff --git a/tests/unit_system_test.py b/tests/unit_system_test.py index df817d2cc..96ff52d57 100644 --- a/tests/unit_system_test.py +++ b/tests/unit_system_test.py @@ -18,28 +18,39 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + import os import unittest -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.codegeneration.expressions_pretty_printer import ExpressionsPrettyPrinter -from pynestml.codegeneration.nest_printer import NestPrinter -from pynestml.codegeneration.nest_reference_converter import NESTReferenceConverter +from pynestml.codegeneration.printers.cpp_expression_printer import CppExpressionPrinter +from pynestml.codegeneration.printers.cpp_types_printer import CppTypesPrinter +from pynestml.codegeneration.printers.nest_printer import NestPrinter +from pynestml.codegeneration.printers.nestml_reference_converter import NestMLReferenceConverter from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.predefined_units import PredefinedUnits from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.model_parser import ModelParser + SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + PredefinedUnits.register_units() PredefinedTypes.register_types() PredefinedVariables.register_variables() PredefinedFunctions.register_functions() + Logger.init_logger(LoggingLevel.INFO) -printer = NestPrinter(ExpressionsPrettyPrinter(), NESTReferenceConverter()) + +types_printer = CppTypesPrinter() +reference_converter = NestMLReferenceConverter() +expression_printer = CppExpressionPrinter(reference_converter) +printer = NestPrinter(reference_converter=reference_converter, + types_printer=types_printer, + expression_printer=expression_printer) def get_first_statement_in_update_block(model): @@ -64,7 +75,7 @@ def print_rhs_of_first_assignment_in_update_block(model): def print_first_function_call_in_update_block(model): function_call = get_first_statement_in_update_block(model).small_stmt.get_function_call() - return printer.print_method_call(function_call) + return printer.print_function_call(function_call) def print_rhs_of_first_declaration_in_state_block(model): diff --git a/tests/valid/CoCoAssignmentToInlineExpression.nestml b/tests/valid/CoCoAssignmentToInlineExpression.nestml new file mode 100644 index 000000000..61c67830f --- /dev/null +++ b/tests/valid/CoCoAssignmentToInlineExpression.nestml @@ -0,0 +1,49 @@ +""" +CoCoAssignmentToInlineExpression.nestml +####################################### + + +Description ++++++++++++ + +This test is used to test the function of CoCoAllVariablesDefined. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoAssignmentToInlineExpression: + parameters: + tau_syn ms = 10 ms + end + + equations: + kernel alpha_kernel = (e / tau_syn) * t * exp(-t / tau_syn) + inline foo real = convolve(alpha_kernel, spikes_in) + end + + input: + spikes_in real <- spike + end + + update: + foo = 42. + end +end diff --git a/tests/valid/CoCoBufferWithRedundantTypes.nestml b/tests/valid/CoCoBufferWithRedundantTypes.nestml deleted file mode 100644 index 06c41493b..000000000 --- a/tests/valid/CoCoBufferWithRedundantTypes.nestml +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * CoCoBufferWithRedundantTypes.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if each buffer is defined uniquely, i.e., - * no redundant keywords are used. - * Positive case. -*/ - -neuron CoCoBufferWithRedundantTypes: - input: - spikeInh integer <- inhibitory spike # no redundant keywords used, thus correct - end -end diff --git a/tests/valid/CoCoCmFunctionExists.nestml b/tests/valid/CoCoCmFunctionExists.nestml new file mode 100644 index 000000000..26e61363b --- /dev/null +++ b/tests/valid/CoCoCmFunctionExists.nestml @@ -0,0 +1,69 @@ +""" +CoCoCmFunctionExists.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether functions expected for each +matching compartmental variable have been defined + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + + +neuron cm_model_one: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + equations: + inline Na real = m_Na**3 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmFunctionOneArg.nestml b/tests/valid/CoCoCmFunctionOneArg.nestml new file mode 100644 index 000000000..d055af5d2 --- /dev/null +++ b/tests/valid/CoCoCmFunctionOneArg.nestml @@ -0,0 +1,81 @@ +""" +CoCoCmFunctionOneArg.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether compartmental model functions receive exactly +one argument + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_two: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + h_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + function some_random_function_to_ignore(v_comp real, something_else real) real: + return 0.0 + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmFunctionReturnsReal.nestml b/tests/valid/CoCoCmFunctionReturnsReal.nestml new file mode 100644 index 000000000..f6be74b69 --- /dev/null +++ b/tests/valid/CoCoCmFunctionReturnsReal.nestml @@ -0,0 +1,81 @@ +""" +CoCoCmFunctionReturnsReal.nestml.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether functions expected for each +matching compartmental variable return type 'real' + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_three: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + h_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + function some_random_function_to_ignore(v_comp real, something_else real) real: + return 0.0 + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmVariableHasRhs.nestml b/tests/valid/CoCoCmVariableHasRhs.nestml new file mode 100644 index 000000000..3052769aa --- /dev/null +++ b/tests/valid/CoCoCmVariableHasRhs.nestml @@ -0,0 +1,68 @@ +""" +CoCoCmVariableHasRhs.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether the all variable declarations of the +compartmental model contain a right hand side expression + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_four: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + equations: + inline Na real = m_Na**3 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmVariableMultiUse.nestml b/tests/valid/CoCoCmVariableMultiUse.nestml new file mode 100644 index 000000000..c304ec563 --- /dev/null +++ b/tests/valid/CoCoCmVariableMultiUse.nestml @@ -0,0 +1,68 @@ +""" +CoCoCmVariableMultiUse.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether the inline expression that characterizes +a channel uses each variable exactly once + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_five: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + equations: + inline Na real = m_Na**3 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmVariableName.nestml b/tests/valid/CoCoCmVariableName.nestml new file mode 100644 index 000000000..38434d18b --- /dev/null +++ b/tests/valid/CoCoCmVariableName.nestml @@ -0,0 +1,81 @@ +""" +CoCoCmVariableName.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether there is at least +one gating variable in the inline expression, meaning +a variable suffixed with '_{channel_name_from_inline}' + +Positive case. + +Even though h_K is not recognized as a gating variable +m_Na is recognized, therefore there is at least one gating variable + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_six: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + h_K real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + equations: + inline Na real = m_Na**3 * h_K**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmVariablesDeclared.nestml b/tests/valid/CoCoCmVariablesDeclared.nestml new file mode 100644 index 000000000..28dbcd205 --- /dev/null +++ b/tests/valid/CoCoCmVariablesDeclared.nestml @@ -0,0 +1,77 @@ +""" +CoCoCmVariablesDeclared.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether compartmental variables used in the inline expression +are also declared in the corresponding state / parameter block + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_seven: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + + m_Na real = 0.0 + h_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + e_Na real = 50.0 + gbar_Na real = 0.0 + + end + + +end diff --git a/tests/valid/CoCoCmVcompExists.nestml b/tests/valid/CoCoCmVcompExists.nestml new file mode 100644 index 000000000..9d1a030f8 --- /dev/null +++ b/tests/valid/CoCoCmVcompExists.nestml @@ -0,0 +1,72 @@ +""" +CoCoCmVcompExists.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether, in case of a compartmental model ("NEST_COMPARTMENTAL"), +there is the required variable called v_comp defined in the state block + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron cm_model_eight_invalid: + + state: + # indicate that we have a compartmental model + # by declaring an unused variable with the name "v_comp" + v_comp real = 0.0 + m_Na real = 0.0 + + end + + #sodium + function m_inf_Na(v_comp real) real: + return (0.182*v_comp + 6.3723659999999995)/((1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))*((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp)))) + end + + function tau_m_Na(v_comp real) real: + return 0.3115264797507788/((-0.124*v_comp - 4.3416119999999996)/(1.0 - 48.927192870146527*exp(0.1111111111111111*v_comp)) + (0.182*v_comp + 6.3723659999999995)/(1.0 - 0.020438532058318047*exp(-0.1111111111111111*v_comp))) + end + + function h_inf_Na(v_comp real) real: + return 1.0/(exp(0.16129032258064516*v_comp + 10.483870967741936) + 1.0) + end + + function tau_h_Na(v_comp real) real: + return 0.3115264797507788/((-0.0091000000000000004*v_comp - 0.68261830000000012)/(1.0 - 3277527.8765015295*exp(0.20000000000000001*v_comp)) + (0.024*v_comp + 1.200312)/(1.0 - 4.5282043263959816e-5*exp(-0.20000000000000001*v_comp))) + end + + equations: + inline Na real = m_Na**3 * h_Na**1 + + end + + parameters: + + end + +end diff --git a/tests/valid/CoCoContinuousInputPortQualifierSpecified.nestml b/tests/valid/CoCoContinuousInputPortQualifierSpecified.nestml new file mode 100644 index 000000000..f826db54e --- /dev/null +++ b/tests/valid/CoCoContinuousInputPortQualifierSpecified.nestml @@ -0,0 +1,36 @@ +""" +CoCoContinuousInputPortQualifierSpecified.nestml +################################################ + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if continuous time input ports are not specified by qualifiers. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoContinuousInputPortQualifierSpecified: + input: + currents pA <- continuous # no qualifier specified for current port, thus correct + end +end diff --git a/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml b/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml index b3976a041..585aaf270 100644 --- a/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml +++ b/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml @@ -1,37 +1,43 @@ -/** - * - * CoCoConvolveNotCorrectlyParametrized.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly - * provided with a initial_block variable and a spike buffer. - * Positive case. -*/ +""" +CoCoConvolveNotCorrectlyParametrized.nestml +########################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoConvolveNotCorrectlyParametrized: parameters: tau ms = 20 ms end - initial_values: + state: G real = 1. end diff --git a/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml b/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml index 640bcff0a..c7168f33e 100644 --- a/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml +++ b/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml @@ -1,37 +1,47 @@ -/** - * - * CoCoConvolveNotCorrectlyProvided.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly - * provided with a initial_block variable and a spike buffer. - * Positive case. -*/ +""" +CoCoConvolveNotCorrectlyProvided.nestml +####################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoConvolveNotCorrectlyProvided: equations: kernel test = 10 - inline testB pA = convolve(test, spikeExc) # convolve provided with a kernel and a buffer, thus correct + inline testB pA = convolve(test, spikeExc) # convolve provided with a kernel and a spike input port, thus correct end input: - spikeExc integer <- excitatory spike + spikeExc integer <- excitatory spike + end + + update: + integrate_odes() end end diff --git a/tests/valid/CoCoCurrentBufferQualifierSpecified.nestml b/tests/valid/CoCoCurrentBufferQualifierSpecified.nestml deleted file mode 100644 index 780f1e59f..000000000 --- a/tests/valid/CoCoCurrentBufferQualifierSpecified.nestml +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * CoCoCurrentBufferQualifierSpecified.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if current buffers are not specified by - * keywords. - * -*/ - -neuron CoCoCurrentBufferQualifierSpecified: - input: - currents pA <- current # no qualifier specified for current port, thus correct - end -end diff --git a/tests/valid/CoCoEachBlockUnique.nestml b/tests/valid/CoCoEachBlockUnique.nestml index 8ce1d8879..e55aa5339 100644 --- a/tests/valid/CoCoEachBlockUnique.nestml +++ b/tests/valid/CoCoEachBlockUnique.nestml @@ -1,29 +1,34 @@ -/** - * - * CoCoEachBlockUnique.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. - * Positive Case. -*/ +""" +CoCoEachBlockUnique.nestml +########################## +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. + +Positive Case. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoEachBlockUnique: state:# each block is unique test1 integer = 0 # no variable is redeclared in the same scope, thus everything correct diff --git a/tests/valid/CoCoElementInSameLine.nestml b/tests/valid/CoCoElementInSameLine.nestml index 067515de0..37d2feec5 100644 --- a/tests/valid/CoCoElementInSameLine.nestml +++ b/tests/valid/CoCoElementInSameLine.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoElementInSameLine.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * recursive definition is detected. - * Positive case. -*/ +""" +CoCoElementInSameLine.nestml +############################ + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +recursive definition is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoElementInSameLine: state: test1 integer = 1 # no recursive definition occurred, thus everthing correct diff --git a/tests/valid/CoCoElementNotDefined.nestml b/tests/valid/CoCoElementNotDefined.nestml index b04f68664..0f9b51d27 100644 --- a/tests/valid/CoCoElementNotDefined.nestml +++ b/tests/valid/CoCoElementNotDefined.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoElementNotDefined.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * definition with not defined references is detected. - * Positive case. -*/ +""" +CoCoElementNotDefined.nestml +############################ + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +definition with not defined references is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoElementNotDefined: state: test integer = 0 diff --git a/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml b/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml index d82945196..8aa18bed8 100644 --- a/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml +++ b/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml @@ -1,30 +1,36 @@ -/** - * - * CoCoFunctionCallNotConsistentWrongArgNumber.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if current buffers are not specified by - * keywords. - * Positive case. -*/ +""" +CoCoFunctionCallNotConsistentWrongArgNumber.nestml +################################################## + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if function calls have the right number of arguments. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoFunctionCallNotConsistentWrongArgNumber: state: test integer = max(1,2) # max is provided with correct number of arguments and types, thus everything is correct diff --git a/tests/valid/CoCoFunctionNotUnique.nestml b/tests/valid/CoCoFunctionNotUnique.nestml index d558ec50d..40075e38c 100644 --- a/tests/valid/CoCoFunctionNotUnique.nestml +++ b/tests/valid/CoCoFunctionNotUnique.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoFunctionNotUnique.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions - * is detected. - * Positive Case. -*/ +""" +CoCoFunctionNotUnique.nestml +############################ + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions +is detected. + +Positive Case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoFunctionNotUnique: function deltaNew(Tau_a ms,Tau_b ms) real: # deltaNew is not predefined, thus everything is correct test real = 1 diff --git a/tests/valid/CoCoFunctionRedeclared.nestml b/tests/valid/CoCoFunctionRedeclared.nestml index d5aecb1eb..40a66aa46 100644 --- a/tests/valid/CoCoFunctionRedeclared.nestml +++ b/tests/valid/CoCoFunctionRedeclared.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoFunctionRedeclared.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. - * Here, if redeclaration of functions has been detected. - * Positive case. -*/ +""" +CoCoFunctionRedeclared.nestml +############################# + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. +Here, if redeclaration of functions has been detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoFunctionRedeclared: function maxGt(arg1 integer,arg2 integer) integer: # both functions have different names, thus everything is if arg1>arg2: diff --git a/tests/valid/CoCoIllegalExpression.nestml b/tests/valid/CoCoIllegalExpression.nestml index ce1a23117..8c7190e6b 100644 --- a/tests/valid/CoCoIllegalExpression.nestml +++ b/tests/valid/CoCoIllegalExpression.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoIllegalExpression.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. - * type(lhs)!= type(rhs) are detected. - * Positive case. -*/ +""" +CoCoIllegalExpression.nestml +############################ + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. +type(lhs)!= type(rhs) are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoIllegalExpression: state: test boolean = True diff --git a/tests/valid/CoCoIncorrectReturnStatement.nestml b/tests/valid/CoCoIncorrectReturnStatement.nestml index d67b6786b..32b6b2a38 100644 --- a/tests/valid/CoCoIncorrectReturnStatement.nestml +++ b/tests/valid/CoCoIncorrectReturnStatement.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoIncorrectReturnStatement.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without - * a proper return statement and wrong type are detected. - * Positive case. -*/ +""" +CoCoIncorrectReturnStatement.nestml +################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without +a proper return statement and wrong type are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoIncorrectReturnStatement: function foo() mV:# correct return type is given test mV = 10mV diff --git a/tests/valid/CoCoInitValuesWithoutOde.nestml b/tests/valid/CoCoInitValuesWithoutOde.nestml index 5ff162b4a..6807d86f4 100644 --- a/tests/valid/CoCoInitValuesWithoutOde.nestml +++ b/tests/valid/CoCoInitValuesWithoutOde.nestml @@ -1,32 +1,39 @@ -/** - * - * CoCoInitValuesWithoutOde.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode - * declarations are detected. Moreover, if initial values without a right-hand side are detected. - * Positive case. -*/ +""" +CoCoInitValuesWithoutOde.nestml +############################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode +declarations are detected. Moreover, if initial values without a right-hand side are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInitValuesWithoutOde: - initial_values: + state: V_m mV = 10mV end diff --git a/tests/valid/CoCoInlineExpressionHasNoRhs.nestml b/tests/valid/CoCoInlineExpressionHasNoRhs.nestml index bbf3cb2b7..93e1d1481 100644 --- a/tests/valid/CoCoInlineExpressionHasNoRhs.nestml +++ b/tests/valid/CoCoInlineExpressionHasNoRhs.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoInlineExpressionHasNoRhs.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. - * - * Positive case. -*/ +""" +CoCoInlineExpressionHasNoRhs.nestml +################################### + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInlineExpressionHasNoRhs: equations: inline V_rest mV = 10mV # a rhs is defined, thus everything is correct diff --git a/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml b/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml index 742264272..0bd61b7eb 100644 --- a/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml +++ b/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoInlineExpressionWithSeveralLhs.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. - * - * Positive case. -*/ +""" +CoCoInlineExpressionWithSeveralLhs.nestml +######################################### + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInlineExpressionWithSeveralLhs: equations: inline V_rest mV = 10mV # only one lhs for a inline, thus everything correct diff --git a/tests/valid/CoCoInputPortWithRedundantTypes.nestml b/tests/valid/CoCoInputPortWithRedundantTypes.nestml new file mode 100644 index 000000000..080b44be7 --- /dev/null +++ b/tests/valid/CoCoInputPortWithRedundantTypes.nestml @@ -0,0 +1,38 @@ +""" +CoCoInputPortWithRedundantTypes.nestml +###################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if each input port is defined uniquely, i.e., no redundant keywords are used. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoInputPortWithRedundantTypes: + input: + spikeInh integer <- inhibitory spike # no redundant keywords used, thus correct + end +end diff --git a/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml b/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml new file mode 100644 index 000000000..06db4a933 --- /dev/null +++ b/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml @@ -0,0 +1,48 @@ +""" +CoCoIntegrateOdesCalledIfEquationsDefined.nestml +################################################ + + +Description ++++++++++++ + +This model is used to test the check that integrate_odes() is called if one or more dynamical equations are defined. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoIntegrateOdesCalledIfEquationsDefined: + state: + x real = 1. + y integer = 0 + end + + equations: + x' = -x / (10 ms) + end + + update: + y = min(x, y) + integrate_odes() + end +end diff --git a/tests/valid/CoCoInvariantNotBool.nestml b/tests/valid/CoCoInvariantNotBool.nestml index 95a8ad91d..b08efebc7 100644 --- a/tests/valid/CoCoInvariantNotBool.nestml +++ b/tests/valid/CoCoInvariantNotBool.nestml @@ -1,30 +1,37 @@ -/** - * - * CoCoInvariantNotBool.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants - * is detected and invariants are correctly constructed. - * Positive case. -*/ +""" +CoCoInvariantNotBool.nestml +########################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants +is detected and invariants are correctly constructed. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoInvariantNotBool: state: V_notBool mV = 10mV [[V_notBool > V_notBool]]# this should not be detected although on logical level incorrect diff --git a/tests/valid/CoCoKernelType.nestml b/tests/valid/CoCoKernelType.nestml index 3345b82c1..4dfb35d99 100644 --- a/tests/valid/CoCoKernelType.nestml +++ b/tests/valid/CoCoKernelType.nestml @@ -1,38 +1,44 @@ -/** - * - * CoCoKernelCorrectlyTyped.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. - * - * Here, the kernel is defined with a correct type. - * - * Positive case -*/ +""" +CoCoKernelCorrectlyTyped.nestml +############################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. + +Here, the kernel is defined with a correct type. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoKernelCorrectlyTyped: parameters: tau ms = 10 ms end - initial_values: # variable is now defined in the initial block, thus everything is correct. + state: # variable is now defined in the initial block, thus everything is correct. g real = 1 g' ms**-1 = 1 ms**-1 end diff --git a/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml b/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml index ecf446484..ab3d0072d 100644 --- a/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml +++ b/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoMultipleNeuronsWithEqualName.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name - * are detected. - * Positive case. -*/ +""" +CoCoMultipleNeuronsWithEqualName.nestml +####################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name +are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoMultipleNeuronsWithEqualName: end diff --git a/tests/valid/CoCoNestNamespaceCollision.nestml b/tests/valid/CoCoNestNamespaceCollision.nestml index e2a9b76bd..a44c77a08 100644 --- a/tests/valid/CoCoNestNamespaceCollision.nestml +++ b/tests/valid/CoCoNestNamespaceCollision.nestml @@ -1,30 +1,36 @@ -/** - * - * CoCoNestNamespaceCollision.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace - * is detected. - * Positive case. -*/ +""" +CoCoNestNamespaceCollision.nestml +################################# +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace +is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoNestNamespaceCollision: function handler(Tau_1 mV): # handler is not a NEST specific function, thus everything correct return diff --git a/tests/valid/CoCoNoOrderOfEquations.nestml b/tests/valid/CoCoNoOrderOfEquations.nestml index 5141e11c9..13c63312e 100644 --- a/tests/valid/CoCoNoOrderOfEquations.nestml +++ b/tests/valid/CoCoNoOrderOfEquations.nestml @@ -1,35 +1,46 @@ -/** - * - * CoCoNoOrderOfEquations.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. - * Positive case. -*/ +""" +CoCoNoOrderOfEquations.nestml +############################# + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoNoOrderOfEquations: - initial_values: + state: V_m mV = 10mV end equations: V_m' = 10 mV / s # rhs is provided with an order > 0, thus everything is correct end + + update: + integrate_odes() + end end diff --git a/tests/valid/CoCoOdeCorrectlyTyped.nestml b/tests/valid/CoCoOdeCorrectlyTyped.nestml index 06c1ffbda..4a242b6e0 100644 --- a/tests/valid/CoCoOdeCorrectlyTyped.nestml +++ b/tests/valid/CoCoOdeCorrectlyTyped.nestml @@ -1,38 +1,48 @@ -/** - * - * CoCoOdeCorrectlyTyped.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. - * - * Here, ODE is defined with correct typing. - * - * Positive case -*/ +""" +CoCoOdeCorrectlyTyped.nestml +############################ + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. + +Here, ODE is defined with correct typing. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoOdeCorrectlyTyped: - initial_values: # variable is now defined in the initial block, thus everything is correct. + state: # variable is now defined in the initial block, thus everything is correct. V_m mV = 10 mV end equations: V_m' = (10 pA) / (100 pF) end + + update: + integrate_odes() + end end diff --git a/tests/valid/CoCoOdeVarNotInInitialValues.nestml b/tests/valid/CoCoOdeVarNotInInitialValues.nestml index 3bc7bea3a..de0a0cf7d 100644 --- a/tests/valid/CoCoOdeVarNotInInitialValues.nestml +++ b/tests/valid/CoCoOdeVarNotInInitialValues.nestml @@ -1,36 +1,47 @@ -/** - * - * CoCoOdeVarNotInInitialValues.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if ode is defiend for a variable outside - * the initial-values block. - * Positive case -*/ +""" +CoCoOdeVarNotInInitialValues.nestml +################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if ode is defiend for a variable outside +the initial-values block. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoOdeVarNotInInitialValues: - initial_values: # variable is now defined in the initial block, thus everything is correct. + state: # variable is now defined in the initial block, thus everything is correct. V_m mV = 10mV end equations: V_m' = 10 mV / s end + + update: + integrate_odes() + end end diff --git a/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml b/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml index 9824031f8..451b809c0 100644 --- a/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml +++ b/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml @@ -1,56 +1,61 @@ -/** - * - * CoCoOutputPortDefinedIfEmitCall.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if the output is not defined. Based on the ``iaf_psc_exp`` model at Sep 2020. - * Positive case. -*/ +""" +CoCoOutputPortDefinedIfEmitCall.nestml +###################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if the output is not defined. Based on the ``iaf_psc_exp`` model at Sep 2020. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron iaf_psc_exp: state: - r integer # counts number of tick during the refractory period - end - - initial_values: + r integer = 0 # counts number of tick during the refractory period V_abs mV = 0 mV end equations: - kernel I_kernel_in = exp(-1/tau_syn_in*t) - kernel I_kernel_ex = exp(-1/tau_syn_ex*t) - recordable inline V_m mV = V_abs + E_L # Membrane potential. - inline I_syn pA = convolve(I_kernel_in, in_spikes) + convolve(I_kernel_ex, ex_spikes) + I_e + I_stim + kernel I_kernel_inh = exp(-t/tau_syn_inh) + kernel I_kernel_exc = exp(-t/tau_syn_exc) + recordable inline V_m mV = V_abs + E_L # Membrane potential + inline I_syn pA = convolve(I_kernel_inh, inh_spikes) + convolve(I_kernel_exc, exc_spikes) + I_e + I_stim V_abs' = -V_abs / tau_m + I_syn / C_m end parameters: - C_m pF = 250 pF # Capacity of the membrane - tau_m ms = 10 ms # Membrane time constant - tau_syn_in ms = 2 ms # Time constant of synaptic current - tau_syn_ex ms = 2 ms # Time constant of synaptic current - t_ref ms = 2 ms # Duration of refractory period - E_L mV = -70 mV # Resting potential + C_m pF = 250 pF # Capacitance of the membrane + tau_m ms = 10 ms # Membrane time constant + tau_syn_inh ms = 2 ms # Time constant of synaptic current + tau_syn_exc ms = 2 ms # Time constant of synaptic current + t_ref ms = 2 ms # Duration of refractory period + E_L mV = -70 mV # Resting potential V_reset mV = -70 mV - E_L # reset value of the membrane potential - Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!). - # I.e. the real threshold is (E_L_+V_th_) + Theta mV = -55 mV - E_L # Threshold, RELATIVE TO RESTING POTENTIAL (!) + # I.e. the real threshold is E_L + Theta # constant external input current I_e pA = 0 pA @@ -61,9 +66,9 @@ neuron iaf_psc_exp: end input: - ex_spikes pA <- excitatory spike - in_spikes pA <- inhibitory spike - I_stim pA <- current + exc_spikes pA <- excitatory spike + inh_spikes pA <- inhibitory spike + I_stim pA <- continuous end update: diff --git a/tests/valid/CoCoParameterAssignedOutsideBlock.nestml b/tests/valid/CoCoParameterAssignedOutsideBlock.nestml index a73fa42a1..d7955d9fd 100644 --- a/tests/valid/CoCoParameterAssignedOutsideBlock.nestml +++ b/tests/valid/CoCoParameterAssignedOutsideBlock.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoParameterAssignedOutsideBlock.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * assignment of values to parameters outside of parameter blocks is detected. - * Positive example. -*/ +""" +CoCoParameterAssignedOutsideBlock.nestml +######################################## + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +assignment of values to parameters outside of parameter blocks is detected. + +Positive example. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoParameterAssignedOutsideBlock: parameters: # parameter is not assigned outside the block, thus everything is correct test mV = 10mV diff --git a/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml b/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml new file mode 100644 index 000000000..411528f3c --- /dev/null +++ b/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml @@ -0,0 +1,44 @@ +""" +CoCoPrioritiesCorrectlySpecified.nestml +####################################### + + +Description ++++++++++++ + +This model is used to test the sequencing of event handlers in synapse models. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse CoCoPrioritiesCorrectlySpecified: + input: + pre_spikes real <- spike + post_spikes real <- spike + end + + onReceive(pre_spikes, priority=1): + end + + onReceive(post_spikes, priority=2): + end + +end diff --git a/tests/valid/CoCoResolutionLegallyUsed.nestml b/tests/valid/CoCoResolutionLegallyUsed.nestml new file mode 100644 index 000000000..73453f458 --- /dev/null +++ b/tests/valid/CoCoResolutionLegallyUsed.nestml @@ -0,0 +1,57 @@ +""" +CoCoResolutionLegallyUsed.nestml +################################ + + +Description ++++++++++++ + +This model is used to test the use of the predefined ``resolution()`` function. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +synapse CoCoResolutionLegallyUsed: + parameters: + d ms = 1 ms @nest::delay + a ms = resolution() + end + + internals: + b ms = resolution() + end + + state: + q ms = resolution() + end + + input: + pre_spikes real <- spike + end + + onReceive(pre_spikes): + x ms = resolution() + end + + update: + z ms = resolution() + end +end diff --git a/tests/valid/CoCoSpikeBufferWithoutType.nestml b/tests/valid/CoCoSpikeBufferWithoutType.nestml deleted file mode 100644 index ce43071dc..000000000 --- a/tests/valid/CoCoSpikeBufferWithoutType.nestml +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * CoCoSpikeBufferWithoutType.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if spike buffers without a data-type - * are detected. - * Positive case. -*/ - -neuron CoCoSpikeBufferWithoutType: - input: # buffer is provided with a type, thus everything is correct - spikeAll integer <- spike - end -end diff --git a/tests/valid/CoCoSpikeInputPortWithoutType.nestml b/tests/valid/CoCoSpikeInputPortWithoutType.nestml new file mode 100644 index 000000000..66c822334 --- /dev/null +++ b/tests/valid/CoCoSpikeInputPortWithoutType.nestml @@ -0,0 +1,38 @@ +""" +CoCoSpikeInputPortWithoutType.nestml +#################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if spike input ports without a data-type are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoSpikeInputPortWithoutType: + input: # port is provided with a type, thus everything is correct + spikeAll integer <- spike + end +end diff --git a/tests/valid/CoCoStateVariablesInitialized.nestml b/tests/valid/CoCoStateVariablesInitialized.nestml new file mode 100644 index 000000000..2eb7691a4 --- /dev/null +++ b/tests/valid/CoCoStateVariablesInitialized.nestml @@ -0,0 +1,39 @@ +""" +CoCoStateVariablesInitialized.nestml +#################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if initial values are provided for all state variables declared in the ``state`` block. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoStateVariablesInitialized: + state: + V_m mV = 10 mV + V_abs mV = -10 mV + r integer = 5 + end +end diff --git a/tests/valid/CoCoSynsOneBuffer.nestml b/tests/valid/CoCoSynsOneBuffer.nestml new file mode 100644 index 000000000..d3e9fd82c --- /dev/null +++ b/tests/valid/CoCoSynsOneBuffer.nestml @@ -0,0 +1,88 @@ +""" +CoCoSynsOneBuffer.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether each synapse +uses exactly one buffer + +Here the AMPA synapse uses one buffer: spikesAMPA +and the AMPA_NMDA synapse uses one buffer: spikesExc + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron cm_syns_model_one: + + state: + + # the presence of the state variable [v_comp] + # triggers compartment model context + v_comp real = 0 + + end + + + parameters: + + ### synapses ### + e_AMPA real = 0.0 + tau_syn_AMPA real = 0.2 + + e_NMDA real = 0.0 + tau_syn_NMDA real = 0.2 # Synaptic Time Constant Excitatory Synapse + + NMDA_ratio_ real = 2.0 + + end + + equations: + + ### synapses ### + + kernel g_ex_AMPA = exp(-t / tau_syn_AMPA) + inline AMPA real = convolve(g_ex_AMPA, spikesAMPA) * (v_comp - e_AMPA) + + kernel g_ex_NMDA = exp(-t / tau_syn_NMDA) + inline AMPA_NMDA real = convolve(g_ex_NMDA, spikesExc) * (v_comp - e_NMDA) + NMDA_ratio_ * convolve(g_ex_AMPA, spikesExc) * (v_comp - e_AMPA) + + end + + internals: + + end + + input: + spikesExc nS <- excitatory spike + spikesAMPA ns <- excitatory spike + end + + output: spike + + update: + end + +end \ No newline at end of file diff --git a/tests/valid/CoCoUnitNumeratorNotOne.nestml b/tests/valid/CoCoUnitNumeratorNotOne.nestml index cec9c9cdb..eba6ee71a 100644 --- a/tests/valid/CoCoUnitNumeratorNotOne.nestml +++ b/tests/valid/CoCoUnitNumeratorNotOne.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoUnitNumeratorNotOne.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the - * incorrect numerator of the unit is detected. - * Positive case. -*/ +""" +CoCoUnitNumeratorNotOne.nestml +############################## + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the +incorrect numerator of the unit is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoUnitNumeratorNotOne: state: test1 1/s = 10/s # the numerator is correctly stated as 1, thus everything correct diff --git a/tests/valid/CoCoValueAssignedToBuffer.nestml b/tests/valid/CoCoValueAssignedToBuffer.nestml deleted file mode 100644 index b71c43c42..000000000 --- a/tests/valid/CoCoValueAssignedToBuffer.nestml +++ /dev/null @@ -1,36 +0,0 @@ -/** - * - * CoCoValueAssignedToBuffer.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to buffers - * is detected. - * Positive case. -*/ - -neuron CoCoValueAssignedToBuffer: - input: - spikeInh integer <- inhibitory spike - end - - update: # buffer not assigned, thus everything is correct - test integer = spikeInh + 10 - end -end diff --git a/tests/valid/CoCoValueAssignedToInputPort.nestml b/tests/valid/CoCoValueAssignedToInputPort.nestml new file mode 100644 index 000000000..4d7237dae --- /dev/null +++ b/tests/valid/CoCoValueAssignedToInputPort.nestml @@ -0,0 +1,42 @@ +""" +CoCoValueAssignedToInputPort.nestml +################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to input ports is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CoCoValueAssignedToInputPort: + input: + spikeInh integer <- inhibitory spike + end + + update: # input port not assigned to, thus everything is correct + test integer = spikeInh + 10 + end +end diff --git a/tests/valid/CoCoVariableDefinedAfterUsage.nestml b/tests/valid/CoCoVariableDefinedAfterUsage.nestml index 68384d67f..f12bb7768 100644 --- a/tests/valid/CoCoVariableDefinedAfterUsage.nestml +++ b/tests/valid/CoCoVariableDefinedAfterUsage.nestml @@ -1,36 +1,43 @@ -/** - * - * CoCoVariableDefinedAfterUsage.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. - * Positive case. -*/ +""" +CoCoVariableDefinedAfterUsage.nestml +#################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableDefinedAfterUsage: state: - test1 integer = 10 [[test1 < 10]] # the invalid invariant shall not be detected, although logically incorrect - test2 integer = test1 + test2 integer = 10 end update: - test1 = test2 + test1 + test1 integer = 20 + test1 = test2 end end diff --git a/tests/valid/CoCoVariableNotDefined.nestml b/tests/valid/CoCoVariableNotDefined.nestml index a16d09dac..6cc9c2e5c 100644 --- a/tests/valid/CoCoVariableNotDefined.nestml +++ b/tests/valid/CoCoVariableNotDefined.nestml @@ -1,29 +1,36 @@ -/** - * - * CoCoVariableNotDefined.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. - * Positive case. -*/ +""" +CoCoVariableNotDefined.nestml +############################# + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableNotDefined: state: test1 integer = 0 diff --git a/tests/valid/CoCoVariableRedeclared.nestml b/tests/valid/CoCoVariableRedeclared.nestml index 490b05fa2..65b2a6a87 100644 --- a/tests/valid/CoCoVariableRedeclared.nestml +++ b/tests/valid/CoCoVariableRedeclared.nestml @@ -1,28 +1,36 @@ -/** - * - * CoCoVariableRedeclared.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This test is used to test the functionality of the coco which ensures that redeclaration of symbols is detected - * Positive case. -*/ +""" +CoCoVariableRedeclared.nestml +############################# + + +Description ++++++++++++ + +This test is used to test the functionality of the coco which ensures that redeclaration of symbols is detected + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableRedeclared: state: test1 mV = 20mV diff --git a/tests/valid/CoCoVariableRedeclaredInSameScope.nestml b/tests/valid/CoCoVariableRedeclaredInSameScope.nestml index 3802d9f0d..38f37da3a 100644 --- a/tests/valid/CoCoVariableRedeclaredInSameScope.nestml +++ b/tests/valid/CoCoVariableRedeclaredInSameScope.nestml @@ -1,29 +1,37 @@ -/** - * - * CoCoVariableRedeclaredInSameScope.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if - * a variable has been redeclared in a single scope. - * Positive case. -*/ +""" +CoCoVariableRedeclaredInSameScope.nestml +######################################## + + +Description ++++++++++++ + +This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +a variable has been redeclared in a single scope. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableRedeclaredInSameScope: state: test1 integer = 10 diff --git a/tests/valid/CoCoVariableWithSameNameAsUnit.nestml b/tests/valid/CoCoVariableWithSameNameAsUnit.nestml index 03bb8d8d6..f77cf8ac8 100644 --- a/tests/valid/CoCoVariableWithSameNameAsUnit.nestml +++ b/tests/valid/CoCoVariableWithSameNameAsUnit.nestml @@ -1,28 +1,36 @@ -/** - * - * CoCoVariableRedeclared.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. - * Negative case. -*/ +""" +CoCoVariableRedeclared.nestml +############################# + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. + +Negative case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVariableWithSameNameAsUnit: state: eV mV = 1 mV # should not conflict with predefined unit eV but throw a warning diff --git a/tests/valid/CoCoVectorDeclarationSize.nestml b/tests/valid/CoCoVectorDeclarationSize.nestml new file mode 100644 index 000000000..9d6478c25 --- /dev/null +++ b/tests/valid/CoCoVectorDeclarationSize.nestml @@ -0,0 +1,45 @@ +""" +CoCoVectorParameterSize.nestml +############################## + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. +Here, if the vector parameter or the size of the vector is greater than 0. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron CoCoVectorParameterSize: + state: + V_m [10] mV = -10. mV + end + + parameters: + N integer = 1 + coeff [N] real = 0 + end +end diff --git a/tests/valid/CoCoVectorInNonVectorDeclaration.nestml b/tests/valid/CoCoVectorInNonVectorDeclaration.nestml index 7f9f73a3c..32ce49604 100644 --- a/tests/valid/CoCoVectorInNonVectorDeclaration.nestml +++ b/tests/valid/CoCoVectorInNonVectorDeclaration.nestml @@ -1,34 +1,43 @@ -/** - * - * CoCoVectorInNonVectorDeclaration.nestml - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - * - * This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration - * are detected. - * Positive case. -*/ +""" +CoCoVectorInNonVectorDeclaration.nestml +####################################### + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration +are detected. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" neuron CoCoVectorInNonVectorDeclaration: state: + g_ex [ten] mV = 10mV + end + + parameters: ten integer = 10 - g_ex mV [ten] = 10mV - g_in mV [ten]= g_ex + g_ex # vector = vector + vector, thus everything is correct end end diff --git a/tests/valid/CoCoVectorParameterDeclaration.nestml b/tests/valid/CoCoVectorParameterDeclaration.nestml new file mode 100644 index 000000000..bf1f93b47 --- /dev/null +++ b/tests/valid/CoCoVectorParameterDeclaration.nestml @@ -0,0 +1,49 @@ +""" +CoCoVectorParameterDeclaration.nestml +##################################### + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. +Here, if the vector parameter is declared in the correct block. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron CoCoVectorParameterDeclaration: + state: + v_m [size] mV = -55 mV + y [size_y] real = 1.5 + end + + parameters: + size integer = 20 + end + + internals: + size_y integer = 5 + end +end diff --git a/tests/valid/CoCoVectorParameterType.nestml b/tests/valid/CoCoVectorParameterType.nestml new file mode 100644 index 000000000..c827958f2 --- /dev/null +++ b/tests/valid/CoCoVectorParameterType.nestml @@ -0,0 +1,45 @@ +""" +CoCoVectorParameterType.nestml +############################## + + +Description ++++++++++++ + +This model is used to test if broken CoCos are identified correctly. +Here, if the vector parameter is of the type integer. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +neuron CoCoVectorParameterDeclaration: + state: + v_m [size] mV = -55 mV + y [15] real = 1.5 + end + + parameters: + size integer = 20 + end +end diff --git a/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml b/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml new file mode 100644 index 000000000..354b5710a --- /dev/null +++ b/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml @@ -0,0 +1,39 @@ +""" +CompoundOperatorWithDifferentButCompatibleUnits.nestml +######################################################## + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron CompoundOperatorTest: + state: + lhs V = 1 V + end + + update: + lhs *= 1 + lhs *= (1 mA) * (1 Ohm) * (1/Volt) + lhs /= 1 + lhs /= (1 mA) * (1 Ohm) * (1/Volt) + lhs += 1 mV + lhs -= 1 mV + end +end diff --git a/tests/valid/DocstringCommentTest.nestml b/tests/valid/DocstringCommentTest.nestml new file mode 100644 index 000000000..f99a4622f --- /dev/null +++ b/tests/valid/DocstringCommentTest.nestml @@ -0,0 +1,41 @@ +""" +DocstringCommentTest.nestml +########################### + + +Description ++++++++++++ + +This model is used to test whether docstring comments are detected at any place other than just before the neuron keyword. + +Positive case. + + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" +neuron docstringCommentTest: + state: + # foo + test boolean = True #inline comment ok + # foo + # bar + end +end