├── LICENSE
├── LICENSE.CC-BY-4.0
├── LICENSE.MIT
├── README.md
├── environment.yml
├── example_1_pyloric_net_plot.py
├── example_1_pyloric_network.ipynb
├── example_1_pyloric_network_complex.ipynb
├── example_2_eye_movements.ipynb
├── example_2_eye_movements_interactive.ipynb
├── example_2_eye_movements_interactive_matplotlib.ipynb
├── example_3_bisection.ipynb
├── example_4_microphone.ipynb
├── example_appendix_multicompartment_model.ipynb
├── example_appendix_parameter_exploration.ipynb
├── index.ipynb
├── scale_flute.wav
├── sound_from_file.cpp
├── sound_from_mic.cpp
├── sound_input.h
└── tc200.CNG.swc
/LICENSE:
--------------------------------------------------------------------------------
1 | ## License
2 |
3 | This work is dual-licensed under the Creative Commons Attribution 4.0 International and the MIT license.
4 | You can choose between them if you use this work.
5 |
6 | `SPDX-License-Identifier: CC-BY-4.0 OR MIT`
7 |
8 |
--------------------------------------------------------------------------------
/LICENSE.CC-BY-4.0:
--------------------------------------------------------------------------------
1 | Creative Commons Attribution 4.0 International Public License
2 |
3 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
4 |
5 | Section 1 – Definitions.
6 |
7 | a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
8 | b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
9 | c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
10 | d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
11 | e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
12 | f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
13 | g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
14 | h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
15 | i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
16 | j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
17 | k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
18 |
19 | Section 2 – Scope.
20 |
21 | a. License grant.
22 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
23 | A. reproduce and Share the Licensed Material, in whole or in part; and
24 | B. produce, reproduce, and Share Adapted Material.
25 | 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
26 | 3. Term. The term of this Public License is specified in Section 6(a).
27 | 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
28 | 5. Downstream recipients.
29 | A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
30 | B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
31 | 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
32 | b. Other rights.
33 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
34 | 2. Patent and trademark rights are not licensed under this Public License.
35 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
36 |
37 | Section 3 – License Conditions.
38 |
39 | Your exercise of the Licensed Rights is expressly made subject to the following conditions.
40 |
41 | a. Attribution.
42 | 1. If You Share the Licensed Material (including in modified form), You must:
43 | A. retain the following if it is supplied by the Licensor with the Licensed Material:
44 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
45 | ii. a copyright notice;
46 | iii. a notice that refers to this Public License;
47 | iv. a notice that refers to the disclaimer of warranties;
48 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
49 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
50 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
51 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
52 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
53 | 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
54 |
55 | Section 4 – Sui Generis Database Rights.
56 |
57 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
58 |
59 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
60 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
61 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
62 |
63 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
64 |
65 | Section 5 – Disclaimer of Warranties and Limitation of Liability.
66 |
67 | a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
68 | b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
69 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
70 |
71 | Section 6 – Term and Termination.
72 |
73 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
74 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
75 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
76 | 2. upon express reinstatement by the Licensor.
77 | c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
78 | d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
79 | e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
80 |
81 | Section 7 – Other Terms and Conditions.
82 |
83 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
84 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
85 |
86 | Section 8 – Interpretation.
87 |
88 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
89 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
90 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
91 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
92 |
--------------------------------------------------------------------------------
/LICENSE.MIT:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Marcel Stimberg, Romain Brette, and Dan F.M. Goodman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Examples for Brian 2 paper
2 | --------------------------
3 |
4 | This repository contains interactive examples in the form of [Jupyter notebooks]() that demonstrate
5 | the use of the [Brian simulator](http://briansimulator.org) for neural modeling.
6 |
7 | Running these examples needs an installation of Brian 2 (see documentation at
8 | [brian2.readthedocs.io](https://brian2.readthedocs.io)), together with libraries
9 | for plotting of the results ([plotly](https://plot.ly/) and [matplotlib](https://matplotlib.org/)).
10 |
11 | You can install all necessary dependencies by creating a [conda](https://conda.io) environment from the provided environment file:
12 |
13 | ```shell
14 | $ conda env create -f environment.yml
15 | ```
16 |
17 | To run the notebooks in the [binder](https://mybinder.org/) environment, without requiring any installation on your local computer, use the following link:
18 | [](https://mybinder.org/v2/gh/brian-team/brian2_paper_examples/master?filepath=index.ipynb)
19 |
20 | The code and data in this repository are dual-licensed under the [Creative Commons Attribution 4.0 International Public License](LICENSE.CC-BY-4.0) and the
21 | [MIT license](LICENSE.MIT), you can chose between them if you use this work.
22 |
--------------------------------------------------------------------------------
/environment.yml:
--------------------------------------------------------------------------------
1 | name: brian2-paper-examples
2 | channels:
3 | - conda-forge
4 | dependencies:
5 | - python=3.6
6 | - cython=0.29*
7 | - nose=1.3*
8 | - ipywidgets=7.4*
9 | - notebook=5.7*
10 | - widgetsnbextension=3.4*
11 | - plotly=3.6*
12 | - sympy=1.3*
13 | - scipy=1.2*
14 | - matplotlib=2.1*
15 | - ipympl=0.2*
16 | - brian2=2.2.2.1
17 | - pip=19.*
18 | - pip:
19 | - brian2tools
20 |
21 |
--------------------------------------------------------------------------------
/example_1_pyloric_net_plot.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from plotly import tools
4 | from plotly.offline import iplot, init_notebook_mode
5 | import plotly.graph_objs as go
6 |
7 | from brian2.units import second, mV
8 |
9 | init_notebook_mode(connected=True)
10 |
11 | def do_pyloric_net_plot(spike_trains, times, membrane_potential, varname,
12 | init_time, observe_time, adapt_time):
13 | fig = tools.make_subplots(rows=7, cols=2, shared_xaxes=True, shared_yaxes=True,
14 | start_cell='bottom-left', subplot_titles=['initial', 'adapted',
15 | '', '', '', '', '', ''],
16 | specs=[[{}, {}],
17 | [{'rowspan': 2}, {'rowspan': 2}],
18 | [None, None],
19 | [{'rowspan': 2}, {'rowspan': 2}],
20 | [None, None],
21 | [{'rowspan': 2}, {'rowspan': 2}],
22 | [None, None]],
23 | print_grid=False)
24 |
25 | traces = []
26 | before_adaptation = (times>=init_time) & (times < (init_time + observe_time))
27 | after_adapt_time = init_time + observe_time + adapt_time
28 | after_adaptation = (times>=after_adapt_time)
29 | for idx, (label, color) in enumerate(zip(['AB/PD', 'LP', 'PY'],
30 | ['#1f77b4', '#ff7f03', '#2ca02c'])):
31 |
32 | trace = go.Scattergl(x=(times[before_adaptation] - init_time) / second,
33 | y=membrane_potential[idx][before_adaptation] / mV,
34 | marker={'color': color},
35 | showlegend=False, name=label)
36 | fig.append_trace(trace, 2+idx*2, 1)
37 | if spike_trains is not None:
38 | spike_times = spike_trains[idx]
39 | spike_times = spike_times[(spike_times >= init_time) & (spike_times < (init_time + observe_time))]
40 | spike_trace = go.Scattergl(x=(spike_times - init_time) / second,
41 | y=np.ones(len(spike_times))*(3-idx),
42 | marker={'symbol': 'line-ns', "line": {"width": 2, 'color': color}},
43 | mode='markers', showlegend=False, name=label)
44 | fig.append_trace(spike_trace, 1, 1)
45 | trace = go.Scattergl(x=(times[after_adaptation] - after_adapt_time) / second,
46 | y=membrane_potential[idx][after_adaptation] / mV,
47 | marker={'color': color},
48 | name=label)
49 | fig.append_trace(trace, 2+idx*2, 2)
50 | if spike_trains is not None:
51 | spike_times = spike_trains[idx]
52 | spike_times = spike_times[spike_times >= after_adapt_time]
53 | spike_trace = go.Scattergl(x=(spike_times - after_adapt_time) / second,
54 | y=np.ones(len(spike_times))*(3-idx),
55 | marker={'symbol': 'line-ns', "line": {"width": 2, 'color': color}},
56 | mode='markers', showlegend=False, name=label)
57 | fig.append_trace(spike_trace, 1, 2)
58 | fig['layout'].update(xaxis1={'range': (0, observe_time/second),
59 | 'title': 'time (in s)',
60 | 'zeroline': False},
61 | xaxis2={'range': (0, observe_time/second),
62 | 'title': 'time (in s)',
63 | 'zeroline': False},
64 | yaxis3={'title': 'v (in mV)'},
65 | yaxis1={'showline': False,
66 | 'showticklabels': False})
67 | iplot(fig)
68 |
--------------------------------------------------------------------------------
/example_1_pyloric_network.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 1 (Pyloric network of the crustacean stomatogastric ganglion)\n",
24 | "\n",
25 | "This example demonstrates a highly simplified model of the pyloric circuit of the crustacean stomatogastric ganglion. This circuit generates a tri-phasic rhythmic pattern with alternating bursts of action potentials in different types of motor neurons. Here, we follow previous work (e.g. Golowasch et al., 1999) by modeling the circuit as consisting of three populations: AB/PD (anterior buster and pyloaric dilator neurons), LP (lateral pyloric neurons), and PY (pyloric neurons). This model has a number of non-standard properties that will be described in the following annotated version of the code.\n",
26 | "\n",
27 | "Golowasch, J., Casey, M., Abbott, L. F., & Marder, E. (1999).
\n",
28 | "Network Stability from Activity-Dependent Regulation of Neuronal Conductances.
\n",
29 | "Neural Computation, 11(5), 1079-1096.
\n",
30 | "https://doi.org/10.1162/089976699300016359"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "metadata": {},
36 | "source": [
37 | "Before describing a model, we set up the Brian simulator:"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {},
44 | "outputs": [],
45 | "source": [
46 | "# Import names from the the Brian library\n",
47 | "from brian2.only import *"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "We now enable the high-performance \"standalone-mode\". By default, the first run statement the code encounters will trigger the automatic compilcation and execution. We disable this feature here (`build_on_run=False`) because our model consists of a sequence of runs. Only after all runs have been defined, we ask Brian to build and execute the simulation code"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "set_device('cpp_standalone', build_on_run=False)"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "To make simulation runs reproducible, we set the seed of the random number generator."
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": null,
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "seed(123456)"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "All operations in Brian take place on \"clocks\" that step forward with given time steps. If not defined otherwise (as in this script), operations use the \"default clock\". We set its time step to 0.01ms:"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "defaultclock.dt = 0.01*ms"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "The neuron's membrane potential in the pyloric network shows slow oscillations with burst of action potentials at its peak. Here, we use a variant of the Hindmarsh-Rose model, reformulated to use physical dimensions instead of unitless variables. This model defines the dynamics of the membrane potential $v$, and of the adaptation variables $w$ and $x$ as follows:\n",
103 | "$$\n",
104 | "\\frac{\\mathrm{d}v}{\\mathrm{d}t} = \\left(\\Delta_Tg\\left(-a\\left(v - v_T\\right)^3 + b\\left(v - v_T\\right)^2\\right) + w - x - I_\\mathrm{fast} - I_\\mathrm{slow}\\right)\\frac{1}{C} \\\\\n",
105 | "\\frac{\\mathrm{d}w}{\\mathrm{d}t} = \\left(c - d\\left(v - v_T\\right)^2 - w\\right)\\frac{1}{\\tau} \\\\\n",
106 | "\\frac{\\mathrm{d}x}{\\mathrm{d}t} = \\left(s\\left(v - v_r\\right) - x\\right)\\frac{1}{\\tau_x}\n",
107 | "$$\n",
108 | "\n",
109 | "In Brian, such equations can be specified as a string, following mathematic notation as closely as possible. The physical dimensions of the variable defined in the respective line has to be specified after a colon; this allows Brian to check for the consistency of the dimensions and therefore avoid the use of incorrect equations:"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": null,
115 | "metadata": {},
116 | "outputs": [],
117 | "source": [
118 | "eqs = '''\n",
119 | "dv/dt = (Delta_T*g*(-a*(v - v_T)**3 + b*(v - v_T)**2) + w - x - I_fast - I_slow)/C : volt\n",
120 | "dw/dt = (c - d*(v - v_T)**2 - w)/tau : amp\n",
121 | "dx/dt = (s*(v - v_r) - x)/tau_x : amp\n",
122 | "'''"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "One particular feature of the pyloric network model in Golowasch et al. (1999) is that not all intrinsic conductances are constant, but some are activity-dependent via the Calcium current. Here, we simplify this dependency by having a Calcium signal that exponentially decays in the absence of spikes (it increases with each spike, see definition later in the script):\n",
130 | "$$\n",
131 | "\\frac{\\mathrm{d}Ca}{\\mathrm{d}t} = -\\frac{Ca}{\\tau_{Ca}}\n",
132 | "$$"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {},
139 | "outputs": [],
140 | "source": [
141 | "eqs += '''\n",
142 | "dCa/dt = -Ca/tau_Ca : 1\n",
143 | "'''"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "Note that this Calcium signal is normalized and therefore dimensionless. We now follow the model of Golowasch et al. (1999) to describe the dependency of two conductances, $s$ and $g$ in our case, on the difference of this Calcium current to a target current via the dynamic variable $z$:\n",
151 | "$$\n",
152 | "\\frac{\\mathrm{d}z}{\\mathrm{d}t} = \\tanh\\left(Ca - Ca_\\mathrm{target}\\right)\\frac{1}{\\tau_z}\\\\\n",
153 | "s = S\\left(1 - \\tanh(z)\\right)\\\\\n",
154 | "g = G\\left(1 + \\tanh(z)\\right)\n",
155 | "$$"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "metadata": {},
162 | "outputs": [],
163 | "source": [
164 | "eqs += '''\n",
165 | "s = S*(1 - tanh(z)) : siemens\n",
166 | "g = G*(1 + tanh(z)) : siemens\n",
167 | "dz/dt = tanh(Ca - Ca_target)/tau_z : 1\n",
168 | "'''"
169 | ]
170 | },
171 | {
172 | "cell_type": "markdown",
173 | "metadata": {},
174 | "source": [
175 | "Finally, we note that $I_\\mathrm{fast}$ and $I_\\mathrm{slow}$ are neuron-specific state variables (set by the Synapses later), and that $Ca_\\mathrm{target}$ is a neuron-specific constant. We also add a special integer constant called `label` that will be used to label AB/PD, LP, and PY neurons."
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "metadata": {},
182 | "outputs": [],
183 | "source": [
184 | "eqs += '''\n",
185 | "I_fast : amp\n",
186 | "I_slow : amp\n",
187 | "Ca_target : 1 (constant)\n",
188 | "label : integer (constant)\n",
189 | "'''"
190 | ]
191 | },
192 | {
193 | "cell_type": "markdown",
194 | "metadata": {},
195 | "source": [
196 | "Our equations refer to a number of constants that are shared across all neurons, we define them as standard Python variables. "
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {},
203 | "outputs": [],
204 | "source": [
205 | "init_time = 2.5*second\n",
206 | "observe_time = 4*second\n",
207 | "adapt_time = 49 * second\n",
208 | "Delta_T = 17.5*mV\n",
209 | "v_T = -40*mV\n",
210 | "tau = 2*ms\n",
211 | "tau_adapt = .02*second\n",
212 | "tau_Ca = 150*ms\n",
213 | "tau_x = 2*second\n",
214 | "v_r = -68*mV\n",
215 | "a = 1/Delta_T**3\n",
216 | "b = 3/Delta_T**2\n",
217 | "d = 2.5*nA/Delta_T**2\n",
218 | "C = 60*pF\n",
219 | "S = 2*nA/Delta_T\n",
220 | "G = 28.5*nS\n",
221 | "tau_z = 5*second\n",
222 | "c = 1.2*nA\n",
223 | "ABPD, LP, PY = 0, 1, 2 # Arbitrary numbers"
224 | ]
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "Now, we create the neurons that follow the previously defined model, and additionally define what should count as a threshold crossing (`threshold`) and what should happen when it is crossed (`reset`). Note that this model describes the trajectory of the membrane potential during an action potential as part of its equations, it therefore does not reset the membrane potential after a spike as an integrate-and-fire model would. To prevent repeatedly triggering \"spikes\" due to the fact that the membrane potential is above the threshold all the time during the action potential, we state that while the neuron is still above the threshold, it should be considered not able to elicit any more spikes (`refractory`). Finally, we define the numerical integration method to use (`method`), here, a 2nd order Runge-Kutta method."
231 | ]
232 | },
233 | {
234 | "cell_type": "code",
235 | "execution_count": null,
236 | "metadata": {},
237 | "outputs": [],
238 | "source": [
239 | "circuit = NeuronGroup(3, eqs, threshold='v>-20*mV', refractory='v>-20*mV', method='rk2',\n",
240 | " reset='Ca += 0.1')"
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {},
246 | "source": [
247 | "We've defined a group of three neurons, each one being of a different type. We set the neurons' label accordingly and set the initial conditions for the variables $v$, $w$, and $z$, as well as the neuron-type dependent values for the constant $Ca_\\mathrm{target}$:"
248 | ]
249 | },
250 | {
251 | "cell_type": "code",
252 | "execution_count": null,
253 | "metadata": {},
254 | "outputs": [],
255 | "source": [
256 | "circuit.label = [ABPD, LP, PY]\n",
257 | "circuit.v = v_r\n",
258 | "circuit.w = '-5*nA*rand()'\n",
259 | "circuit.z = 'rand()*0.2 - 0.1'\n",
260 | "circuit.Ca_target = [0.048, 0.0384, 0.06]"
261 | ]
262 | },
263 | {
264 | "cell_type": "markdown",
265 | "metadata": {},
266 | "source": [
267 | "The predefined `rand()` function returns random number from a uniform distribution between 0 and 1, i.e. $w$ is initialized to be between 0nA and -5nA, and $z$ between -0.1 and 0.1.\n",
268 | "\n",
269 | "For this model, we want to describe two classes of synapses, \"fast\" and \"slow\". Both synaptic currents are graded functions of the presynaptic membrane potential. For the fast synapses, the current is an instantaneous function of both the pre-synaptic and the post-synaptic membrane potential:"
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": null,
275 | "metadata": {},
276 | "outputs": [],
277 | "source": [
278 | "# Synapses\n",
279 | "eqs_fast = '''\n",
280 | "g_fast : siemens (constant)\n",
281 | "I_fast_post = g_fast*(v_post - E_syn)/(1+exp(s_fast*(V_fast-v_pre))) : amp (summed)\n",
282 | "'''\n",
283 | "fast_synapses = Synapses(circuit, circuit, model=eqs_fast)"
284 | ]
285 | },
286 | {
287 | "cell_type": "markdown",
288 | "metadata": {},
289 | "source": [
290 | "The `(summed)` here means that the post-synaptic current will be summed over all currents from synapses targetting the same post-synaptic target. As for neurons, we then define general constants as Python variables:"
291 | ]
292 | },
293 | {
294 | "cell_type": "code",
295 | "execution_count": null,
296 | "metadata": {},
297 | "outputs": [],
298 | "source": [
299 | "s_fast = 0.2/mV\n",
300 | "V_fast = -50*mV\n",
301 | "s_slow = 1/mV\n",
302 | "V_slow = -55*mV\n",
303 | "E_syn = -75*mV\n",
304 | "k_1 = 1/ms"
305 | ]
306 | },
307 | {
308 | "cell_type": "markdown",
309 | "metadata": {},
310 | "source": [
311 | "To establish synapses between the neurons, we can provide a logical condition detailing whether a connection should be created for a specific pair of neurons. This condition can refer to arbitrary pre- and post-synaptic variables or constants. In the following, we make use of the `label` constant that defines the type of each neuron. Given that our simple model only includes one neuron of each type, we could have used the neuron indices instead. However, using a label has the advantage of clearly showing the intent behind the connection pattern and would automatically generalize to a network with multiple neurons per type. Here, we want to establish connections with fast synapses for all pairs of neurons with different type (i.e., don't connect neurons of the same type to each other), but not from PY to AB/PD neurons: "
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": null,
317 | "metadata": {},
318 | "outputs": [],
319 | "source": [
320 | "fast_synapses.connect('label_pre != label_post and not (label_pre == PY and label_post == ABPD)')"
321 | ]
322 | },
323 | {
324 | "cell_type": "markdown",
325 | "metadata": {},
326 | "source": [
327 | "The maximum conductance of each synapse depends on the pre- and post-synaptic neuron types, we assign them accordingly:"
328 | ]
329 | },
330 | {
331 | "cell_type": "code",
332 | "execution_count": null,
333 | "metadata": {},
334 | "outputs": [],
335 | "source": [
336 | "fast_synapses.g_fast['label_pre == ABPD and label_post == LP'] = 0.015*uS\n",
337 | "fast_synapses.g_fast['label_pre == ABPD and label_post == PY'] = 0.005*uS\n",
338 | "fast_synapses.g_fast['label_pre == LP and label_post == ABPD'] = 0.01*uS\n",
339 | "fast_synapses.g_fast['label_pre == LP and label_post == PY'] = 0.02*uS\n",
340 | "fast_synapses.g_fast['label_pre == PY and label_post == LP'] = 0.005*uS"
341 | ]
342 | },
343 | {
344 | "cell_type": "markdown",
345 | "metadata": {},
346 | "source": [
347 | "For the slow synapses, the post-synaptic current depends on the pre-synaptic membrane potential indirectly via the variable $m_\\mathrm{slow}$ (its differential equation is solved via its analytical solution, requested by chosing `method='exact'`):"
348 | ]
349 | },
350 | {
351 | "cell_type": "code",
352 | "execution_count": null,
353 | "metadata": {},
354 | "outputs": [],
355 | "source": [
356 | "eqs_slow = '''\n",
357 | "k_2 : 1/second (constant)\n",
358 | "g_slow : siemens (constant)\n",
359 | "I_slow_post = g_slow*m_slow*(v_post-E_syn) : amp (summed)\n",
360 | "dm_slow/dt = k_1*(1-m_slow)/(1+exp(s_slow*(V_slow-v_pre))) - k_2*m_slow : 1 (clock-driven)\n",
361 | "'''\n",
362 | "slow_synapses = Synapses(circuit, circuit, model=eqs_slow, method='exact')"
363 | ]
364 | },
365 | {
366 | "cell_type": "markdown",
367 | "metadata": {},
368 | "source": [
369 | "Slow synapses are only arising from AB/PD units, and target neurons of all other types:"
370 | ]
371 | },
372 | {
373 | "cell_type": "code",
374 | "execution_count": null,
375 | "metadata": {},
376 | "outputs": [],
377 | "source": [
378 | "slow_synapses.connect('label_pre == ABPD and label_post != ABPD')"
379 | ]
380 | },
381 | {
382 | "cell_type": "markdown",
383 | "metadata": {},
384 | "source": [
385 | "Their maximum conductance depends on the type of the target cell:"
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": null,
391 | "metadata": {},
392 | "outputs": [],
393 | "source": [
394 | "slow_synapses.g_slow['label_post == LP'] = 0.025*uS\n",
395 | "slow_synapses.k_2['label_post == LP'] = 0.03/ms\n",
396 | "slow_synapses.g_slow['label_post == PY'] = 0.015*uS\n",
397 | "slow_synapses.k_2['label_post == PY'] = 0.008/ms"
398 | ]
399 | },
400 | {
401 | "cell_type": "markdown",
402 | "metadata": {},
403 | "source": [
404 | "Before we start the simulation, we state what data we want to record during the simulation. In addition to the spiking activity, we record the membrane potential $v$ for all cells (`record=True`). By default, this monitor would use the same time resolution as the rest of the simulation (0.01 ms), but we reduce the resolution to 0.1ms:"
405 | ]
406 | },
407 | {
408 | "cell_type": "code",
409 | "execution_count": null,
410 | "metadata": {},
411 | "outputs": [],
412 | "source": [
413 | "M = StateMonitor(circuit, ['v'], record=True, dt=.1*ms)\n",
414 | "spikes = SpikeMonitor(circuit)"
415 | ]
416 | },
417 | {
418 | "cell_type": "markdown",
419 | "metadata": {},
420 | "source": [
421 | "To make analysis and plotting easier, we run the simulations in separate parts with the recording initally switched off (`M.active = false`). After a short period (`init_time`) we record the activity for a fixed period (`observe_time`). We then let the network adapt its conductances for a long time (`adapt_time`), without recording its activity. Finally, we record the activity in the adaptated network."
422 | ]
423 | },
424 | {
425 | "cell_type": "code",
426 | "execution_count": null,
427 | "metadata": {},
428 | "outputs": [],
429 | "source": [
430 | "M.active = False\n",
431 | "run(init_time, report='text')\n",
432 | "M.active = True\n",
433 | "run(observe_time, report='text')\n",
434 | "M.active = False\n",
435 | "run(adapt_time, report='text')\n",
436 | "M.active = True\n",
437 | "run(observe_time, report='text')"
438 | ]
439 | },
440 | {
441 | "cell_type": "markdown",
442 | "metadata": {},
443 | "source": [
444 | "In the computationally efficient \"standalone mode\", the above statements describe the simulation protocol without actually launching the compilation and execution process. We do this now:"
445 | ]
446 | },
447 | {
448 | "cell_type": "code",
449 | "execution_count": null,
450 | "metadata": {},
451 | "outputs": [],
452 | "source": [
453 | "device.build(directory='example_1')"
454 | ]
455 | },
456 | {
457 | "cell_type": "markdown",
458 | "metadata": {},
459 | "source": [
460 | "After the simulation finished, we extract the spike trains from the monitor (spiking activity for each neuron) and call a general plotting procedure that we share with the more complex biophysical model."
461 | ]
462 | },
463 | {
464 | "cell_type": "code",
465 | "execution_count": null,
466 | "metadata": {},
467 | "outputs": [],
468 | "source": [
469 | "spike_trains = spikes.spike_trains()"
470 | ]
471 | },
472 | {
473 | "cell_type": "code",
474 | "execution_count": null,
475 | "metadata": {},
476 | "outputs": [],
477 | "source": [
478 | "from example_1_pyloric_net_plot import do_pyloric_net_plot\n",
479 | "do_pyloric_net_plot(spike_trains, M.t, M.v, 'v',\n",
480 | " init_time, observe_time, adapt_time);"
481 | ]
482 | },
483 | {
484 | "cell_type": "markdown",
485 | "metadata": {},
486 | "source": [
487 | "Note that you can zoom and pan the above figure."
488 | ]
489 | }
490 | ],
491 | "metadata": {
492 | "kernelspec": {
493 | "display_name": "Python 3",
494 | "language": "python",
495 | "name": "python3"
496 | },
497 | "language_info": {
498 | "codemirror_mode": {
499 | "name": "ipython",
500 | "version": 3
501 | },
502 | "file_extension": ".py",
503 | "mimetype": "text/x-python",
504 | "name": "python",
505 | "nbconvert_exporter": "python",
506 | "pygments_lexer": "ipython3",
507 | "version": "3.6.7"
508 | }
509 | },
510 | "nbformat": 4,
511 | "nbformat_minor": 2
512 | }
513 |
--------------------------------------------------------------------------------
/example_1_pyloric_network_complex.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 1 (Pyloric network of the crustacean stomatogastric ganglion) – biophysically detailed model\n",
24 | "\n",
25 | "This example is equivalent to the [simplified model](example_1_pyloric_network.ipynb), but uses a more biophysically detailed neuron model. For a detailed explanation of the modelling approach and the conversion of equations into Brian syntax, see the comments in that file.\n",
26 | "\n",
27 | "For details about the neuron model, see:\n",
28 | "\n",
29 | "Golowasch, J., Casey, M., Abbott, L. F., & Marder, E. (1999). \n",
30 | "Network Stability from Activity-Dependent Regulation of Neuronal Conductances. \n",
31 | "Neural Computation, 11(5), 1079-1096. \n",
32 | "https://doi.org/10.1162/089976699300016359"
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": null,
38 | "metadata": {},
39 | "outputs": [],
40 | "source": [
41 | "from brian2.only import *\n",
42 | "import numpy as np\n",
43 | "\n",
44 | "set_device('cpp_standalone', build_on_run=False)\n",
45 | "\n",
46 | "defaultclock.dt = 0.01*ms\n",
47 | "\n",
48 | "init_time = 0.5*second\n",
49 | "observe_time = 3*second\n",
50 | "adapt_time = 24 * second\n",
51 | "\n",
52 | "### Class-independent constants\n",
53 | "# Reversal potentials\n",
54 | "E_L = -68*mV\n",
55 | "E_Na = 20*mV\n",
56 | "E_K = -80*mV\n",
57 | "E_Ca = 120*mV\n",
58 | "E_proc = -10*mV\n",
59 | "\n",
60 | "# Capacitance\n",
61 | "C_s = 0.2*nF\n",
62 | "C_a = 0.02*nF\n",
63 | "\n",
64 | "# maximal conductances\n",
65 | "g_E = 10*nS\n",
66 | "g_La = 7.5*nS\n",
67 | "g_Na = 300*nS\n",
68 | "g_Kd = 4*uS\n",
69 | "G_Ca = 0.2*uS\n",
70 | "G_K = 16*uS\n",
71 | "\n",
72 | "# time constants (independent of V)\n",
73 | "tau_h_Ca = 150*ms\n",
74 | "tau_m_A = 0.1*ms\n",
75 | "tau_h_A = 50*ms\n",
76 | "tau_m_proc = 6*ms\n",
77 | "tau_m_Na = 0.025*ms\n",
78 | "tau_z = 5*second\n",
79 | "\n",
80 | "# Synapses\n",
81 | "s_fast = 0.2/mV\n",
82 | "V_fast = -50*mV\n",
83 | "s_slow = 1/mV\n",
84 | "V_slow = -55*mV\n",
85 | "E_syn = -75*mV\n",
86 | "k_1 = 1/ms\n",
87 | "\n",
88 | "### Neuronal equations\n",
89 | "eqs = '''\n",
90 | "# somatic compartment\n",
91 | "dV_s/dt = (-I_syn - I_L - I_Ca - I_K - I_A - I_proc - g_E*(V_s - V_a))/C_s : volt\n",
92 | "\n",
93 | "I_L = g_Ls*(V_s - E_L) : amp\n",
94 | "I_K = g_K*m_K**4*(V_s - E_K) : amp\n",
95 | "I_A = g_A*m_A**3*h_A*(V_s - E_K) : amp\n",
96 | "I_proc = g_proc*m_proc*(V_s - E_proc) : amp\n",
97 | "\n",
98 | "I_syn = I_fast + I_slow: amp\n",
99 | "I_fast : amp\n",
100 | "I_slow : amp\n",
101 | "\n",
102 | "I_Ca = g_Ca*m_Ca**3*h_Ca*(V_s - E_Ca) : amp\n",
103 | "dm_Ca/dt = (m_Ca_inf - m_Ca)/tau_m_Ca : 1\n",
104 | "m_Ca_inf = 1/(1 + exp(0.205/mV*(-61.2*mV - V_s))): 1\n",
105 | "tau_m_Ca = 30*ms -5*ms/(1 + exp(0.2/mV*(-65*mV - V_s))) : second\n",
106 | "dh_Ca/dt = (h_Ca_inf - h_Ca)/tau_h_Ca : 1\n",
107 | "h_Ca_inf = 1/(1 + exp(-0.15/mV*(-75*mV - V_s))) : 1\n",
108 | "\n",
109 | "dm_K/dt = (m_K_inf - m_K)/tau_m_K : 1\n",
110 | "m_K_inf = 1/(1 + exp(0.1/mV*(-35*mV - V_s))) : 1\n",
111 | "tau_m_K = 2*ms + 55*ms/(1 + exp(-0.125/mV*(-54*mV - V_s))) : second\n",
112 | "\n",
113 | "dm_A/dt = (m_A_inf - m_A)/tau_m_A : 1\n",
114 | "m_A_inf = 1/(1 + exp(0.2/mV*(-60*mV - V_s))) : 1\n",
115 | "dh_A/dt = (h_A_inf - h_A)/tau_h_A : 1\n",
116 | "h_A_inf = 1/(1 + exp(-0.18/mV*(-68*mV - V_s))) : 1\n",
117 | "\n",
118 | "dm_proc/dt = (m_proc_inf - m_proc)/tau_m_proc : 1\n",
119 | "m_proc_inf = 1/(1 + exp(0.2/mV*(-55*mV - V_s))) : 1\n",
120 | "\n",
121 | "# axonal compartment\n",
122 | "dV_a/dt = (-g_La*(V_a - E_L) - g_Na*m_Na**3*h_Na*(V_a - E_Na)\n",
123 | " -g_Kd*m_Kd**4*(V_a - E_K) - g_E*(V_a - V_s))/C_a : volt\n",
124 | "\n",
125 | "dm_Na/dt = (m_Na_inf - m_Na)/tau_m_Na : 1\n",
126 | "m_Na_inf = 1/(1 + exp(0.1/mV*(-42.5*mV - V_a))) : 1\n",
127 | "dh_Na/dt = (h_Na_inf - h_Na)/tau_h_Na : 1\n",
128 | "h_Na_inf = 1/(1 + exp(-0.13/mV*(-50*mV - V_a))) : 1\n",
129 | "tau_h_Na = 10*ms/(1 + exp(0.12/mV*(-77*mV - V_a))) : second\n",
130 | "\n",
131 | "dm_Kd/dt = (m_Kd_inf - m_Kd)/tau_m_Kd : 1\n",
132 | "m_Kd_inf = 1/(1 + exp(0.2/mV*(-41*mV - V_a))) : 1\n",
133 | "tau_m_Kd = 12.2*ms + 10.5*ms/(1 + exp(-0.05/mV*(58*mV - V_a))) : second\n",
134 | "\n",
135 | "# class-specific fixed maximal conductances\n",
136 | "g_Ls : siemens (constant)\n",
137 | "g_A : siemens (constant)\n",
138 | "g_proc : siemens (constant)\n",
139 | "\n",
140 | "# Adaptive conductances\n",
141 | "g_Ca = G_Ca/2*(1 + tanh(z)) : siemens\n",
142 | "g_K = G_K/2*(1 - tanh(z)) : siemens\n",
143 | "I_diff = (I_target + I_Ca) : amp\n",
144 | "dz/dt = tanh(I_diff/nA)/tau_z : 1\n",
145 | "I_target : amp (constant)\n",
146 | "\n",
147 | "# neuron class\n",
148 | "label : integer (constant)\n",
149 | "'''\n",
150 | "ABPD, LP, PY = 0, 1, 2\n",
151 | "\n",
152 | "circuit = NeuronGroup(3, eqs, method='rk2',\n",
153 | " threshold='m_Na > 0.5', refractory='m_Na > 0.5')\n",
154 | "\n",
155 | "# class-specific constants\n",
156 | "circuit.label = [ABPD, LP, PY]\n",
157 | "circuit.I_target = [0.4, 0.3, 0.5]*nA\n",
158 | "circuit.g_Ls = [30, 25, 15]*nS\n",
159 | "circuit.g_A = [450, 100, 250]*nS\n",
160 | "circuit.g_proc = [6, 8, 0]*nS\n",
161 | "\n",
162 | "# Initial conditions\n",
163 | "circuit.V_s = E_L\n",
164 | "circuit.V_a = E_L\n",
165 | "circuit.m_Ca = 'm_Ca_inf'\n",
166 | "circuit.h_Ca = 'h_Ca_inf'\n",
167 | "circuit.m_K = 'm_K_inf'\n",
168 | "circuit.m_A = 'm_A_inf'\n",
169 | "circuit.h_A = 'h_A_inf'\n",
170 | "circuit.m_proc = 'm_proc_inf'\n",
171 | "circuit.m_Na = 'm_Na_inf'\n",
172 | "circuit.h_Na = 'h_Na_inf'\n",
173 | "circuit.m_Kd = 'm_Kd_inf'"
174 | ]
175 | },
176 | {
177 | "cell_type": "markdown",
178 | "metadata": {},
179 | "source": [
180 | "The definition of the synapses and the simulation protocol are identical to the simplified model:"
181 | ]
182 | },
183 | {
184 | "cell_type": "code",
185 | "execution_count": null,
186 | "metadata": {},
187 | "outputs": [],
188 | "source": [
189 | "eqs_fast = '''\n",
190 | "g_fast : siemens (constant)\n",
191 | "I_fast_post = g_fast*(V_s_post - E_syn)/(1+exp(s_fast*(V_fast-V_s_pre))) : amp (summed)\n",
192 | "'''\n",
193 | "fast_synapses = Synapses(circuit, circuit, model=eqs_fast)\n",
194 | "fast_synapses.connect('label_pre != label_post and not (label_pre == PY and label_post == ABPD)')\n",
195 | "fast_synapses.g_fast['label_pre == ABPD and label_post == LP'] = 0.015*uS\n",
196 | "fast_synapses.g_fast['label_pre == ABPD and label_post == PY'] = 0.005*uS\n",
197 | "fast_synapses.g_fast['label_pre == LP and label_post == ABPD'] = 0.01*uS\n",
198 | "fast_synapses.g_fast['label_pre == LP and label_post == PY'] = 0.02*uS\n",
199 | "fast_synapses.g_fast['label_pre == PY and label_post == LP'] = 0.005*uS\n",
200 | "\n",
201 | "eqs_slow = '''\n",
202 | "k_2 : 1/second (constant)\n",
203 | "g_slow : siemens (constant)\n",
204 | "I_slow_post = g_slow*m_slow*(V_s_post-E_syn) : amp (summed)\n",
205 | "dm_slow/dt = k_1*(1-m_slow)/(1+exp(s_slow*(V_slow-V_s_pre))) - k_2*m_slow : 1 (clock-driven)\n",
206 | "'''\n",
207 | "slow_synapses = Synapses(circuit, circuit, model=eqs_slow, method='exact')\n",
208 | "slow_synapses.connect('label_pre == ABPD and label_post != ABPD')\n",
209 | "slow_synapses.g_slow['label_post == LP'] = 0.025*uS\n",
210 | "slow_synapses.k_2['label_post == LP'] = 0.03/ms\n",
211 | "slow_synapses.g_slow['label_post == PY'] = 0.015*uS\n",
212 | "slow_synapses.k_2['label_post == PY'] = 0.008/ms\n",
213 | "\n",
214 | "\n",
215 | "M = StateMonitor(circuit, 'V_s', record=True)\n",
216 | "spikes = SpikeMonitor(circuit)\n",
217 | "\n",
218 | "M.active = False\n",
219 | "run(init_time, report='text')\n",
220 | "M.active = True\n",
221 | "run(observe_time, report='text')\n",
222 | "M.active = False\n",
223 | "run(adapt_time, report='text')\n",
224 | "M.active = True\n",
225 | "run(observe_time, report='text')\n",
226 | "device.build(directory='example_1_complex')"
227 | ]
228 | },
229 | {
230 | "cell_type": "markdown",
231 | "metadata": {},
232 | "source": [
233 | "We use the same analysis/plotting procedure as in the simplified model:"
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": null,
239 | "metadata": {},
240 | "outputs": [],
241 | "source": [
242 | "spike_trains = spikes.spike_trains()\n",
243 | "\n",
244 | "# Plot\n",
245 | "from example_1_pyloric_net_plot import do_pyloric_net_plot\n",
246 | "do_pyloric_net_plot(spike_trains, M.t, M.V_s, 'V_s',\n",
247 | " init_time, observe_time, adapt_time);"
248 | ]
249 | }
250 | ],
251 | "metadata": {
252 | "kernelspec": {
253 | "display_name": "Python 3",
254 | "language": "python",
255 | "name": "python3"
256 | },
257 | "language_info": {
258 | "codemirror_mode": {
259 | "name": "ipython",
260 | "version": 3
261 | },
262 | "file_extension": ".py",
263 | "mimetype": "text/x-python",
264 | "name": "python",
265 | "nbconvert_exporter": "python",
266 | "pygments_lexer": "ipython3",
267 | "version": "3.6.7"
268 | }
269 | },
270 | "nbformat": 4,
271 | "nbformat_minor": 2
272 | }
273 |
--------------------------------------------------------------------------------
/example_2_eye_movements.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 2 (Smooth pursuit eye movements)\n",
24 | "This is an idealized model of the smooth pursuit reflex, including two ocular muscles, a moving visual stimulus and spiking neural control."
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {},
31 | "outputs": [],
32 | "source": [
33 | "from brian2 import *\n",
34 | "seed(79620)"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "Each of the two antagonistic ocular muscles is modelled as a spring of elasticity $k$ and some friction. To simplify, we consider that the eye moves laterally, rather than rotate. If $x$ is the position of the eye with 0 being the center, then the lengths of the springs are $L+x$ and $L-x$. The dynamics of the eye is then given by a second-order differential equation:\n",
42 | "$$ m\\frac{d^2x}{dt^2} = - k\\left(\\left(L+x\\right)-x_L\\right) + k\\left(\\left(L-x\\right)-x_R\\right) - f\\frac{dx}{dt}$$\n",
43 | "or:\n",
44 | "$$ m\\frac{d^2x}{dt^2} = k(x_L-x_R-2x) - f\\frac{dx}{dt}$$\n",
45 | "\n",
46 | "We see that $x_0 = \\frac{1}{2}(x_L-x_R)$ is the equilibrium position of the eye. Here we have assumed that spring elasticities are identical. We can rewrite this equation with just two parameters $\\alpha$ and $\\beta$:\n",
47 | "$$ \\frac{d^2x}{dt^2} = \\alpha(x_0 - x) - \\beta\\frac{dx}{dt}$$\n",
48 | "\n",
49 | "We will assume that eye position can move between -1 and 1.\n",
50 | "\n",
51 | "We consider that the resting length is the variable on which motoneurons act. Each spike from a motoneuron produces a waveform of contraction (\"twitch\"), i.e., a change in resting length. We consider that contractions add linearly, and resting lengths relax exponentially. By linearity it follows that we can simply express the action of motoneurons on the equilibrium position of the eye $x_0$, which relaxes exponentially to the center position 0.\n",
52 | "\n",
53 | "Finally, we consider a visual object that performs a random walk according to an Ornstein–Uhlenbeck with 0 as the central location."
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {},
60 | "outputs": [],
61 | "source": [
62 | "alpha = (1/(50*ms))**2 # characteristic relaxation time is 50 ms\n",
63 | "beta = 1/(50*ms) # friction parameter\n",
64 | "tau_muscle = 20*ms # relaxation time of muscle contraction\n",
65 | "tau_object = 500*ms # time constant of object movement\n",
66 | "\n",
67 | "eqs_eye = '''\n",
68 | "dx/dt = velocity : 1\n",
69 | "dvelocity/dt = alpha*(x0-x)-beta*velocity : 1/second\n",
70 | "dx0/dt = -x0/tau_muscle : 1\n",
71 | "dx_object/dt = (noise - x_object)/tau_object: 1\n",
72 | "dnoise/dt = -noise/tau_object + tau_object**-0.5*xi : 1\n",
73 | "'''\n",
74 | "eye = NeuronGroup(1, model=eqs_eye, method='euler')"
75 | ]
76 | },
77 | {
78 | "cell_type": "markdown",
79 | "metadata": {},
80 | "source": [
81 | "We now define two motoneurons, one for each muscle:"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": null,
87 | "metadata": {},
88 | "outputs": [],
89 | "source": [
90 | "taum = 20*ms\n",
91 | "motoneurons = NeuronGroup(2, model= 'dv/dt = -v/taum : 1', threshold = 'v>1',\n",
92 | " reset = 'v=0', refractory = 5*ms, method='exact')"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "The motoneurons project to the eye, and each spike produces a small contraction."
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": null,
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "motosynapses = Synapses(motoneurons, eye, model = 'w : 1', on_pre = 'x0+=w')\n",
109 | "motosynapses.connect() # connects all motoneurons to the eye\n",
110 | "motosynapses.w = [-0.5,0.5]"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "We now implement the sensory neurons, which we simplify by considering spiking neurons which directly respond to light, i.e they represent both photoreceptors and retinal ganglion cells. \n",
118 | "TODO: Talk about Gaussian dependence, et.c"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": null,
124 | "metadata": {},
125 | "outputs": [],
126 | "source": [
127 | "N = 20\n",
128 | "width = 2./N # width of receptive field\n",
129 | "gain = 4.\n",
130 | "eqs_retina = '''\n",
131 | "I = gain*exp(-((x_object-x_eye-x_neuron)/width)**2) : 1\n",
132 | "x_neuron : 1 (constant)\n",
133 | "x_object : 1 (linked) # position of the object\n",
134 | "x_eye : 1 (linked) # position of the eye\n",
135 | "dv/dt = (I-(1+gs)*v)/taum : 1\n",
136 | "gs : 1 # total synaptic conductance\n",
137 | "'''\n",
138 | "retina = NeuronGroup(N, model = eqs_retina, threshold = 'v>1', reset = 'v=0', method='exact')\n",
139 | "retina.v = 'rand()'\n",
140 | "retina.x_eye = linked_var(eye, 'x')\n",
141 | "retina.x_object = linked_var(eye, 'x_object')\n",
142 | "retina.x_neuron = '-1.0 + 2.0*i/(N-1)'"
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {},
148 | "source": [
149 | "Finally we connect sensory neurons to motoneurons. Sensory neurons on each hemifield connects to the corresponding motoneuron, with a strength that scales with eccentricity:"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {},
156 | "outputs": [],
157 | "source": [
158 | "sensorimotor_synapses = Synapses(retina, motoneurons, model = 'w : 1 (constant)', on_pre = 'v+=w')\n",
159 | "sensorimotor_synapses.connect(j = 'int(x_neuron_pre > 0)')\n",
160 | "sensorimotor_synapses.w = '20*abs(x_neuron_pre)/N_pre'"
161 | ]
162 | },
163 | {
164 | "cell_type": "markdown",
165 | "metadata": {},
166 | "source": [
167 | "We record the position of the eye, of the object, and spikes produced by the retina and motoneurons:"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": null,
173 | "metadata": {},
174 | "outputs": [],
175 | "source": [
176 | "M = StateMonitor(eye, ('x', 'x0', 'x_object'), record = True)\n",
177 | "S_retina = SpikeMonitor(retina)\n",
178 | "S_motoneurons = SpikeMonitor(motoneurons)"
179 | ]
180 | },
181 | {
182 | "cell_type": "markdown",
183 | "metadata": {},
184 | "source": [
185 | "We now can run the simulation:"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": null,
191 | "metadata": {},
192 | "outputs": [],
193 | "source": [
194 | "run(10*second, report='text')"
195 | ]
196 | },
197 | {
198 | "cell_type": "markdown",
199 | "metadata": {},
200 | "source": [
201 | "Finally, we plot the results"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "metadata": {},
208 | "outputs": [],
209 | "source": [
210 | "from plotly import tools\n",
211 | "from plotly.offline import iplot, init_notebook_mode\n",
212 | "import plotly.graph_objs as go\n",
213 | "\n",
214 | "init_notebook_mode(connected=True)\n",
215 | "\n",
216 | "fig = tools.make_subplots(3, 1, specs=[[{'rowspan': 2}], [None], [{}]],\n",
217 | " shared_xaxes=True, print_grid=False)\n",
218 | "\n",
219 | "trace = go.Scatter(x=S_retina.t/second,\n",
220 | " y=S_retina.i,\n",
221 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'black'}},\n",
222 | " mode='markers',\n",
223 | " name='retina',\n",
224 | " showlegend=False)\n",
225 | "fig.append_trace(trace, 1, 1)\n",
226 | "motoneuron_spikes = S_motoneurons.spike_trains()\n",
227 | "trace = go.Scatter(x=motoneuron_spikes[0]/second,\n",
228 | " y=np.ones(S_motoneurons.count[0])*N,\n",
229 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'#1f77b4'},\n",
230 | " 'color':'#1f77b4'},\n",
231 | " mode='markers',\n",
232 | " name='left motoneuron',\n",
233 | " showlegend=False)\n",
234 | "fig.append_trace(trace, 1, 1)\n",
235 | "trace = go.Scatter(x=motoneuron_spikes[1]/second,\n",
236 | " y=np.ones(S_motoneurons.count[1])*(N+1),\n",
237 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'#ff7f03'},\n",
238 | " 'color':'#ff7f03'},\n",
239 | " mode='markers',\n",
240 | " name='right motoneuron',\n",
241 | " showlegend=False)\n",
242 | "fig.append_trace(trace, 1, 1)\n",
243 | "\n",
244 | "trace = go.Scatter(x=M.t/second,\n",
245 | " y=M.x[0],\n",
246 | " mode='lines',\n",
247 | " line={'color': 'black'},\n",
248 | " name='eye')\n",
249 | "fig.append_trace(trace, 3, 1)\n",
250 | "trace = go.Scatter(x=M.t/second,\n",
251 | " y=M.x_object[0],\n",
252 | " mode='lines',\n",
253 | " line={'color': '#2ca02c'},\n",
254 | " name='object')\n",
255 | "fig.append_trace(trace, 3, 1)\n",
256 | "\n",
257 | "fig['layout'].update(xaxis1={'showline': False,\n",
258 | " 'zeroline': False,\n",
259 | " 'title': 'time (in s)'},\n",
260 | " yaxis1={'title': 'neuron index',\n",
261 | " 'showticklabels': False,\n",
262 | " 'showline': True},\n",
263 | " yaxis2={'tickmode': 'array',\n",
264 | " 'ticktext': ['left', 'right'],\n",
265 | " 'tickvals': [-1, 1],\n",
266 | " 'range': [-1.05, 1.05],\n",
267 | " 'zeroline': True,\n",
268 | " 'showline': True}\n",
269 | " )\n",
270 | "iplot(fig)"
271 | ]
272 | }
273 | ],
274 | "metadata": {
275 | "kernelspec": {
276 | "display_name": "Python 3",
277 | "language": "python",
278 | "name": "python3"
279 | },
280 | "language_info": {
281 | "codemirror_mode": {
282 | "name": "ipython",
283 | "version": 3
284 | },
285 | "file_extension": ".py",
286 | "mimetype": "text/x-python",
287 | "name": "python",
288 | "nbconvert_exporter": "python",
289 | "pygments_lexer": "ipython3",
290 | "version": "3.6.7"
291 | }
292 | },
293 | "nbformat": 4,
294 | "nbformat_minor": 2
295 | }
296 |
--------------------------------------------------------------------------------
/example_2_eye_movements_interactive.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 2 (Smooth pursuit eye movements) – interactive version\n",
24 | "\n",
25 | "This is an interactive verison of the idealized model of the smooth pursuit reflex. This version does not explain the model itself, but shows how Brian's \"runtime mode\" can be used to interact with a running simulation. In this mode, the generated code based on the model descriptions is seemlessly integrated with the Python environment and can execute arbitrary Python code at any point during the simulation via a specially annotated function, called a \"network operation\".\n",
26 | "\n",
27 | "For a non-interactive version of this example which generates the article's figure see [this notebook](example_2_eye_movements.ipynb).\n",
28 | "\n",
29 | "**This version uses the *plotly* library for consistency with the other examples. However, updating an existing figure is slower than with the *matplotlib* library, so it is not an ideal solution for this example. For a version based on *matplotlib*, see [this notebook](example_2_eye_movements_interactive_matplotlib.ipynb)**"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {},
36 | "outputs": [],
37 | "source": [
38 | "# Needs ipywidgets\n",
39 | "import ipywidgets as widgets\n",
40 | "import threading\n",
41 | "from brian2 import *"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "The model itself (mostly identical to the [non-interactive example](example_2_eye_movements.ipynb), except that some of the constants are included as parameters in the equation and can therefore change during the simulation):"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "alpha = (1/(50*ms))**2 # characteristic relaxation time is 50 ms\n",
58 | "beta = 1/(50*ms) # friction parameter\n",
59 | "\n",
60 | "eqs_eye = '''\n",
61 | "dx/dt = velocity : 1\n",
62 | "dvelocity/dt = alpha*(x0-x)-beta*velocity : 1/second\n",
63 | "dx0/dt = -x0/tau_muscle : 1\n",
64 | "dx_object/dt = (noise - x_object)/tau_object: 1\n",
65 | "dnoise/dt = -noise/tau_object + tau_object**-0.5*xi : 1\n",
66 | "tau_object : second\n",
67 | "tau_muscle : second\n",
68 | "'''\n",
69 | "eye = NeuronGroup(1, model=eqs_eye, method='euler')\n",
70 | "taum = 20*ms\n",
71 | "motoneurons = NeuronGroup(2, model= 'dv/dt = -v/taum : 1', threshold = 'v>1',\n",
72 | " reset = 'v=0', refractory = 5*ms, method='exact')\n",
73 | "motosynapses = Synapses(motoneurons, eye, model = 'w : 1', on_pre = 'x0+=w')\n",
74 | "motosynapses.connect() # connects all motoneurons to the eye\n",
75 | "motosynapses.w = [-0.5,0.5]\n",
76 | "N = 20\n",
77 | "width = 2./N # width of receptive field\n",
78 | "gain = 4.\n",
79 | "eqs_retina = '''\n",
80 | "I = gain*exp(-((x_object-x_eye-x_neuron)/width)**2) : 1\n",
81 | "x_neuron : 1 (constant)\n",
82 | "x_object : 1 (linked) # position of the object\n",
83 | "x_eye : 1 (linked) # position of the eye\n",
84 | "dv/dt = (I-(1+gs)*v)/taum : 1\n",
85 | "gs : 1 # total synaptic conductance\n",
86 | "'''\n",
87 | "retina = NeuronGroup(N, model = eqs_retina, threshold = 'v>1', reset = 'v=0', method='exact')\n",
88 | "retina.v = 'rand()'\n",
89 | "retina.x_eye = linked_var(eye, 'x')\n",
90 | "retina.x_object = linked_var(eye, 'x_object')\n",
91 | "retina.x_neuron = '-1.0 + 2.0*i/(N-1)'\n",
92 | "sensorimotor_synapses = Synapses(retina, motoneurons, model = 'w : 1 (constant)', on_pre = 'v+=w')\n",
93 | "sensorimotor_synapses.connect(j = 'int(x_neuron_pre > 0)')\n",
94 | "sensorimotor_synapses.w = '20*abs(x_neuron_pre)/N_pre'\n",
95 | "M = StateMonitor(eye, ('x', 'x0', 'x_object'), record = True)\n",
96 | "S_retina = SpikeMonitor(retina)\n",
97 | "S_motoneurons = SpikeMonitor(motoneurons)\n"
98 | ]
99 | },
100 | {
101 | "cell_type": "markdown",
102 | "metadata": {},
103 | "source": [
104 | "We create an empty plot that will be updated during the run:"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "from plotly import tools\n",
114 | "from plotly.offline import iplot, init_notebook_mode\n",
115 | "import plotly.graph_objs as go\n",
116 | "\n",
117 | "init_notebook_mode(connected=True)\n",
118 | "\n",
119 | "fig = tools.make_subplots(3, 1, specs=[[{'rowspan': 2}], [None], [{}]],\n",
120 | " shared_xaxes=True, print_grid=False)\n",
121 | "\n",
122 | "retina_spikes = go.Scattergl(x=[],\n",
123 | " y=[],\n",
124 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'black'}},\n",
125 | " mode='markers',\n",
126 | " name='retina',\n",
127 | " showlegend=False)\n",
128 | "fig.append_trace(retina_spikes, 1, 1)\n",
129 | "left_spikes = go.Scattergl(x=[],\n",
130 | " y=[],\n",
131 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'#1f77b4'},\n",
132 | " 'color':'#1f77b4'},\n",
133 | " mode='markers',\n",
134 | " name='left motoneuron',\n",
135 | " showlegend=False)\n",
136 | "fig.append_trace(left_spikes, 1, 1)\n",
137 | "right_spikes = go.Scattergl(x=[],\n",
138 | " y=[],\n",
139 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'#ff7f03'},\n",
140 | " 'color':'#ff7f03'},\n",
141 | " mode='markers',\n",
142 | " name='right motoneuron',\n",
143 | " showlegend=False)\n",
144 | "fig.append_trace(right_spikes, 1, 1)\n",
145 | "\n",
146 | "eye_position = go.Scattergl(x=[],\n",
147 | " y=[],\n",
148 | " mode='lines',\n",
149 | " line={'color': 'black'},\n",
150 | " name='eye')\n",
151 | "fig.append_trace(eye_position, 3, 1)\n",
152 | "object_position = go.Scattergl(x=[],\n",
153 | " y=[],\n",
154 | " mode='lines',\n",
155 | " line={'color': '#2ca02c'},\n",
156 | " name='object')\n",
157 | "fig.append_trace(object_position, 3, 1)\n",
158 | "\n",
159 | "fig['layout'].update(xaxis1={'showline': False,\n",
160 | " 'zeroline': False,\n",
161 | " 'title': 'time (in s)',\n",
162 | " 'range': (0, 10),\n",
163 | " 'ticktext': ['-10', '-8', '-6', '-4', '-2', '0'],\n",
164 | " 'tickvals': [0, 2, 4, 6, 8, 10]},\n",
165 | " yaxis1={'title': 'neuron index',\n",
166 | " 'showticklabels': False,\n",
167 | " 'showline': True,\n",
168 | " 'range': (0, N+2)},\n",
169 | " yaxis2={'tickmode': 'array',\n",
170 | " 'ticktext': ['left', 'right'],\n",
171 | " 'tickvals': [-1, 1],\n",
172 | " 'range': [-1.05, 1.05],\n",
173 | " 'zeroline': True,\n",
174 | " 'showline': True}\n",
175 | " )\n",
176 | "fig_widget = go.FigureWidget(fig)\n",
177 | "retina_spikes, left_spikes, right_spikes, eye_position, object_position = fig_widget.data"
178 | ]
179 | },
180 | {
181 | "cell_type": "markdown",
182 | "metadata": {},
183 | "source": [
184 | "We now create interactive widgets that the user can use to start/stop the simulation, as well as for setting certain simulation parameters."
185 | ]
186 | },
187 | {
188 | "cell_type": "code",
189 | "execution_count": null,
190 | "metadata": {},
191 | "outputs": [],
192 | "source": [
193 | "time_label = widgets.Label(value='Time: 0 s')\n",
194 | "start_stop_button = widgets.Button(tooltip='Start simulation', icon='play')\n",
195 | "\n",
196 | "tau_obj_slider = widgets.FloatSlider(orientation='horizontal', description='tau_object',\n",
197 | " value=500, min=100, max=1000)\n",
198 | "tau_muscle_slider = widgets.FloatSlider(orientation='horizontal', description='tau_muscle',\n",
199 | " value=20, min=5, max=100)\n",
200 | "weight_slider = widgets.FloatSlider(orientation='horizontal', description='w_muscle',\n",
201 | " value=0.5, min=0, max=2)\n",
202 | "sliders = widgets.VBox([widgets.HBox([time_label, start_stop_button]),\n",
203 | " tau_obj_slider, tau_muscle_slider, weight_slider])\n",
204 | "layout = widgets.HBox([fig_widget, sliders])"
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {},
210 | "source": [
211 | "We interact with the running simulation via a \"network operation\", a Python function that will be regularly called by Brian during the simulation run (here, every 100ms of biological time). This function can access arbitrary attributes of the model to get or set their values. We use this here to 1) update the plot with the data from the last second and 2) set parameters of the model to the values requested by the user."
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {},
218 | "outputs": [],
219 | "source": [
220 | "should_stop = False\n",
221 | "@network_operation(dt=500*ms)\n",
222 | "def plot_output(t):\n",
223 | " with fig_widget.batch_update():\n",
224 | " cutoff = (t - 10*second)\n",
225 | " # Plot the data of the last 10 seconds\n",
226 | " indices = S_retina.t > cutoff\n",
227 | " retina_spikes.x = (S_retina.t[indices] - cutoff)/second\n",
228 | " retina_spikes.y = S_retina.i[indices]\n",
229 | " motoneuron_trains = S_motoneurons.spike_trains()\n",
230 | " to_plot = motoneuron_trains[0][motoneuron_trains[0] > cutoff]\n",
231 | " left_spikes.x = (to_plot - cutoff)/second\n",
232 | " left_spikes.y = np.ones(len(to_plot))*N\n",
233 | " to_plot = motoneuron_trains[1][motoneuron_trains[1] > cutoff]\n",
234 | " right_spikes.x = (to_plot - cutoff)/second\n",
235 | " right_spikes.y = np.ones(len(to_plot))*(N+1)\n",
236 | " indices = M.t > cutoff\n",
237 | " eye_position.x = (M.t[indices] - cutoff)/second\n",
238 | " eye_position.y = M.x[0][indices]\n",
239 | " object_position.x = (M.t[indices] - cutoff)/second\n",
240 | " object_position.y = M.x_object[0][indices]\n",
241 | " time_label.value = 'Time: {:.1f}s'.format(float(t[:]))\n",
242 | " # Set the simulation parameters according to user settings\n",
243 | " eye.tau_object = tau_obj_slider.value*ms\n",
244 | " eye.tau_muscle = tau_muscle_slider.value*ms\n",
245 | " motosynapses.w = [-weight_slider.value, weight_slider.value]\n",
246 | " if should_stop:\n",
247 | " net.stop()"
248 | ]
249 | },
250 | {
251 | "cell_type": "markdown",
252 | "metadata": {},
253 | "source": [
254 | "We store the model and the \"network operation\" in a `Network` object, and store its current state to allow for repeated execution."
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": null,
260 | "metadata": {},
261 | "outputs": [],
262 | "source": [
263 | "net = Network(collect())\n",
264 | "net.store()"
265 | ]
266 | },
267 | {
268 | "cell_type": "markdown",
269 | "metadata": {},
270 | "source": [
271 | "We now define two helper functions used to start/stop simulations. The actual simulation will be run in a background thread so that the user interface stays reactive while the simulation is running:"
272 | ]
273 | },
274 | {
275 | "cell_type": "code",
276 | "execution_count": null,
277 | "metadata": {},
278 | "outputs": [],
279 | "source": [
280 | "def do_run(runtime):\n",
281 | " net.restore()\n",
282 | " net.run(runtime)\n",
283 | "running = False\n",
284 | "def button_pressed(b):\n",
285 | " global running\n",
286 | " global should_stop\n",
287 | " if running:\n",
288 | " should_stop = True\n",
289 | " running = False\n",
290 | " start_stop_button.tooltip = 'Start simulation'\n",
291 | " start_stop_button.icon = 'play'\n",
292 | " else:\n",
293 | " should_stop = False\n",
294 | " running = True\n",
295 | " time_label.value = 'starting...'\n",
296 | " start_stop_button.tooltip = 'Stop simulation'\n",
297 | " start_stop_button.icon = 'stop'\n",
298 | " thread = threading.Thread(target=do_run, args=(100*second, ))\n",
299 | " thread.start()\n",
300 | "start_stop_button.on_click(button_pressed)"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "We are now ready to display the plot and user interface, which can then be used to start the simulation and interact with the simulation parameters:"
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": null,
313 | "metadata": {},
314 | "outputs": [],
315 | "source": [
316 | "display(layout)"
317 | ]
318 | }
319 | ],
320 | "metadata": {
321 | "kernelspec": {
322 | "display_name": "Python 3",
323 | "language": "python",
324 | "name": "python3"
325 | },
326 | "language_info": {
327 | "codemirror_mode": {
328 | "name": "ipython",
329 | "version": 3
330 | },
331 | "file_extension": ".py",
332 | "mimetype": "text/x-python",
333 | "name": "python",
334 | "nbconvert_exporter": "python",
335 | "pygments_lexer": "ipython3",
336 | "version": "3.6.7"
337 | }
338 | },
339 | "nbformat": 4,
340 | "nbformat_minor": 2
341 | }
342 |
--------------------------------------------------------------------------------
/example_2_eye_movements_interactive_matplotlib.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 2 (Smooth pursuit eye movements) – interactive version based on *matplotlib*\n",
24 | "\n",
25 | "\n",
26 | "This is an interactive verison of the idealized model of the smooth pursuit reflex. This version does not explain the model itself, but shows how Brian's \"runtime mode\" can be used to interact with a running simulation. In this mode, the generated code based on the model descriptions is seemlessly integrated with the Python environment and can execute arbitrary Python code at any point during the simulation via a specially annotated function, called a \"network operation\".\n",
27 | "\n",
28 | "For a non-interactive version of this example which generates the article's figure see [this notebook](example_2_eye_movements.ipynb).\n",
29 | "\n",
30 | "This notebook is based on *matplotlib* and *ipympl*, which enables quick updates of the plot in real-time. For a version based on *plotly* (as the other, non-interactive examples), see [this notebook](example_2_eye_movements_interactive.ipynb)."
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": null,
36 | "metadata": {},
37 | "outputs": [],
38 | "source": [
39 | "# Needs ipywidgets and ipympl\n",
40 | "%matplotlib widget\n",
41 | "import ipywidgets as widgets\n",
42 | "import threading\n",
43 | "from brian2 import *\n",
44 | "\n",
45 | "plt.ioff()"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "The model itself (mostly identical to the [non-interactive example](example_2_eye_movements.ipynb), except that some of the constants are included as parameters in the equation and can therefore change during the simulation):"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "alpha = (1/(50*ms))**2 # characteristic relaxation time is 50 ms\n",
62 | "beta = 1/(50*ms) # friction parameter\n",
63 | "\n",
64 | "eqs_eye = '''\n",
65 | "dx/dt = velocity : 1\n",
66 | "dvelocity/dt = alpha*(x0-x)-beta*velocity : 1/second\n",
67 | "dx0/dt = -x0/tau_muscle : 1\n",
68 | "dx_object/dt = (noise - x_object)/tau_object: 1\n",
69 | "dnoise/dt = -noise/tau_object + tau_object**-0.5*xi : 1\n",
70 | "tau_object : second\n",
71 | "tau_muscle : second\n",
72 | "'''\n",
73 | "eye = NeuronGroup(1, model=eqs_eye, method='euler')\n",
74 | "taum = 20*ms\n",
75 | "motoneurons = NeuronGroup(2, model= 'dv/dt = -v/taum : 1', threshold = 'v>1',\n",
76 | " reset = 'v=0', refractory = 5*ms, method='exact')\n",
77 | "motosynapses = Synapses(motoneurons, eye, model = 'w : 1', on_pre = 'x0+=w')\n",
78 | "motosynapses.connect() # connects all motoneurons to the eye\n",
79 | "motosynapses.w = [-0.5,0.5]\n",
80 | "N = 20\n",
81 | "width = 2./N # width of receptive field\n",
82 | "gain = 4.\n",
83 | "eqs_retina = '''\n",
84 | "I = gain*exp(-((x_object-x_eye-x_neuron)/width)**2) : 1\n",
85 | "x_neuron : 1 (constant)\n",
86 | "x_object : 1 (linked) # position of the object\n",
87 | "x_eye : 1 (linked) # position of the eye\n",
88 | "dv/dt = (I-(1+gs)*v)/taum : 1\n",
89 | "gs : 1 # total synaptic conductance\n",
90 | "'''\n",
91 | "retina = NeuronGroup(N, model = eqs_retina, threshold = 'v>1', reset = 'v=0', method='exact')\n",
92 | "retina.v = 'rand()'\n",
93 | "retina.x_eye = linked_var(eye, 'x')\n",
94 | "retina.x_object = linked_var(eye, 'x_object')\n",
95 | "retina.x_neuron = '-1.0 + 2.0*i/(N-1)'\n",
96 | "sensorimotor_synapses = Synapses(retina, motoneurons, model = 'w : 1 (constant)', on_pre = 'v+=w')\n",
97 | "sensorimotor_synapses.connect(j = 'int(x_neuron_pre > 0)')\n",
98 | "sensorimotor_synapses.w = '20*abs(x_neuron_pre)/N_pre'\n",
99 | "M = StateMonitor(eye, ('x', 'x0', 'x_object'), record = True)\n",
100 | "S_retina = SpikeMonitor(retina)\n",
101 | "S_motoneurons = SpikeMonitor(motoneurons)\n"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "We create an empty plot that will be updated during the run:"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": null,
114 | "metadata": {},
115 | "outputs": [],
116 | "source": [
117 | "# Plot preparation\n",
118 | "fig, (ax_spikes, ax_position) = plt.subplots(2, 1, gridspec_kw={'height_ratios': (2, 1)}, sharex=True)\n",
119 | "h_retina = ax_spikes.plot([], [], '|k', markeredgecolor='k', label='retina')[0]\n",
120 | "h_left = ax_spikes.plot([], [], '|', color='C0', markeredgecolor='C0', label='left motoneuron')[0]\n",
121 | "h_right = ax_spikes.plot([], [], '|', color='C1', markeredgecolor='C1', label='right motoneuron')[0]\n",
122 | "ax_spikes.set(yticks=[], ylabel='neuron index', xticks=[], xlim=(0, 10), ylim=(0, 22))\n",
123 | "ax_spikes.spines['bottom'].set_visible(False)\n",
124 | "\n",
125 | "ax_position.axhline(0, color='gray')\n",
126 | "h_eye = ax_position.plot([], [], 'k', label='eye')[0]\n",
127 | "h_object = ax_position.plot([], [], color='C2', label='object')[0]\n",
128 | "ax_position.set(yticks=[-1, 1], yticklabels=['left', 'right'], xlabel='time (s)',\n",
129 | " xticks=np.arange(11, 2), xticklabels=np.arange(11, 2)-10,\n",
130 | " xlim=(0, 10), ylim=(-1, 1))\n",
131 | "ax_position.legend(loc='upper right', bbox_to_anchor=(1.0, 2.0));"
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "metadata": {},
137 | "source": [
138 | "We now create interactive widgets that the user can use to start/stop the simulation, as well as for setting certain simulation parameters."
139 | ]
140 | },
141 | {
142 | "cell_type": "code",
143 | "execution_count": null,
144 | "metadata": {},
145 | "outputs": [],
146 | "source": [
147 | "time_label = widgets.Label(value='Time: 0 s')\n",
148 | "start_stop_button = widgets.Button(tooltip='Start simulation', icon='play')\n",
149 | "\n",
150 | "tau_obj_slider = widgets.FloatSlider(orientation='horizontal', description='tau_object',\n",
151 | " value=500, min=100, max=1000)\n",
152 | "tau_muscle_slider = widgets.FloatSlider(orientation='horizontal', description='tau_muscle',\n",
153 | " value=20, min=5, max=100)\n",
154 | "weight_slider = widgets.FloatSlider(orientation='horizontal', description='w_muscle',\n",
155 | " value=0.5, min=0, max=2)\n",
156 | "sliders = widgets.VBox([widgets.HBox([time_label, start_stop_button]),\n",
157 | " tau_obj_slider, tau_muscle_slider, weight_slider])\n",
158 | "layout = widgets.HBox([fig.canvas, sliders])"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "We interact with the running simulation via a \"network operation\", a Python function that will be regularly called by Brian during the simulation run (here, every 100ms of biological time). This function can access arbitrary attributes of the model to get or set their values. We use this here to 1) update the plot with the data from the last second and 2) set parameters of the model to the values requested by the user."
166 | ]
167 | },
168 | {
169 | "cell_type": "code",
170 | "execution_count": null,
171 | "metadata": {},
172 | "outputs": [],
173 | "source": [
174 | "should_stop = False\n",
175 | "@network_operation(dt=100*ms)\n",
176 | "def plot_output(t):\n",
177 | " cutoff = (t - 10*second)\n",
178 | " # Plot the data of the last 10 seconds\n",
179 | " indices = S_retina.t > cutoff\n",
180 | " h_retina.set_data((S_retina.t[indices] - cutoff)/second, S_retina.i[indices])\n",
181 | " motoneuron_trains = S_motoneurons.spike_trains()\n",
182 | " to_plot = motoneuron_trains[0][motoneuron_trains[0] > cutoff]\n",
183 | " h_left.set_data((to_plot - cutoff)/second, np.ones(len(to_plot))*N)\n",
184 | " to_plot = motoneuron_trains[1][motoneuron_trains[1] > cutoff]\n",
185 | " h_right.set_data((to_plot - cutoff)/second, np.ones(len(to_plot))*(N+1))\n",
186 | " indices = M.t > cutoff\n",
187 | " h_eye.set_data((M.t[indices] - cutoff)/second, M.x[0][indices])\n",
188 | " h_object.set_data((M.t[indices] - cutoff)/second, M.x_object[0][indices])\n",
189 | " fig.canvas.draw_idle()\n",
190 | " time_label.value = 'Time: {:.1f}s'.format(float(t[:]))\n",
191 | " # Set the simulation parameters according to user settings\n",
192 | " eye.tau_object = tau_obj_slider.value*ms\n",
193 | " eye.tau_muscle = tau_muscle_slider.value*ms\n",
194 | " motosynapses.w = [-weight_slider.value, weight_slider.value]\n",
195 | " if should_stop:\n",
196 | " net.stop()"
197 | ]
198 | },
199 | {
200 | "cell_type": "markdown",
201 | "metadata": {},
202 | "source": [
203 | "We store the model and the \"network operation\" in a `Network` object, and store its current state to allow for repeated execution."
204 | ]
205 | },
206 | {
207 | "cell_type": "code",
208 | "execution_count": null,
209 | "metadata": {},
210 | "outputs": [],
211 | "source": [
212 | "net = Network(collect())\n",
213 | "net.store()"
214 | ]
215 | },
216 | {
217 | "cell_type": "markdown",
218 | "metadata": {},
219 | "source": [
220 | "We now define two helper functions used to start/stop simulations. The actual simulation will be run in a background thread so that the user interface stays reactive while the simulation is running:"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": null,
226 | "metadata": {},
227 | "outputs": [],
228 | "source": [
229 | "def do_run(runtime):\n",
230 | " net.restore()\n",
231 | " net.run(runtime)\n",
232 | "running = False\n",
233 | "def button_pressed(b):\n",
234 | " global running\n",
235 | " global should_stop\n",
236 | " if running:\n",
237 | " should_stop = True\n",
238 | " running = False\n",
239 | " start_stop_button.tooltip = 'Start simulation'\n",
240 | " start_stop_button.icon = 'play'\n",
241 | " else:\n",
242 | " should_stop = False\n",
243 | " running = True\n",
244 | " time_label.value = 'starting...'\n",
245 | " start_stop_button.tooltip = 'Stop simulation'\n",
246 | " start_stop_button.icon = 'stop'\n",
247 | " thread = threading.Thread(target=do_run, args=(100*second, ))\n",
248 | " thread.start()\n",
249 | "start_stop_button.on_click(button_pressed)"
250 | ]
251 | },
252 | {
253 | "cell_type": "markdown",
254 | "metadata": {},
255 | "source": [
256 | "We are now ready to display the plot and user interface, which can then be used to start the simulation and interact with the simulation parameters:"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": null,
262 | "metadata": {},
263 | "outputs": [],
264 | "source": [
265 | "display(layout)"
266 | ]
267 | },
268 | {
269 | "cell_type": "code",
270 | "execution_count": null,
271 | "metadata": {},
272 | "outputs": [],
273 | "source": []
274 | }
275 | ],
276 | "metadata": {
277 | "kernelspec": {
278 | "display_name": "Python 3",
279 | "language": "python",
280 | "name": "python3"
281 | },
282 | "language_info": {
283 | "codemirror_mode": {
284 | "name": "ipython",
285 | "version": 3
286 | },
287 | "file_extension": ".py",
288 | "mimetype": "text/x-python",
289 | "name": "python",
290 | "nbconvert_exporter": "python",
291 | "pygments_lexer": "ipython3",
292 | "version": "3.6.7"
293 | }
294 | },
295 | "nbformat": 4,
296 | "nbformat_minor": 2
297 | }
298 |
--------------------------------------------------------------------------------
/example_3_bisection.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 3 (Using bisection to find a neuron's voltage threshold)\n",
24 | "\n",
25 | "This example demonstrate how a control flow, where simulation parameters depend on the results of previous simulations, can be expressed by making use of standard control structures in Python. By having access to the full expressivity of a general purpose programming language, expressing such control flow is straight-forward; this would not be the case for a declarative model description.\n",
26 | "\n",
27 | "Our goal in this toy example is to find the threshold voltage of neuron as a function of the density of sodium channels.\n",
28 | "\n",
29 | "We start with the basic setup:"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {},
36 | "outputs": [],
37 | "source": [
38 | "from brian2 import *\n",
39 | "\n",
40 | "defaultclock.dt = 0.01*ms # small time step for stiff equations"
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "Our model of the neuron is based on the classical model of from Hodgkin and Huxley (1952). Note that this is not actually a model of a neuron, but rather of a (space-clamped) axon. However, to avoid confusion with spatially extended models, we simply use the term \"neuron\" here. In this model, the membrane potential is shifted, i.e. the resting potential is at 0mV:"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": null,
53 | "metadata": {},
54 | "outputs": [],
55 | "source": [
56 | "El = 10.613*mV\n",
57 | "ENa = 115*mV\n",
58 | "EK = -12*mV\n",
59 | "gl = 0.3*msiemens/cm**2\n",
60 | "gK = 36*msiemens/cm**2\n",
61 | "gNa_max = 100*msiemens/cm**2\n",
62 | "gNa_min = 15*msiemens/cm**2\n",
63 | "C = 1*uF/cm**2\n",
64 | "\n",
65 | "eqs = '''\n",
66 | "dv/dt = (gl * (El-v) + gNa * m**3 * h * (ENa-v) + gK * n**4 * (EK-v)) / C : volt\n",
67 | "gNa : siemens/meter**2\n",
68 | "dm/dt = alpham * (1-m) - betam * m : 1\n",
69 | "dn/dt = alphan * (1-n) - betan * n : 1\n",
70 | "dh/dt = alphah * (1-h) - betah * h : 1\n",
71 | "alpham = (0.1/mV) * (-v+25*mV) / (exp((-v+25*mV) / (10*mV)) - 1)/ms : Hz\n",
72 | "betam = 4 * exp(-v/(18*mV))/ms : Hz\n",
73 | "alphah = 0.07 * exp(-v/(20*mV))/ms : Hz\n",
74 | "betah = 1/(exp((-v+30*mV) / (10*mV)) + 1)/ms : Hz\n",
75 | "alphan = (0.01/mV) * (-v+10*mV) / (exp((-v+10*mV) / (10*mV)) - 1)/ms : Hz\n",
76 | "betan = 0.125*exp(-v/(80*mV))/ms : Hz\n",
77 | "'''"
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {},
83 | "source": [
84 | "We simulate 100 neurons at the same time, each of them having a density of sodium channels between 15 and 100 mS/cm²:"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {},
91 | "outputs": [],
92 | "source": [
93 | "neurons = NeuronGroup(100, eqs, method='rk4', threshold='v>50*mV')\n",
94 | "neurons.gNa = 'gNa_min + (gNa_max - gNa_min)*1.0*i/N'"
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "We initialize the state variables to their resting state values, note that the values for $m$, $n$, $h$ depend on the values of $\\alpha_m$, $\\beta_m$, etc. which themselves depend on $v$. The order of the assignments ($v$ is initialized before $m$, $n$, and $h$) therefore matters, something that is naturally expressed by stating initial values as sequential assignments to the state variables. In a declarative approach, this would be potentially ambiguous."
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {},
108 | "outputs": [],
109 | "source": [
110 | "neurons.v = 0*mV\n",
111 | "neurons.m = '1/(1 + betam/alpham)'\n",
112 | "neurons.n = '1/(1 + betan/alphan)'\n",
113 | "neurons.h = '1/(1 + betah/alphah)'"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "We record the spiking activity of the neurons and store the current network state so that we can later restore it and run another iteration of our experiment:"
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "execution_count": null,
126 | "metadata": {},
127 | "outputs": [],
128 | "source": [
129 | "S = SpikeMonitor(neurons)\n",
130 | "store()"
131 | ]
132 | },
133 | {
134 | "cell_type": "markdown",
135 | "metadata": {},
136 | "source": [
137 | "The algorithm we use here to find the voltage threshold is a simple bisection: we try to find the threshold voltage of a neuron by repeatedly testing values and increasing or decreasing these values depending on whether we observe a spike or not. By continously halving the size of the correction, we quickly converge to a precise estimate.\n",
138 | "\n",
139 | "We start with the same initial estimate for all segments, 25mV above the resting potential, and the same value for the size of the \"correction step\":"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": null,
145 | "metadata": {},
146 | "outputs": [],
147 | "source": [
148 | "v0 = 25*mV*ones(len(neurons))\n",
149 | "step = 25*mV"
150 | ]
151 | },
152 | {
153 | "cell_type": "markdown",
154 | "metadata": {},
155 | "source": [
156 | "For later visualization of how the estimates converged towards their final values, we also store the intermediate values of the estimates:"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "estimates = np.full((11, len(neurons)), np.nan)*mV\n",
166 | "estimates[0, :] = v0"
167 | ]
168 | },
169 | {
170 | "cell_type": "markdown",
171 | "metadata": {},
172 | "source": [
173 | "We now run 10 iterations of our algorithm:"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": null,
179 | "metadata": {},
180 | "outputs": [],
181 | "source": [
182 | "for i in range(10):\n",
183 | " # Reset to the initial state\n",
184 | " restore()\n",
185 | " # Set the membrane potential to our threshold estimate\n",
186 | " neurons.v = v0\n",
187 | " # Run the simulation for 20ms\n",
188 | " run(20*ms)\n",
189 | " # Decrease the estimates for neurons that spiked\n",
190 | " v0[S.count > 0] -= step\n",
191 | " # Increase the estimate for neurons that did not spike\n",
192 | " v0[S.count == 0] += step\n",
193 | " # Reduce step size and store current estimate\n",
194 | " step /= 2.0\n",
195 | " estimates[i + 1, :] = v0"
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "After the 10 iteration steps, we plot the results:"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {},
209 | "outputs": [],
210 | "source": [
211 | "from plotly import tools\n",
212 | "from plotly.offline import iplot, init_notebook_mode\n",
213 | "import plotly.graph_objs as go\n",
214 | "\n",
215 | "init_notebook_mode(connected=True)\n",
216 | "\n",
217 | "fig = tools.make_subplots(2, 1, shared_yaxes=True, print_grid=False)\n",
218 | "colors = ['#1f77b4', '#ff7f03', '#2ca02c']\n",
219 | "examples = [10, 50, 90]\n",
220 | "for example, color in zip(examples, colors):\n",
221 | " trace = go.Scatter(x=np.arange(11),\n",
222 | " y=estimates[:, example] / mV, \n",
223 | " name='gNA = %.1fmS/cm$^2$' % (neurons.gNa[example]/(mS/cm**2)),\n",
224 | " marker={'color': color, 'size': 10},\n",
225 | " mode='markers+lines',\n",
226 | " showlegend=False)\n",
227 | " fig.append_trace(trace, 1, 1)\n",
228 | "\n",
229 | "trace = go.Scatter(x=neurons.gNa/(mS/cm**2),\n",
230 | " y=v0/mV,\n",
231 | " line={'color': 'gray'},\n",
232 | " mode='lines',\n",
233 | " name='threshold estimate',\n",
234 | " showlegend=False)\n",
235 | "fig.append_trace(trace, 2, 1)\n",
236 | "for idx, (example, color) in enumerate(zip(examples, colors)):\n",
237 | " trace = go.Scatter(x=[neurons.gNa[example]/(mS/cm**2)],\n",
238 | " y=[estimates[-1, example]/mV],\n",
239 | " mode='markers',\n",
240 | " marker={'color': color, 'symbol': 'circle', 'size': 15},\n",
241 | " showlegend=False,\n",
242 | " name='gNA = %.1fmS/cm$^2$' % (neurons.gNa[example]/(mS/cm**2)))\n",
243 | " fig.append_trace(trace, 2, 1)\n",
244 | "fig['layout'].update(xaxis1={'title': 'iteration'},\n",
245 | " xaxis2={'title': 'gNA (mS/cm²)'},\n",
246 | " yaxis1={'range': (0, 45),\n",
247 | " 'title': 'threshold estimate (mV)'},\n",
248 | " yaxis2={'range': (0, 45),\n",
249 | " 'title': 'threshold estimate (mV)'})\n",
250 | "\n",
251 | "iplot(fig)"
252 | ]
253 | }
254 | ],
255 | "metadata": {
256 | "kernelspec": {
257 | "display_name": "Python 3",
258 | "language": "python",
259 | "name": "python3"
260 | },
261 | "language_info": {
262 | "codemirror_mode": {
263 | "name": "ipython",
264 | "version": 3
265 | },
266 | "file_extension": ".py",
267 | "mimetype": "text/x-python",
268 | "name": "python",
269 | "nbconvert_exporter": "python",
270 | "pygments_lexer": "ipython3",
271 | "version": "3.6.7"
272 | }
273 | },
274 | "nbformat": 4,
275 | "nbformat_minor": 2
276 | }
277 |
--------------------------------------------------------------------------------
/example_4_microphone.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Example 4 (neural pitch processing with audio input)\n",
24 | "\n",
25 | "This example is a crude \"pitch detector\" network that performs autocorrelation of an audio signal. It works with coincidence detector neurons that receive two copies of the input (which has been transformed into spikes by an equally crude \"periphery neuron\" model), with a certain delay between the two inputs. Depending on their respective delay, neurons are sensitive to different periodicities.\n",
26 | "\n",
27 | "The example shows how Brian's high-level model descriptions can be seemlessly combined with low-level code in a target language, in this case C++. Such code can be necessary to extend Brian functionalities without sacrificing performance, e.g. in applications that necessitate real-time processing of external stimuli.\n",
28 | "\n",
29 | "In this code, we use this mechanism to provide two possible sources of audio input: a pre-recorded audio file (`use_microphone = False`), or real-time input from a microphone (`use_microphone = True`). For the latter, the `portaudio` library needs to be installed. Also note that access to the computers microphone is not possible when running the notebook on an external server such as [mybinder](https://mybinder.org)."
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {},
36 | "outputs": [],
37 | "source": [
38 | "from brian2 import *\n",
39 | "import os"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {},
45 | "source": [
46 | "We'll use the high-performance C++ standalone mode, otherwise we are not guaranteed that processing is faster than realtime (necessary when using microphone input)."
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {},
53 | "outputs": [],
54 | "source": [
55 | "set_device('cpp_standalone', directory='example_4')"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "We first set a few global parameters of the model:"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "metadata": {},
69 | "outputs": [],
70 | "source": [
71 | "sample_rate = 44.1*kHz\n",
72 | "buffer_size = 128\n",
73 | "defaultclock.dt = 1/sample_rate\n",
74 | "runtime = 4.5*second\n",
75 | "\n",
76 | "# Receptor neurons (\"ear\")\n",
77 | "max_delay = 20*ms # 50 Hz\n",
78 | "tau_ear = 1*ms\n",
79 | "tau_th = 5*ms\n",
80 | "# Coincidence detectors\n",
81 | "min_freq = 50*Hz\n",
82 | "max_freq = 1000*Hz\n",
83 | "num_neurons = 300\n",
84 | "tau = 1*ms\n",
85 | "sigma = .1"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "The model equations (see code further down below) refer to a `get_sample` function that returns the next available audio sample. Since we cannot express this function as mathematical equations, we directly provide its implementation in the target language C++. Since the code is relatively long we do not include it directly here, but instead store the source code in a separate file. We provide two such files, `sound_from_mic.cpp` for sound input from a microphone (used when `use_microphone` is set to `True`), and `sound_from_file.cpp` for sound read out from an uncompressed WAV audio file. These files will be compiled when needed because we provide their names as arguments to the `sources` keyword. Similarly, we include the function declaration that is present in the `sound_input.h` header file (identical for both cases), by specifying it to the `headers` keyword. We further customize the code that gets compiled by providing preprocessor macros via the `define_macros` keyword. Finally, since we are making use of the `portaudio` library for microphone input, we link to the `portaudio` library via the `libraries` keyword:"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "use_microphone = False\n",
102 | "if use_microphone:\n",
103 | " # Now comes the connection to the microphone code.\n",
104 | " @implementation('cpp','//actual code in sound_from_mic.cpp',\n",
105 | " sources=[os.path.abspath('sound_from_mic.cpp')],\n",
106 | " headers=['\"{}\"'.format(os.path.abspath('sound_input.h'))],\n",
107 | " libraries=['portaudio'],\n",
108 | " define_macros=[('BUFFER_SIZE', buffer_size),\n",
109 | " ('SAMPLE_RATE', sample_rate/Hz)])\n",
110 | " @check_units(t=second, result=1)\n",
111 | " def get_sample(t):\n",
112 | " raise NotImplementedError('Use a C++-based code generation target.')\n",
113 | "else:\n",
114 | " # Instead of using the microphone, use a sound file\n",
115 | " @implementation('cpp','//actual code in sound_from_file.cpp',\n",
116 | " sources=[os.path.abspath('sound_from_file.cpp')],\n",
117 | " headers=['\"{}\"'.format(os.path.abspath('sound_input.h'))],\n",
118 | " define_macros=[('FILENAME', r'\\\"{}\\\"'.format(os.path.abspath('scale_flute.wav')))])\n",
119 | " @check_units(t=second, result=1)\n",
120 | " def get_sample(t):\n",
121 | " raise NotImplementedError('Use a C++-based code generation target.')"
122 | ]
123 | },
124 | {
125 | "cell_type": "markdown",
126 | "metadata": {},
127 | "source": [
128 | "We now specify our neural and synaptic model, making use of the `get_sample` function as if it were one of the standard functions provided by Brian:"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": null,
134 | "metadata": {},
135 | "outputs": [],
136 | "source": [
137 | "gain = 50\n",
138 | "\n",
139 | "# Note that the `get_sample` function does not actually make use of the time `t` that it is given, for simplicity\n",
140 | "# it assumes that it is called only once per time step. This is actually enforced by using our `constant over dt`\n",
141 | "# feature -- the variable `sound` can be used in several places (which is important here, since we want to\n",
142 | "# record it as well):\n",
143 | "eqs_ear = '''\n",
144 | "dx/dt = (sound - x)/tau_ear: 1 (unless refractory)\n",
145 | "dth/dt = (0.1*x - th)/tau_th : 1\n",
146 | "sound = clip(get_sample(t), 0, inf) : 1 (constant over dt)\n",
147 | "'''\n",
148 | "receptors = NeuronGroup(1, eqs_ear, threshold='x>th', reset='x=0; th = th*2.5 + 0.01',\n",
149 | " refractory=2*ms, method='exact')\n",
150 | "receptors.th = 1\n",
151 | "sound_mon = StateMonitor(receptors, 'sound', record=0)\n",
152 | "\n",
153 | "eqs_neurons = '''\n",
154 | "dv/dt = -v/tau+sigma*(2./tau)**.5*xi : 1\n",
155 | "freq : Hz (constant)\n",
156 | "'''\n",
157 | "\n",
158 | "neurons = NeuronGroup(num_neurons, eqs_neurons, threshold='v>1', reset='v=0',\n",
159 | " method='euler')\n",
160 | "neurons.freq = 'exp(log(min_freq/Hz)+(i*1.0/(num_neurons-1))*log(max_freq/min_freq))*Hz'\n",
161 | "synapses = Synapses(receptors, neurons, on_pre='v += 0.5',\n",
162 | " multisynaptic_index='k')\n",
163 | "synapses.connect(n=2) # one synapse without delay; one with delay\n",
164 | "synapses.delay['k == 1'] = '1/freq_post'"
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "We record the spikes of the \"pitch detector\" neurons, and run the simulation:"
172 | ]
173 | },
174 | {
175 | "cell_type": "code",
176 | "execution_count": null,
177 | "metadata": {},
178 | "outputs": [],
179 | "source": [
180 | "spikes = SpikeMonitor(neurons)\n",
181 | "\n",
182 | "run(runtime)"
183 | ]
184 | },
185 | {
186 | "cell_type": "markdown",
187 | "metadata": {},
188 | "source": [
189 | "After the simulation ran through, we plot the raw sound input as well as its spectrogram, and the spiking activity of the detector neurons:"
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": null,
195 | "metadata": {},
196 | "outputs": [],
197 | "source": [
198 | "from plotly import tools\n",
199 | "from plotly.offline import iplot, init_notebook_mode\n",
200 | "import plotly.graph_objs as go\n",
201 | "from scipy.signal import spectrogram\n",
202 | "init_notebook_mode(connected=True)\n",
203 | "\n",
204 | "fig = tools.make_subplots(5, 1, shared_xaxes=True,\n",
205 | " specs=[[{}], [{'rowspan': 2}], [None], [{'rowspan': 2}], [None]],\n",
206 | " print_grid=False\n",
207 | " # subplot_titles=('Raw sound signal', 'Spectrogram of sound signal',\n",
208 | " # 'Spiking activity')\n",
209 | " )\n",
210 | "\n",
211 | "trace = go.Scatter(x=sound_mon.t/second,\n",
212 | " y=sound_mon.sound[0],\n",
213 | " name='sound signal',\n",
214 | " mode='lines',\n",
215 | " line={'color':'#1f77b4'},\n",
216 | " showlegend=False\n",
217 | " )\n",
218 | "fig.append_trace(trace, 1, 1)\n",
219 | "f, t, Sxx = spectrogram(sound_mon.sound[0], fs=sample_rate/Hz, nperseg=2**12, window='hamming')\n",
220 | "\n",
221 | "trace = go.Heatmap(x=t, y=f, z=10*np.log10(Sxx), showscale=False,\n",
222 | " colorscale='Viridis', name='PSD')\n",
223 | "fig.append_trace(trace, 2, 1)\n",
224 | "\n",
225 | "trace = go.Scatter(x=spikes.t/second,\n",
226 | " y=neurons.freq[spikes.i]/Hz, \n",
227 | " marker={'symbol': 'line-ns', 'line': {'width': 1, 'color':'#1f77b4'},\n",
228 | " 'color':'#1f77b4'},\n",
229 | " mode='markers',\n",
230 | " name='spikes', showlegend=False)\n",
231 | "fig.append_trace(trace, 4, 1)\n",
232 | "\n",
233 | "fig['layout'].update(xaxis={'title': 'time (in s)',\n",
234 | " 'range': (0.4, runtime/second)},\n",
235 | " yaxis1={'title': 'amplitude',\n",
236 | " 'showticklabels': False},\n",
237 | " yaxis2={'type': 'log',\n",
238 | " 'range': (0.9*np.log10(min_freq/Hz), 1.1*np.log10(500)),\n",
239 | " 'title': 'Frequency (Hz)'},\n",
240 | " yaxis3={'type': 'log',\n",
241 | " 'range': (0.9*np.log10(min_freq/Hz), 1.1*np.log10(500)),\n",
242 | " 'title': 'Preferred\\nFrequency (Hz)'})\n",
243 | "\n",
244 | "iplot(fig)"
245 | ]
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {},
250 | "source": [
251 | "If you ran the above code for the pre-recorded sound file, you should clearly see that four separate, ascending notes were played."
252 | ]
253 | }
254 | ],
255 | "metadata": {
256 | "kernelspec": {
257 | "display_name": "Python 3",
258 | "language": "python",
259 | "name": "python3"
260 | },
261 | "language_info": {
262 | "codemirror_mode": {
263 | "name": "ipython",
264 | "version": 3
265 | },
266 | "file_extension": ".py",
267 | "mimetype": "text/x-python",
268 | "name": "python",
269 | "nbconvert_exporter": "python",
270 | "pygments_lexer": "ipython3",
271 | "version": "3.6.7"
272 | }
273 | },
274 | "nbformat": 4,
275 | "nbformat_minor": 2
276 | }
277 |
--------------------------------------------------------------------------------
/example_appendix_parameter_exploration.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### Quickstart\n",
8 | "To run the code below:\n",
9 | "\n",
10 | "1. Click on the cell to select it.\n",
11 | "2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
12 | " () in the toolbar above.\n",
13 | "\n",
14 | "Feel free to create new cells using the plus button\n",
15 | "(), or pressing `SHIFT+ENTER` while this cell\n",
16 | "is selected."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Appendix 4: parameter exploration\n",
24 | "\n",
25 | "In this example, we show how Brian can be used to do a parameter exploration. The most efficient way to implement this is to consider a group of neurons, where each of the neurons is described by the same model, but one or several model parameters systematically change across neurons."
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "%matplotlib notebook\n",
35 | "from brian2 import *"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "We can speed up this \"embarassingly parallel\" problem by parallelizing it over CPUs, making use of the OpenMP interface for multithreading:"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "set_device('cpp_standalone')\n",
52 | "prefs.devices.cpp_standalone.openmp_threads = 4"
53 | ]
54 | },
55 | {
56 | "cell_type": "markdown",
57 | "metadata": {},
58 | "source": [
59 | "Using the [Brian2GeNN](https://brian2genn.readthedocs.io) interface, this simulation could also run on a GPU (needs a [CUDA](https://developer.nvidia.com/cuda-zone)-enabled NVIDIA GPU, and an installation of `brian2genn`): "
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": null,
65 | "metadata": {},
66 | "outputs": [],
67 | "source": [
68 | "# These two lines would replace the above two lines:\n",
69 | "# import brian2genn\n",
70 | "# set_device('genn')"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "We will first set some general constants for our model (a HH-type model with an injected current):"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "area = 20000*umetre**2\n",
87 | "Cm = (1*ufarad*cm**-2) * area\n",
88 | "gl = (5e-5*siemens*cm**-2) * area\n",
89 | "\n",
90 | "El = -60*mV\n",
91 | "EK = -90*mV\n",
92 | "ENa = 50*mV\n",
93 | "g_kd = (30*msiemens*cm**-2) * area\n",
94 | "VT = -63*mV"
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "We will explore the effect of the $g_{Na}$ conductance, and the effect of the injected current $I$, varying each over 100 values:"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {},
108 | "outputs": [],
109 | "source": [
110 | "g_na_values = np.linspace(10, 100, num=100)*msiemens*cm**-2 * area\n",
111 | "I_values = np.linspace(0, 20, num=100)*pA"
112 | ]
113 | },
114 | {
115 | "cell_type": "markdown",
116 | "metadata": {},
117 | "source": [
118 | "We now define the model, with $g_{Na}$ and $I$ as parameters, set independently for each neuron, and create one neuron for each combination of parameters:"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": null,
124 | "metadata": {},
125 | "outputs": [],
126 | "source": [
127 | "eqs = Equations('''\n",
128 | "dv/dt = (gl*(El-v)-\n",
129 | " g_na*(m*m*m)*h*(v-ENa)-\n",
130 | " g_kd*(n*n*n*n)*(v-EK) + I)/Cm : volt\n",
131 | "dm/dt = alpha_m*(1-m)-beta_m*m : 1\n",
132 | "dn/dt = alpha_n*(1-n)-beta_n*n : 1\n",
133 | "dh/dt = alpha_h*(1-h)-beta_h*h : 1\n",
134 | "alpha_m = 0.32*(mV**-1)*(13*mV-v+VT)/\n",
135 | " (exp((13*mV-v+VT)/(4*mV))-1.)/ms : Hz\n",
136 | "beta_m = 0.28*(mV**-1)*(v-VT-40*mV)/\n",
137 | " (exp((v-VT-40*mV)/(5*mV))-1)/ms : Hz\n",
138 | "alpha_h = 0.128*exp((17*mV-v+VT)/(18*mV))/ms : Hz\n",
139 | "beta_h = 4./(1+exp((40*mV-v+VT)/(5*mV)))/ms : Hz\n",
140 | "alpha_n = 0.032*(mV**-1)*(15*mV-v+VT)/\n",
141 | " (exp((15*mV-v+VT)/(5*mV))-1.)/ms : Hz\n",
142 | "beta_n = .5*exp((10*mV-v+VT)/(40*mV))/ms : Hz\n",
143 | "I : amp (constant)\n",
144 | "g_na : siemens (constant)\n",
145 | "''')\n",
146 | "neuron = NeuronGroup(len(g_na_values)*len(I_values), eqs,\n",
147 | " method='exponential_euler',\n",
148 | " threshold='v>-20*mV', refractory='v>-20*mV')\n",
149 | "neuron.v = El\n",
150 | "spike_mon = SpikeMonitor(neuron)"
151 | ]
152 | },
153 | {
154 | "cell_type": "markdown",
155 | "metadata": {},
156 | "source": [
157 | "We now create all combinations of the explored parameters, and assign them to the individual neurons. Running the \"network\" of neurons will then explore all the parameter combinations."
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": null,
163 | "metadata": {},
164 | "outputs": [],
165 | "source": [
166 | "all_g_na_values, all_I_values = np.meshgrid(g_na_values, I_values)\n",
167 | "all_g_na_values = all_g_na_values.flat[:]\n",
168 | "all_I_values = all_I_values.flat[:]\n",
169 | "neuron.g_na = all_g_na_values\n",
170 | "neuron.I = all_I_values"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | "We start the run and determine the firing rate for each neuron:"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {},
184 | "outputs": [],
185 | "source": [
186 | "run(10*second)\n",
187 | "rates = spike_mon.count/(10*second)/Hz"
188 | ]
189 | },
190 | {
191 | "cell_type": "markdown",
192 | "metadata": {},
193 | "source": [
194 | "We can now plot the firing rate as a function of the two explored parameters (in this example here, vertical slices of the graph can also be interpreted as the f/I curve of the neuron for varying values of $g_{Na}$):"
195 | ]
196 | },
197 | {
198 | "cell_type": "code",
199 | "execution_count": null,
200 | "metadata": {},
201 | "outputs": [],
202 | "source": [
203 | "I_index = ((neuron.I - np.min(I_values)) / np.diff(I_values)[0]).round().astype('int')\n",
204 | "Na_index = ((neuron.g_na - np.min(g_na_values)) / np.diff(g_na_values)[0]).round().astype('int')\n",
205 | "matrix = np.full((len(I_values), len(g_na_values)), np.nan)\n",
206 | "matrix[I_index, Na_index] = rates\n",
207 | "norm = mpl.colors.BoundaryNorm(np.arange(0, 19), plt.cm.viridis.N)\n",
208 | "fig, ax = plt.subplots()\n",
209 | "m = ax.imshow(matrix, norm=norm)\n",
210 | "# We do manual ticks, easier than using extent and getting the scaling right\n",
211 | "ticks = [0, 49, 99]\n",
212 | "ax.set(xticks=ticks, xticklabels=['%.1f' % (g_na_values[i]/(mS*cm**-2 * area)) for i in ticks],\n",
213 | " yticks=ticks, yticklabels=['%.1f' % (I_values[i]/pA) for i in ticks],\n",
214 | " xlabel='$g_{Na}$ (mS/cm²)', ylabel='$I$ (nA)')\n",
215 | "ax.axes.invert_yaxis()\n",
216 | "cbar = fig.colorbar(m)\n",
217 | "cbar.set_label('number of spikes')"
218 | ]
219 | }
220 | ],
221 | "metadata": {
222 | "kernelspec": {
223 | "display_name": "Python 3",
224 | "language": "python",
225 | "name": "python3"
226 | },
227 | "language_info": {
228 | "codemirror_mode": {
229 | "name": "ipython",
230 | "version": 3
231 | },
232 | "file_extension": ".py",
233 | "mimetype": "text/x-python",
234 | "name": "python",
235 | "nbconvert_exporter": "python",
236 | "pygments_lexer": "ipython3",
237 | "version": "3.6.7"
238 | }
239 | },
240 | "nbformat": 4,
241 | "nbformat_minor": 2
242 | }
243 |
--------------------------------------------------------------------------------
/index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Brian example notebooks\n",
8 | "\n",
9 | "These notebooks showcase examples that demonstrate various features of the [Brian simulator](http://brian2.readthedocs.io):\n",
10 | "\n",
11 | "* [Example 1 (Pyloric network of the crustacean stomatogastric ganglion)](example_1_pyloric_network.ipynb)\n",
12 | " * [the same example using a more detailed neuron model](example_1_pyloric_network_complex.ipynb)\n",
13 | "* [Example 2 (Smooth pursuit eye movements)](example_2_eye_movements.ipynb)\n",
14 | " * [an interactive version of the same example (using *plotly*)](example_2_eye_movements_interactive.ipynb)\n",
15 | " * [an interactive version of the same example (using *matplotlib*)](example_2_eye_movements_interactive_matplotlib.ipynb)\n",
16 | "* [Example 3 (Using bisection to find a neuron's voltage threshold)](example_3_bisection.ipynb)\n",
17 | "* [Example 4 (neural pitch processing with audio input)](example_4_microphone.ipynb)\n",
18 | "\n",
19 | "\n",
20 | "* [Appendix: multicompartmental model](example_appendix_multicompartment_model.ipynb)\n",
21 | "* [Appendix: parameter exploration](example_appendix_parameter_exploration.ipynb)"
22 | ]
23 | }
24 | ],
25 | "metadata": {
26 | "kernelspec": {
27 | "display_name": "Python 3",
28 | "language": "python",
29 | "name": "python3"
30 | },
31 | "language_info": {
32 | "codemirror_mode": {
33 | "name": "ipython",
34 | "version": 3
35 | },
36 | "file_extension": ".py",
37 | "mimetype": "text/x-python",
38 | "name": "python",
39 | "nbconvert_exporter": "python",
40 | "pygments_lexer": "ipython3",
41 | "version": "3.6.7"
42 | }
43 | },
44 | "nbformat": 4,
45 | "nbformat_minor": 2
46 | }
47 |
--------------------------------------------------------------------------------
/scale_flute.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brian-team/brian2_paper_examples/73045cd61322e923e96883dc97c0848154f79f8c/scale_flute.wav
--------------------------------------------------------------------------------
/sound_from_file.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #define CHECK(x) { if(!(x)) { \
8 | fprintf(stderr, "%s:%i: failure at: %s\n", __FILE__, __LINE__, #x); \
9 | _exit(1); } }
10 |
11 | int numChannels;
12 | int sampleRate;
13 | int bytesPerSample, bitsPerSample;
14 |
15 | std::string freadStr(FILE* f, size_t len) {
16 | std::string s(len, '\0');
17 | CHECK(fread(&s[0], 1, len, f) == len);
18 | return s;
19 | }
20 |
21 | template
22 | T freadNum(FILE* f) {
23 | T value;
24 | CHECK(fread(&value, sizeof(value), 1, f) == 1);
25 | return value; // no endian-swap for now... WAV is LE anyway...
26 | }
27 |
28 | void readFmtChunk(FILE *wavfile, uint32_t chunkLen) {
29 | CHECK(chunkLen >= 16);
30 | uint16_t fmttag = freadNum(wavfile);
31 | CHECK(fmttag == 1 /*PCM*/);
32 | numChannels = freadNum(wavfile);
33 | CHECK(numChannels == 2);
34 | sampleRate = freadNum(wavfile);
35 | CHECK(sampleRate == 44100);
36 | uint32_t byteRate = freadNum(wavfile);
37 | uint16_t blockAlign = freadNum(wavfile);
38 | bitsPerSample = freadNum(wavfile);
39 | bytesPerSample = bitsPerSample / 8;
40 | CHECK(byteRate == sampleRate * numChannels * bytesPerSample);
41 | CHECK(blockAlign == numChannels * bytesPerSample);
42 | CHECK(bitsPerSample == 16);
43 | if(chunkLen > 16) {
44 | uint16_t extendedSize = freadNum(wavfile);
45 | CHECK(chunkLen == 18 + extendedSize);
46 | fseek(wavfile, extendedSize, SEEK_CUR);
47 | }
48 | }
49 |
50 | void readHeader(FILE *wavfile) {
51 | CHECK(freadStr(wavfile, 4) == "RIFF");
52 | uint32_t wavechunksize = freadNum(wavfile);
53 | CHECK(freadStr(wavfile, 4) == "WAVE");
54 | while(true) {
55 | std::string chunkName = freadStr(wavfile, 4);
56 | uint32_t chunkLen = freadNum(wavfile);
57 | if(chunkName == "fmt ")
58 | readFmtChunk(wavfile, chunkLen);
59 | else if(chunkName == "data") {
60 | CHECK(sampleRate != 0);
61 | CHECK(numChannels > 0);
62 | CHECK(bytesPerSample > 0);
63 | printf("bytesPerSample: %d\n", bytesPerSample);
64 | printf("len: %.2f secs\n", double(chunkLen) / sampleRate / numChannels / bytesPerSample);
65 | break; // start playing now
66 | } else {
67 | // skip chunk
68 | CHECK(fseek(wavfile, chunkLen, SEEK_CUR) == 0);
69 | }
70 | }
71 | }
72 |
73 | FILE *init_file() {
74 | FILE *wavfile = fopen(FILENAME, "r"); // will be replaced via macro
75 | readHeader(wavfile);
76 | return wavfile;
77 | }
78 |
79 | float get_sample(const double t) {
80 | static FILE *wavfile = init_file();
81 | static int16_t samples[2];
82 | if (fread(samples, bytesPerSample * numChannels, 1, wavfile) == 0) {
83 | // end of file
84 | return 0.0;
85 | }
86 | return samples[0]*1.0/32767;
87 | }
88 |
--------------------------------------------------------------------------------
/sound_from_mic.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | PaStream *_init_stream()
10 | {
11 | PaStream* stream;
12 | PaError err;
13 |
14 | err = Pa_Initialize();
15 | if (err != paNoError)
16 | {
17 | std::cerr << "Initializing PortAudio failed with error: " << Pa_GetErrorText(err) << std::endl;
18 | exit(err);
19 | }
20 |
21 | err = Pa_OpenDefaultStream(&stream, 1, 0, paFloat32, SAMPLE_RATE, BUFFER_SIZE, NULL, NULL);
22 | if (err != paNoError)
23 | {
24 | std::cerr << "Opening the default input stream failed with error: " << Pa_GetErrorText(err) << std::endl;
25 | exit(err);
26 | }
27 |
28 | err = Pa_StartStream(stream);
29 | if (err != paNoError)
30 | {
31 | std::cerr << "Starting the stream failed with error: " << Pa_GetErrorText(err) << std::endl;
32 | exit(err);
33 | }
34 |
35 | return stream;
36 | }
37 |
38 | float get_sample(const double t)
39 | {
40 | static PaStream* stream = _init_stream();
41 | static float buffer[BUFFER_SIZE];
42 | static int next_sample = BUFFER_SIZE;
43 |
44 | if (next_sample >= BUFFER_SIZE)
45 | {
46 | Pa_ReadStream(stream, buffer, BUFFER_SIZE);
47 | next_sample = 0;
48 | }
49 | return buffer[next_sample++];
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/sound_input.h:
--------------------------------------------------------------------------------
1 | float get_sample(const double);
2 |
--------------------------------------------------------------------------------
/tc200.CNG.swc:
--------------------------------------------------------------------------------
1 | # Original file tc200.swc edited by Duncan Donohue using SWCfix version 1.21 on 12/6/05.
2 | # Errors and fixes documented in tc200.swc.std. See SWCfix1.21.doc for more information.
3 | #
4 | # ORIGINAL_SOURCE
5 | # CREATURE
6 | # REGION
7 | # FIELD/LAYER
8 | # TYPE
9 | # CONTRIBUTOR
10 | # REFERENCE
11 | # RAW
12 | # EXTRAS
13 | # SOMA_AREA
14 | # SHRINKAGE_CORRECTION
15 | # VERSION_NUMBER
16 | # VERSION_DATE
17 | # *********************************************
18 | # SCALE 1.0 1.0 1.0
19 | 1 1 -13.8 -3.059 -24.01 14.43 -1
20 | 2 3 -13.5 0. -38.5 0.70 1
21 | 3 3 -22.5 0.5 -33.5 0.4 2
22 | 4 3 -30. -1.5 -33.5 0.4 3
23 | 5 3 -36.5 -2. -33.5 0.4 4
24 | 6 3 -41. -2. -33.5 0.4 5
25 | 7 3 -47. -2. -28. 0.4 6
26 | 8 3 -53. -1. -21. 0.4 7
27 | 9 3 -60.5 1.5 -14.5 0.4 8
28 | 10 3 -66.5 2.5 -13. 0.4 9
29 | 11 3 -72.5 1. -13.5 0.4 10
30 | 12 3 -78.5 1.5 -13.5 0.4 11
31 | 13 3 -85.5 2. -12.5 0.4 12
32 | 14 3 -92.5 2. -11. 0.4 13
33 | 15 3 -99.5 3. -9.5 0.4 14
34 | 16 3 -106. 3.5 -8.5 0.4 15
35 | 17 3 -111. 5. -7.5 0.4 16
36 | 18 3 -113.5 6.5 -7. 0.4 17
37 | 19 3 -70. -1. -16. 0.4 11
38 | 20 3 -69. -3. -17.5 0.4 19
39 | 21 3 -70. -5.5 -20.5 0.4 20
40 | 22 3 -72.5 -8. -22. 0.4 21
41 | 23 3 -77.5 -10.5 -24. 0.4 22
42 | 24 3 -83.5 -12. -25.5 0.4 23
43 | 25 3 -89. -14. -25.5 0.4 24
44 | 26 3 -95. -14.5 -25.5 0.4 25
45 | 27 3 -100. -15. -25.5 0.4 26
46 | 28 3 -105. -15. -25.5 0.4 27
47 | 29 3 -109.5 -15.5 -25.5 0.4 28
48 | 30 3 -114. -16. -21. 0.4 29
49 | 31 3 -120. -16. -17.5 0.4 30
50 | 32 3 -125.5 -16.5 -14. 0.4 31
51 | 33 3 -131. -16. -12.5 0.4 32
52 | 34 3 -135.5 -16. -8.5 0.4 33
53 | 35 3 -26. 2.5 -36. 0.55 3
54 | 36 3 -31.5 2. -35.5 0.4 35
55 | 37 3 -38.5 2.5 -34.5 0.4 36
56 | 38 3 -45.5 4. -29. 0.4 37
57 | 39 3 -53.5 5. -24.5 0.4 38
58 | 40 3 -61.5 5.5 -20. 0.4 39
59 | 41 3 -67. 9. -21.5 0.4 40
60 | 42 3 -72.5 11.5 -22.5 0.4 41
61 | 43 3 -78.5 14. -22.5 0.4 42
62 | 44 3 -84. 14. -22.5 0.4 43
63 | 45 3 -90. 12. -22.5 0.4 44
64 | 46 3 -95. 9. -22.5 0.4 45
65 | 47 3 -101. 7. -20.5 0.4 46
66 | 48 3 -107. 4. -19. 0.4 47
67 | 49 3 -114. 0. -20. 0.4 48
68 | 50 3 -121. -5.5 -25.5 0.4 49
69 | 51 3 -61. 9. -21. 0.4 40
70 | 52 3 -63.5 13. -17.5 0.4 51
71 | 53 3 -69.5 16.5 -11.5 0.4 52
72 | 54 3 -75.5 20.5 -10. 0.4 53
73 | 55 3 -79. 22.5 -10. 0.4 54
74 | 56 3 -79. 25. -9. 0.4 55
75 | 57 3 -78. 26.5 -4.5 0.4 56
76 | 58 3 -77. 28. 0. 0.4 57
77 | 59 3 -76.5 29.5 3.5 0.4 58
78 | 60 3 -32. 8.5 -29. 0.4 35
79 | 61 3 -38. 15. -24.5 0.4 60
80 | 62 3 -45.5 22. -22.5 0.4 61
81 | 63 3 -52. 27.5 -20. 0.4 62
82 | 64 3 -58.5 33.5 -17. 0.4 63
83 | 65 3 -63. 40. -15. 0.4 64
84 | 66 3 -68.5 47.5 -13.5 0.4 65
85 | 67 1 -9.75 -1.5110 -21.67 14.16 1
86 | 68 1 -3.45 0.795 -15.44 11.89 67
87 | 69 3 -4.8 1.088 -17.57 2.550 68
88 | 70 3 -2.80 10.59 -8.066 2.550 69
89 | 71 3 -2.6 10.59 -8.066 2.550 70
90 | 72 3 -2.5 10.59 -8.066 2.550 71
91 | 73 3 -2.4 10.59 -8.066 2.550 72
92 | 74 3 -2.30 10.59 -8.066 2.550 73
93 | 75 3 -5.8 11.59 1.934 0.45 74
94 | 76 3 -8.3 14.59 8.9340 0.45 75
95 | 77 3 -9.3 19.09 12.93 0.45 76
96 | 78 3 -9.8 25.59 15.93 0.45 77
97 | 79 3 -12.8 30.59 19.43 0.45 78
98 | 80 3 -15.8 35.09 22.43 0.45 79
99 | 81 3 -18.8 37.09 25.93 0.45 80
100 | 82 3 -19.3 38.59 28.93 0.45 81
101 | 83 3 -18.8 40.59 32.43 0.45 82
102 | 84 3 -15.8 43.59 37.43 0.45 83
103 | 85 3 -12.3 46.09 40.93 0.45 84
104 | 86 3 -9.8 49.59 43.93 0.45 85
105 | 87 3 -10.3 54.59 47.93 0.45 86
106 | 88 3 -11.8 62.09 51.43 0.45 87
107 | 89 3 -13.8 70.09 53.93 0.45 88
108 | 90 3 -6.3 14.59 -7.066 1.40 74
109 | 91 3 -10.3 19.09 -7.066 1.40 90
110 | 92 3 -14.8 24.59 -7.066 1.40 91
111 | 93 3 -19.3 26.09 -8.066 1. 92
112 | 94 3 -25.3 29.09 -9.066 0.43 93
113 | 95 3 -35.80 33.09 -10.07 0.43 94
114 | 96 3 -47.80 37.09 -11.07 0.43 95
115 | 97 3 -59.80 40.09 -12.57 0.43 96
116 | 98 3 -68.8 40.59 -14.57 0.43 97
117 | 99 3 -78.3 38.59 -17.57 0.43 98
118 | 100 3 -17.8 28.09 -9.066 0.420 93
119 | 101 3 -17.3 32.09 -5.566 0.420 100
120 | 102 3 -17.8 38.09 0.434 0.420 101
121 | 103 3 -19.3 45.59 6.934 0.420 102
122 | 104 3 -23.3 55.09 8.9340 0.420 103
123 | 105 3 -28.8 66.09 8.4340 0.420 104
124 | 106 3 -36.80 77.59 10.43 0.420 105
125 | 107 3 -42.30 90.09 13.43 0.420 106
126 | 108 3 -46.30 103.60 17.93 0.420 107
127 | 109 3 -13.3 28.59 -18.07 0.55 92
128 | 110 3 -14.3 35.09 -26.57 0.55 109
129 | 111 3 -18.8 44.09 -32.07 0.55 110
130 | 112 3 -22.8 46.09 -43.07 0.4 111
131 | 113 3 -29.3 50.09 -48.07 0.4 112
132 | 114 3 -34.80 55.59 -54.07 0.4 113
133 | 115 3 -38.80 62.59 -58.07 0.4 114
134 | 116 3 -42.30 70.59 -60.07 0.4 115
135 | 117 3 -25.3 51.59 -44.07 0.4 112
136 | 118 3 -27.8 57.09 -47.57 0.4 117
137 | 119 3 -29.8 61.59 -56.07 0.4 118
138 | 120 3 -33.3 65.09 -67.070 0.4 119
139 | 121 3 -17.8 48.09 -31.57 0.4 111
140 | 122 3 -16.3 53.59 -29.07 0.4 121
141 | 123 3 -16.3 59.59 -29.07 0.4 122
142 | 124 3 -15.8 65.09 -27.57 0.4 123
143 | 125 3 -15.3 70.09 -29.07 0.4 124
144 | 126 3 -12.8 75.09 -27.07 0.4 125
145 | 127 3 -11.3 80.09 -28.57 0.4 126
146 | 128 3 -9.3 85.09 -29.57 0.4 127
147 | 129 3 -8.3 91.09 -31.07 0.4 128
148 | 130 3 -4.3 15.59 -6.066 0.4 73
149 | 131 3 -5.8 20.59 -3.0660 0.4 130
150 | 132 3 -7.3 25.09 0.934 0.4 131
151 | 133 3 -7.3 29.59 4.434 0.4 132
152 | 134 3 -6.8 34.09 8.9340 0.4 133
153 | 135 3 -5.3 37.59 12.43 0.4 134
154 | 136 3 -3.80 42.09 13.43 0.4 135
155 | 137 3 0.2 47.59 15.43 0.4 136
156 | 138 3 4.7 52.59 17.93 0.4 137
157 | 139 3 9.20 55.09 22.43 0.4 138
158 | 140 3 12.20 55.59 27.43 0.4 139
159 | 141 3 14.70 56.59 31.93 0.4 140
160 | 142 3 15.70 59.09 36.43 0.4 141
161 | 143 3 16.2 62.09 39.43 0.4 142
162 | 144 3 17.7 65.59 41.43 0.4 143
163 | 145 3 21.7 69.09 43.43 0.4 144
164 | 146 3 -3.80 16.09 -10.57 0.5 72
165 | 147 3 -4.3 21.09 -12.07 0.5 146
166 | 148 3 -4.3 26.09 -12.57 0.5 147
167 | 149 3 -3.80 31.09 -13.57 0.5 148
168 | 150 3 -1.8 15.59 -7.066 0.470 71
169 | 151 3 1.2 21.09 -9.066 0.470 150
170 | 152 3 5.2 27.59 -13.57 0.470 151
171 | 153 3 4.2 34.09 -14.07 0.4 152
172 | 154 3 4.2 41.09 -15.57 0.4 153
173 | 155 3 4.2 47.09 -17.07 0.4 154
174 | 156 3 3.7 51.59 -16.07 0.4 155
175 | 157 3 1.7 54.09 -13.57 0.4 156
176 | 158 3 9.70 31.59 -16.07 0.4 152
177 | 159 3 14.20 35.59 -17.57 0.4 158
178 | 160 3 20.2 39.09 -17.57 0.4 159
179 | 161 3 25.2 40.59 -17.57 0.4 160
180 | 162 3 30.2 42.09 -17.57 0.4 161
181 | 163 3 34.2 42.59 -14.07 0.4 162
182 | 164 3 38.7 43.09 -10.57 0.4 163
183 | 165 3 43.7 45.09 -6.566 0.4 164
184 | 166 3 48.7 49.59 -5.566 0.4 165
185 | 167 3 0.70 13.09 -7.066 1.3 70
186 | 168 3 3.2 17.09 -7.066 1.3 167
187 | 169 3 4.7 21.59 -7.066 1.3 168
188 | 170 3 9.20 23.09 -7.066 0.4 169
189 | 171 3 15.20 25.59 -6.566 0.4 170
190 | 172 3 21.7 28.09 -6.566 0.4 171
191 | 173 3 28.2 31.09 -6.566 0.4 172
192 | 174 3 36.2 33.09 -6.566 0.4 173
193 | 175 3 42.7 35.59 -8.066 0.4 174
194 | 176 3 49.2 38.59 -10.07 0.4 175
195 | 177 3 54.2 43.09 -14.07 0.4 176
196 | 178 3 59.7 49.59 -17.57 0.4 177
197 | 179 3 8.70 28.09 4.934 1. 169
198 | 180 3 8.8 28.09 4.934 0.950 179
199 | 181 3 9. 28.09 4.934 0.950 180
200 | 182 3 7.2 30.09 19.43 0.4 181
201 | 183 3 6.7 32.09 27.43 0.4 182
202 | 184 3 5.7 29.59 7.934 0.4 181
203 | 185 3 1.7 32.59 8.9340 0.4 184
204 | 186 3 -1.3 36.09 10.43 0.4 185
205 | 187 3 -3.30 41.09 12.93 0.4 186
206 | 188 3 -2.30 47.59 17.43 0.4 187
207 | 189 3 -0.3 52.09 22.43 0.4 188
208 | 190 3 2.2 55.59 27.43 0.4 189
209 | 191 3 4.2 56.59 30.93 0.4 190
210 | 192 3 5.7 58.09 33.93 0.4 191
211 | 193 3 6.7 59.59 36.93 0.4 192
212 | 194 3 8.2 31.59 7.934 0.4 184
213 | 195 3 10.20 35.09 11.93 0.4 194
214 | 196 3 14.70 39.09 13.93 0.4 195
215 | 197 3 21.7 41.59 14.93 0.4 196
216 | 198 3 27.2 45.59 14.43 0.4 197
217 | 199 3 31.7 49.59 14.43 0.4 198
218 | 200 3 35.2 52.59 14.93 0.4 199
219 | 201 3 38.7 54.59 15.43 0.4 200
220 | 202 3 42.2 56.09 17.93 0.4 201
221 | 203 3 46.2 58.59 20.93 0.4 202
222 | 204 3 50.7 62.09 25.93 0.4 203
223 | 205 3 9.70 32.09 7.434 0.4 194
224 | 206 3 13.20 35.59 9.9340 0.4 205
225 | 207 3 18.7 39.09 12.93 0.4 206
226 | 208 3 24.7 43.09 15.93 0.4 207
227 | 209 3 31.2 48.09 16.93 0.4 208
228 | 210 3 38.2 52.59 16.93 0.4 209
229 | 211 3 45.7 56.09 17.93 0.4 210
230 | 212 3 12.20 28.09 8.9340 0.5 180
231 | 213 3 17.7 28.09 12.93 0.5 212
232 | 214 3 22.2 27.09 4.934 0.4150 213
233 | 215 3 25.2 23.59 1.934 0.4 214
234 | 216 3 31.2 21.59 -0.5660 0.4 215
235 | 217 3 37.7 21.59 1.434 0.4 216
236 | 218 3 43.7 23.59 2.434 0.4 217
237 | 219 3 50.2 24.09 5.934 0.4 218
238 | 220 3 57.2 24.09 7.434 0.4 219
239 | 221 3 64.7 22.59 10.43 0.4 220
240 | 222 3 26.7 29.09 7.934 0.4 214
241 | 223 3 33.7 31.59 7.434 0.4 222
242 | 224 3 41.2 34.09 2.934 0.4 223
243 | 225 3 49.7 36.59 2.434 0.4 224
244 | 226 3 55.2 39.59 -0.0659 0.4 225
245 | 227 3 59.7 42.59 -3.0660 0.4 226
246 | 228 3 19.7 30.09 11.93 0.4150 213
247 | 229 3 22.7 32.59 10.43 0.4150 228
248 | 230 3 26.7 35.09 8.9340 0.4150 229
249 | 231 3 26.8 35.09 8.9340 0.4150 230
250 | 232 3 31.2 36.09 8.9340 0.4 231
251 | 233 3 35.7 38.09 10.43 0.4 232
252 | 234 3 40.2 41.59 10.43 0.4 233
253 | 235 3 43.7 45.09 8.9340 0.4 234
254 | 236 3 46.2 49.59 6.434 0.4 235
255 | 237 3 48.2 55.09 6.434 0.4 236
256 | 238 3 51.2 62.09 10.43 0.4 237
257 | 239 3 52.7 69.09 11.43 0.4 238
258 | 240 3 55.2 76.09 15.43 0.4 239
259 | 241 3 57.2 81.09 16.93 0.4 240
260 | 242 3 61.7 85.59 22.43 0.4 241
261 | 243 3 66.2 88.59 23.43 0.4 242
262 | 244 3 30.7 37.59 13.43 0.4 231
263 | 245 3 34.7 40.09 14.93 0.4 244
264 | 246 3 39.2 42.59 15.43 0.4 245
265 | 247 3 45.7 44.09 15.43 0.4 246
266 | 248 3 52.7 45.09 15.93 0.4 247
267 | 249 3 58.7 45.09 15.43 0.4 248
268 | 250 3 63.7 44.59 15.43 0.4 249
269 | 251 3 69.2 46.09 14.43 0.4 250
270 | 252 3 75.7 50.09 12.93 0.4 251
271 | 253 3 28.2 38.59 10.43 0.4 230
272 | 254 3 30.7 42.59 11.93 0.4 253
273 | 255 3 34.7 46.59 12.93 0.4 254
274 | 256 3 38.2 51.09 13.93 0.4 255
275 | 257 3 41.7 55.59 15.93 0.4 256
276 | 258 3 44.2 62.59 18.93 0.4 257
277 | 259 3 47.2 67.59 22.43 0.4 258
278 | 260 3 50.2 72.09 26.93 0.4 259
279 | 261 3 53.2 74.59 30.93 0.4 260
280 | 262 3 56.2 77.59 33.93 0.4 261
281 | 263 3 59.2 81.09 34.93 0.4 262
282 | 264 3 62.7 84.59 34.93 0.4 263
283 | 265 3 66.2 89.09 33.93 0.4 264
284 | 266 3 9.70 29.09 -3.0660 0.70 179
285 | 267 3 15.20 31.59 -3.5660 0.4 266
286 | 268 3 21.7 34.09 -5.066 0.4 267
287 | 269 3 29.7 37.59 -6.566 0.4 268
288 | 270 3 35.7 41.09 -7.066 0.4 269
289 | 271 3 40.7 45.09 -7.066 0.4 270
290 | 272 3 42.7 49.09 -7.066 0.4 271
291 | 273 3 42.7 52.59 -7.066 0.4 272
292 | 274 3 12.70 35.09 -7.066 0.4 266
293 | 275 3 16.2 41.09 -13.57 0.4 274
294 | 276 3 17.2 44.59 -24.07 0.4 275
295 | 277 3 15.70 45.59 -33.57 0.4 276
296 | 278 3 2.7 24.09 -5.066 0.4 168
297 | 279 3 0.70 28.09 -3.5660 0.4 278
298 | 280 3 -3.30 32.59 -4.566 0.4 279
299 | 281 3 -7.8 37.59 -5.066 0.4 280
300 | 282 3 -13.3 41.59 -8.566 0.4 281
301 | 283 3 -19.3 45.59 -12.07 0.4 282
302 | 284 3 -26.3 48.09 -13.57 0.4 283
303 | 285 3 -33.8 50.09 -12.07 0.4 284
304 | 286 1 -0.75 1.875 -11.42 7.692 68
305 | 287 3 -1.5 3. -5. 0.480 286
306 | 288 3 -1. 2.5 16. 0.480 287
307 | 289 3 -1. 1.5 38. 0.480 288
308 | 290 3 -1. 0. 52.5 0.480 289
309 | 291 3 -2. -2. 63.5 0.480 290
310 | 292 3 -3. -3.5 65. 0.480 291
311 | 293 3 -5. -5. 65. 0.480 292
312 | 294 3 -7.5 -4.5 65. 0.480 293
313 | 295 3 -9.5 -3. 63. 0.480 294
314 | 296 3 -10. 0. 56.5 0.480 295
315 | 297 3 -9. 2.5 50. 0.480 296
316 | 298 3 -7. 4.5 45. 0.480 297
317 | 299 3 -5. 5.5 42. 0.480 298
318 | 300 3 -4.5 7. 39. 0.480 299
319 | 301 3 -6.5 7.5 36. 0.480 300
320 | 302 3 -9. 8.5 36. 0.480 301
321 | 303 3 -10. 10. 36. 0.480 302
322 | 304 3 -9.5 12. 36. 0.480 303
323 | 305 3 -8. 13. 36. 0.480 304
324 | 306 3 -6. 13.5 40. 0.480 305
325 | 307 3 -4.5 14. 44.5 0.480 306
326 | 308 3 -4.5 15. 48. 0.480 307
327 | 309 3 -5. 16. 47. 0.480 308
328 | 310 3 -7. 17. 46. 0.480 309
329 | 311 3 -7.5 18. 47.5 0.480 310
330 | 312 3 -7.5 19. 49.5 0.480 311
331 | 313 3 -7. 20.5 53.5 0.480 312
332 | 314 3 -6.5 22. 55. 0.480 313
333 | 315 3 -6.5 23.5 57.5 0.480 314
334 | 316 3 -6.5 25. 59.5 0.480 315
335 | 317 3 -7. 27. 67.5 0.480 316
336 | 318 3 -9. 27.5 71. 0.480 317
337 | 319 3 -10. 29.5 75.5 0.480 318
338 | 320 3 -10. 32. 77. 0.480 319
339 | 321 1 1.5 3. -9. 1.85 286
340 | 322 3 7. -3. -5. 1.40 321
341 | 323 3 7.5 -4. 2.5 1.40 322
342 | 324 3 9. -6. 7.5 1.40 323
343 | 325 3 11. -8. 10.5 0.65 324
344 | 326 3 14. -8. 11. 0.65 325
345 | 327 3 17. -7.5 12.5 0.65 326
346 | 328 3 20.5 -6.5 14. 0.65 327
347 | 329 3 23.5 -4.5 13.5 0.65 328
348 | 330 3 27. -2.5 13. 0.65 329
349 | 331 3 27.1 -2.5 13. 1.1 330
350 | 332 3 29.5 -4. 15. 0.480 331
351 | 333 3 33. -5.5 18. 0.480 332
352 | 334 3 36.5 -8. 21.5 0.480 333
353 | 335 3 40. -9.5 23. 0.480 334
354 | 336 3 43. -9.5 24. 0.480 335
355 | 337 3 46.5 -7.5 24. 0.480 336
356 | 338 3 49.5 -6. 24. 0.480 337
357 | 339 3 53. -4.5 24. 0.480 338
358 | 340 3 56.5 -4. 25. 0.480 339
359 | 341 3 28. 0. 14.5 0.465 331
360 | 342 3 29.5 2. 15.5 0.465 341
361 | 343 3 31.5 4.5 15.5 0.465 342
362 | 344 3 33.5 7. 19. 0.465 343
363 | 345 3 35. 9.5 23. 0.465 344
364 | 346 3 37. 11. 29.5 0.465 345
365 | 347 3 39. 12.5 33.5 0.465 346
366 | 348 3 41.5 13.5 39. 0.465 347
367 | 349 3 44.5 15. 45. 0.465 348
368 | 350 3 47. 15.5 51.5 0.465 349
369 | 351 3 50. 16.5 55. 0.465 350
370 | 352 3 53. 18. 56. 0.465 351
371 | 353 3 55.5 19. 56. 0.465 352
372 | 354 3 57.5 20.5 56. 0.465 353
373 | 355 3 59. 22. 56. 0.465 354
374 | 356 3 60.5 22. 57. 0.465 355
375 | 357 3 63.5 21. 60.5 0.465 356
376 | 358 3 67. 20. 66.5 0.465 357
377 | 359 3 29. -0.5 11. 0.470 330
378 | 360 3 31.5 1. 10.5 0.470 359
379 | 361 3 34. 4. 10.5 0.470 360
380 | 362 3 37. 6.5 12. 0.470 361
381 | 363 3 39.5 8.5 15.5 0.470 362
382 | 364 3 42.5 10. 18.5 0.470 363
383 | 365 3 45. 11. 21.5 0.470 364
384 | 366 3 47.5 11.5 23.5 0.470 365
385 | 367 3 50. 11.5 27. 0.470 366
386 | 368 3 53. 12.5 30.5 0.470 367
387 | 369 3 57. 14. 33. 0.470 368
388 | 370 3 61. 15.5 35. 0.470 369
389 | 371 3 65.5 17. 38.5 0.470 370
390 | 372 3 69. 17.5 42. 0.470 371
391 | 373 3 72. 17.5 45. 0.470 372
392 | 374 3 75.5 17. 47. 0.4 373
393 | 375 3 79.5 17. 49. 0.4 374
394 | 376 3 83. 16.5 50.5 0.4 375
395 | 377 3 87. 16.5 50.5 0.4 376
396 | 378 3 91.5 16. 50.5 0.4 377
397 | 379 3 96. 17. 53.5 0.4 378
398 | 380 3 100. 19. 60. 0.4 379
399 | 381 3 74.5 18.5 38. 0.4 373
400 | 382 3 77. 20. 34.5 0.4 381
401 | 383 3 81. 21.5 34.5 0.4 382
402 | 384 3 86.5 24.5 34.5 0.4 383
403 | 385 3 12. -10. 10.5 0.6 325
404 | 386 3 15. -11. 14. 0.6 385
405 | 387 3 17.5 -12. 19.5 0.6 386
406 | 388 3 18.5 -14. 23.5 0.6 387
407 | 389 3 18. -16.5 26.5 0.6 388
408 | 390 3 17. -19. 30.5 0.6 389
409 | 391 3 14. -20. 31.5 0.465 390
410 | 392 3 12. -22. 35. 0.465 391
411 | 393 3 11.5 -24.5 40.5 0.465 392
412 | 394 3 12.5 -27.5 42.5 0.465 393
413 | 395 3 15. -29.5 41. 0.465 394
414 | 396 3 18. -21. 28. 0.46 390
415 | 397 3 19.5 -23.5 26.5 0.46 396
416 | 398 3 21. -24.5 23.5 0.46 397
417 | 399 3 23. -24. 22. 0.46 398
418 | 400 3 25.5 -22.5 22. 0.46 399
419 | 401 3 27.5 -21.5 27. 0.46 400
420 | 402 3 30. -21.5 34.5 0.46 401
421 | 403 3 31.5 -20. 39.5 0.455 402
422 | 404 3 33. -19.5 45. 0.455 403
423 | 405 3 34.5 -20. 50.5 0.455 404
424 | 406 3 35. -19. 58. 0.455 405
425 | 407 3 36.5 -18. 63. 0.455 406
426 | 408 3 37.5 -15. 66.5 0.455 407
427 | 409 3 40. -13. 68. 0.455 408
428 | 410 3 42.5 -10.5 72. 0.455 409
429 | 411 3 32.5 -22. 36. 0.455 402
430 | 412 3 35. -23. 37. 0.455 411
431 | 413 1 1.5 8. -1.5 0.8 321
432 | 414 3 1.7 10.59 -6.066 0.4 413
433 | 415 3 6.7 12.09 -4.066 0.4 414
434 | 416 3 11.70 14.59 -5.566 0.4 415
435 | 417 3 16.7 17.59 -8.066 0.4 416
436 | 418 3 21.2 20.09 -11.57 0.4 417
437 | 419 3 26.2 22.59 -10.57 0.4 418
438 | 420 3 30.7 26.09 -14.57 0.4 419
439 | 421 3 35.7 30.09 -23.07 0.4 420
440 | 422 3 11.5 9. -2.5 0.470 413
441 | 423 3 12. 11. -3.5 0.850 422
442 | 424 3 12.5 15.5 -1.5 0.850 423
443 | 425 3 15. 9. -2.5 0.470 422
444 | 426 3 19.5 8. -2.5 0.470 425
445 | 427 3 23. 8. -2.5 0.470 426
446 | 428 3 25.5 9.5 -2.5 0.470 427
447 | 429 3 30.5 11.5 -2.5 0.470 428
448 | 430 3 35. 13. -2.5 0.470 429
449 | 431 3 40.5 18.5 -2.5 0.470 430
450 | 432 3 45. 21.5 -2.5 0.470 431
451 | 433 3 53.5 23. -2.5 0.470 432
452 | 434 3 5.5 9.5 -13. 2. 413
453 | 435 3 12. 16.5 -18.5 2. 434
454 | 436 3 14.5 14. -19. 0.4 435
455 | 437 3 18.5 12. -19.5 0.4 436
456 | 438 3 23. 10.5 -19. 0.4 437
457 | 439 3 28. 9. -16. 0.4 438
458 | 440 3 32. 8. -13. 0.4 439
459 | 441 3 36.5 6. -10. 0.4 440
460 | 442 3 41. 5. -13. 0.4 441
461 | 443 3 44.5 3. -16. 0.4 442
462 | 444 3 47.5 1.5 -20. 0.4 443
463 | 445 3 50.5 2. -20. 0.4 444
464 | 446 3 54. 3.5 -25.5 0.4 445
465 | 447 3 57.5 6. -36. 0.4 446
466 | 448 3 11.5 17.5 0. 1.650 435
467 | 449 3 9. 18.5 0. 0.410 448
468 | 450 3 6.5 21.5 0. 0.410 449
469 | 451 3 3.5 26. 0.5 0.410 450
470 | 452 3 1. 32.5 3.5 0.410 451
471 | 453 3 -2. 40.5 9. 0.410 452
472 | 454 3 -0.5 46. 8.5 0.4 453
473 | 455 3 0.5 51. 9. 0.4 454
474 | 456 3 4. 56. 9. 0.4 455
475 | 457 3 7.5 61. 9.5 0.4 456
476 | 458 3 11. 64. 9. 0.4 457
477 | 459 3 13.5 64. 9.5 0.4 458
478 | 460 3 15.5 63.5 10.5 0.4 459
479 | 461 3 -4. 42.5 8.5 0.410 453
480 | 462 3 -7. 44.5 7. 0.410 461
481 | 463 3 -9.5 47.5 7.5 0.410 462
482 | 464 3 -13. 50.5 9.5 0.410 463
483 | 465 3 -15.5 52.5 13. 0.410 464
484 | 466 3 -17. 54. 16.5 0.410 465
485 | 467 3 -16.5 55. 22. 0.410 466
486 | 468 3 -15. 56. 26. 0.410 467
487 | 469 3 -13. 56.5 30.5 0.410 468
488 | 470 3 -10.5 56. 32.5 0.410 469
489 | 471 3 -8. 56. 34.5 0.410 470
490 | 472 3 -6. 57.5 34.5 0.410 471
491 | 473 3 13.5 19. 0. 1.35 448
492 | 474 3 14. 21.5 1.5 0.75 473
493 | 475 3 15. 24. 2.5 0.75 474
494 | 476 3 12.5 25. 2.5 0.4 475
495 | 477 3 11.5 27. 2.5 0.4 476
496 | 478 3 11.5 30. 3. 0.4 477
497 | 479 3 13.5 35. 3.5 0.4 478
498 | 480 3 15.5 40. 4. 0.4 479
499 | 481 3 18. 44. 4. 0.4 480
500 | 482 3 21. 47.5 4. 0.4 481
501 | 483 3 25. 50.5 4. 0.4 482
502 | 484 3 29. 55. 4. 0.4 483
503 | 485 3 33. 59.5 4. 0.4 484
504 | 486 3 36.5 63.5 4. 0.4 485
505 | 487 3 40. 68. 7. 0.4 486
506 | 488 3 43. 72.5 11. 0.4 487
507 | 489 3 46. 76.5 16. 0.4 488
508 | 490 3 47.5 80. 18.5 0.4 489
509 | 491 3 48.5 84.5 21. 0.4 490
510 | 492 3 50.5 88.5 22.5 0.4 491
511 | 493 3 52.5 92. 24. 0.4 492
512 | 494 3 55. 94. 26. 0.4 493
513 | 495 3 56. 97. 27.5 0.4 494
514 | 496 3 57.5 100.5 29. 0.4 495
515 | 497 3 58.5 105. 29. 0.4 496
516 | 498 3 59.5 110. 29. 0.4 497
517 | 499 3 60. 115.5 29. 0.4 498
518 | 500 3 61. 121. 29. 0.4 499
519 | 501 3 15. 26.5 0.5 0.4 475
520 | 502 3 17. 29.5 4.5 0.4 501
521 | 503 3 19. 34. 9. 0.4 502
522 | 504 3 22.5 38.5 13.5 0.4 503
523 | 505 3 24.5 42.5 15.5 0.4 504
524 | 506 3 27.5 44.5 19.5 0.4 505
525 | 507 3 31.5 45. 23.5 0.4 506
526 | 508 3 37.5 44.5 26.5 0.4 507
527 | 509 3 44. 44.5 28.5 0.4 508
528 | 510 3 50. 45. 30.5 0.4 509
529 | 511 3 57.5 45.5 30.5 0.4 510
530 | 512 3 65. 45.5 32. 0.4 511
531 | 513 3 72.5 45. 34. 0.4 512
532 | 514 3 78.5 43.5 36. 0.4 513
533 | 515 3 84. 41.5 36. 0.4 514
534 | 516 3 89. 39. 35.5 0.4 515
535 | 517 3 94.5 37.5 34.5 0.4 516
536 | 518 3 17. 24.5 -2.5 0.8 474
537 | 519 3 19. 29. -3. 0.8 518
538 | 520 3 20. 32.5 -2.5 0.8 519
539 | 521 3 21. 35. -2.5 0.4 520
540 | 522 3 24. 38. -2.5 0.4 521
541 | 523 3 27.5 41. 0. 0.4 522
542 | 524 3 32.5 44. 5. 0.4 523
543 | 525 3 36.5 45.5 4.5 0.4 524
544 | 526 3 42. 48.5 4. 0.4 525
545 | 527 3 47. 52. 4. 0.4 526
546 | 528 3 51. 55. 4. 0.4 527
547 | 529 3 37. 45. 10. 0.4 524
548 | 530 3 40. 46. -1.5 0.4 529
549 | 531 3 42. 47. -30.5 0.4 530
550 | 532 3 25. 35. -1.5 0.4 520
551 | 533 3 30. 38. -1.5 0.4 532
552 | 534 3 35.5 40.5 -2.5 0.4 533
553 | 535 3 41. 42. -2.5 0.4 534
554 | 536 3 48. 43.5 -2.5 0.4 535
555 | 537 3 54.5 45. -3. 0.4 536
556 | 538 3 60.5 48. -3.5 0.4 537
557 | 539 3 65.5 52.5 -5. 0.4 538
558 | 540 3 15.5 19. 0. 1. 473
559 | 541 3 18.5 20. 0. 1. 540
560 | 542 3 24.5 19. 0. 0.8 541
561 | 543 3 24.6 19. 0. 0.70 542
562 | 544 3 25.5 14.5 3. 0.4 543
563 | 545 3 27. 10. 6. 0.4 544
564 | 546 3 28. 6.5 7.5 0.4 545
565 | 547 3 30.5 3.5 9. 0.4 546
566 | 548 3 31.5 1. 9. 0.4 547
567 | 549 3 33. -0.5 9. 0.4 548
568 | 550 3 34.5 -2. 9. 0.4 549
569 | 551 3 39. -2.5 10. 0.4 550
570 | 552 3 45.5 -3. 11.5 0.4 551
571 | 553 3 52.5 -3. 13.5 0.4 552
572 | 554 3 58. -3. 14. 0.4 553
573 | 555 3 64. -4.5 15.5 0.4 554
574 | 556 3 69.5 -6. 17. 0.4 555
575 | 557 3 75.5 -9.5 15.5 0.4 556
576 | 558 3 80. -12.5 13. 0.4 557
577 | 559 3 83.5 -16.5 10.5 0.4 558
578 | 560 3 87.5 -19.5 11. 0.4 559
579 | 561 3 92. -23. 12.5 0.4 560
580 | 562 3 96.5 -26. 15.5 0.4 561
581 | 563 3 99. -29. 15.5 0.4 562
582 | 564 3 99. -32.5 13. 0.4 563
583 | 565 3 28.5 19. 1.5 0.4 543
584 | 566 3 32. 19. 2.5 0.4 565
585 | 567 3 35.5 19. 2.5 0.4 566
586 | 568 3 38. 18. 6. 0.4 567
587 | 569 3 41. 18. 6.5 0.4 568
588 | 570 3 43.5 19. 7.5 0.4 569
589 | 571 3 47. 21. 5. 0.4 570
590 | 572 3 50.5 23. 5. 0.4 571
591 | 573 3 56.5 23.5 6.5 0.4 572
592 | 574 3 63.5 25. 8. 0.4 573
593 | 575 3 70. 26.5 9.5 0.4 574
594 | 576 3 75.5 28.5 7.5 0.4 575
595 | 577 3 80.5 30.5 7. 0.4 576
596 | 578 3 86. 33. 7. 0.4 577
597 | 579 3 91.5 33.5 10.5 0.4 578
598 | 580 3 96. 34.5 12. 0.4 579
599 | 581 3 100.5 35. 14. 0.4 580
600 | 582 3 105. 36.5 13. 0.4 581
601 | 583 3 28. 21. -1. 0.4 542
602 | 584 3 33.5 22.5 -1. 0.4 583
603 | 585 3 39. 24. 0. 0.4 584
604 | 586 3 44. 25. 0. 0.4 585
605 | 587 3 47.5 26.5 0. 0.4 586
606 | 588 3 50.5 26.5 0. 0.4 587
607 | 589 3 55.5 28. 0. 0.4 588
608 | 590 3 63. 28.5 0. 0.4 589
609 | 591 3 70. 30.5 1. 0.4 590
610 | 592 3 77. 32.5 2.5 0.4 591
611 | 593 3 81.5 35.5 7. 0.4 592
612 | 594 3 86.5 39. 10. 0.4 593
613 | 595 3 90.5 42.5 14. 0.4 594
614 | 596 3 92.5 46. 14. 0.4 595
615 | 597 3 93. 50. 13. 0.4 596
616 | 598 3 19. 22.5 0. 0.55 541
617 | 599 3 23. 22.5 0. 0.4 598
618 | 600 3 26. 23.5 -0.5 0.4 599
619 | 601 3 28.5 25.5 -1.5 0.4 600
620 | 602 3 31.5 27. -2.5 0.4 601
621 | 603 3 35. 28.5 -1.5 0.4 602
622 | 604 3 38.5 31. -0.5 0.4 603
623 | 605 3 40.5 34. -1. 0.4 604
624 | 606 3 40. 36.5 -8. 0.4 605
625 | 607 3 39. 38.5 -23. 0.4 606
626 | 608 3 38. 39. -44. 0.4 607
627 | 609 3 22.5 25. 1.5 0.4 598
628 | 610 3 26.5 27.5 2.5 0.4 609
629 | 611 3 30.5 30.5 2.5 0.4 610
630 | 612 3 33.5 32.5 3.5 0.4 611
631 | 613 3 36.5 35.5 4. 0.4 612
632 | 614 3 39.5 39.5 4. 0.4 613
633 | 615 3 43.5 44.5 7. 0.4 614
634 | 616 3 49. 47.5 10. 0.4 615
635 | 617 3 54. 51. 13. 0.4 616
636 | 618 3 60.5 53. 13. 0.4 617
637 | 619 3 64. 57.5 12. 0.4 618
638 | 620 3 67. 63.5 10.5 0.4 619
639 | 621 3 29. 31. 0.5 0.4 611
640 | 622 3 28.5 33. 1.5 0.4 621
641 | 623 3 29.5 36. 3. 0.4 622
642 | 624 3 32.5 38.5 5. 0.4 623
643 | 625 3 37. 42.5 5. 0.4 624
644 | 626 3 41. 45.5 5. 0.4 625
645 | 627 3 45. 49. 5. 0.4 626
646 | 628 3 48. 51.5 6. 0.4 627
647 | 629 3 51.5 53. 7. 0.4 628
648 | 630 3 55.5 54.5 8. 0.4 629
649 | 631 3 59.5 55.5 9.5 0.4 630
650 | 632 3 63.5 56.5 11. 0.4 631
651 | 633 3 67. 58.5 13. 0.4 632
652 | 634 3 70.5 60.5 14. 0.4 633
653 | 635 3 73.5 62.5 15. 0.4 634
654 | 636 3 77.5 65. 16. 0.4 635
655 | 637 3 82.5 67. 16.5 0.4 636
656 | 638 3 87. 68.5 17.5 0.4 637
657 | 639 3 89.5 70. 19. 0.4 638
658 | 640 3 91.5 71.5 21.5 0.4 639
659 | 641 3 93. 73.5 23.5 0.4 640
660 | 642 3 95.5 75. 25. 0.4 641
661 | 643 3 98.5 76.5 27. 0.4 642
662 | 644 3 101.5 79.5 32. 0.4 643
663 | 645 3 4. 9.5 -3.5 0.8 413
664 | 646 3 7.7 9.5 -3.5 2.80 645
665 | 647 3 7.5 14.5 -1. 1.55 646
666 | 648 3 3.5 11.5 -3.5 0.9 645
667 | 649 3 2. 13.5 -1.5 0.9 648
668 | 650 3 0. 13.5 -5. 0.455 321
669 | 651 3 2. 14. -2.5 0.455 650
670 | 652 3 4.5 14.5 0.5 0.455 651
671 | 653 3 6.5 16. 4. 0.455 652
672 | 654 3 8.5 17. 7.5 0.455 653
673 | 655 3 10. 18.5 11. 0.455 654
674 | 656 3 12. 18.5 12.5 0.455 655
675 | 657 3 14. 19. 15. 0.455 656
676 | 658 3 16. 19. 16.5 0.455 657
677 | 659 3 18. 20. 18.5 0.455 658
678 | 660 3 21. 21. 21. 0.455 659
679 | 661 3 24.5 22.5 26.5 0.465 660
680 | 662 3 28. 24. 31.5 0.465 661
681 | 663 3 31. 26. 34.5 0.465 662
682 | 664 3 33.5 29. 36. 0.465 663
683 | 665 3 35.5 32. 36.5 0.465 664
684 | 666 3 38. 34.5 39.5 0.465 665
685 | 667 3 41.5 34.5 42. 0.465 666
686 | 668 3 45. 33.5 48.5 0.465 667
687 | 669 3 48. 33.5 52.5 0.465 668
688 | 670 3 50. 34.5 56.5 0.465 669
689 | 671 3 52.5 35.5 58. 0.465 670
690 | 672 3 55.5 34.5 59.5 0.465 671
691 | 673 3 58.5 34.5 61.5 0.465 672
692 | 674 3 60. 35. 64. 0.465 673
693 | 675 3 59.5 36.5 68. 0.465 674
694 | 676 3 24.5 25. 34. 0.43 661
695 | 677 3 25.5 28. 42. 0.43 676
696 | 678 3 26.5 30.5 47. 0.43 677
697 | 679 3 28.5 33. 50.5 0.43 678
698 | 680 3 31. 35. 51. 0.43 679
699 | 681 3 33.5 37.5 52. 0.43 680
700 | 682 3 36. 41.5 54.5 0.43 681
701 | 683 3 38. 45.5 57. 0.43 682
702 | 684 3 39.5 49.5 59. 0.43 683
703 | 685 3 41. 52.5 60. 0.43 684
704 | 686 3 42. 55.5 63. 0.43 685
705 | 687 3 42.5 58.5 63. 0.43 686
706 | 688 3 42.5 62.5 61. 0.43 687
707 | 689 3 1.5 5.5 0. 0.455 321
708 | 690 3 3.5 8.5 5.5 0.455 689
709 | 691 3 6. 10. 9. 0.455 690
710 | 692 3 9. 9.5 13. 0.455 691
711 | 693 3 12.5 9. 17. 0.455 692
712 | 694 3 15. 9.5 22. 0.455 693
713 | 695 3 17. 11.5 25. 0.455 694
714 | 696 3 18.5 13.5 29. 0.455 695
715 | 697 3 21.5 14.5 35.5 0.455 696
716 | 698 3 24. 16. 41.5 0.455 697
717 | 699 3 26.5 16. 49.5 0.455 698
718 | 700 3 29.5 17. 55. 0.455 699
719 | 701 3 33. 18. 58.5 0.455 700
720 | 702 3 37.5 18.5 61.5 0.455 701
721 | 703 3 42. 18.5 63.5 0.455 702
722 | 704 3 47. 18.5 66.5 0.455 703
723 | 705 3 6. 3.5 -9. 1.85 321
724 | 706 3 7.5 4.5 -10. 1.85 705
725 | 707 3 9.5 5. -10. 0.8 706
726 | 708 3 13.5 8.5 -10. 0.8 707
727 | 709 3 15.5 10. -9.5 0.8 708
728 | 710 3 14. 12. -9.5 0.4 709
729 | 711 3 15.5 14. -9.5 0.4 710
730 | 712 3 15.5 16. -9.5 0.4 711
731 | 713 3 13. 18. -9. 0.4 712
732 | 714 3 12. 18.5 -9. 0.4 713
733 | 715 3 10.5 19.5 -9. 0.4 714
734 | 716 3 8.5 21.5 -9. 0.4 715
735 | 717 3 7. 23.5 -10. 0.4 716
736 | 718 3 14.5 18. -8.5 0.4 713
737 | 719 3 14. 19. -8.5 0.4 718
738 | 720 3 13. 20.5 -8.5 0.4 719
739 | 721 3 11.5 20.5 -8.5 0.4 720
740 | 722 3 17.5 10. -7.5 0.4 709
741 | 723 3 20. 10. -10.5 0.4 722
742 | 724 3 23.5 8.5 -10. 0.4 723
743 | 725 3 30. 7.5 -10. 0.4 724
744 | 726 3 32. 7. -10. 0.4 725
745 | 727 3 32.5 5.5 -9. 0.4 726
746 | 728 3 35. 5.5 -9. 0.4 727
747 | 729 3 37.5 4.5 -10.5 0.4 728
748 | 730 3 40.5 2.5 -10. 0.4 729
749 | 731 3 43. 1.5 -10. 0.4 730
750 | 732 3 46. 4.5 -10.5 0.4 731
751 | 733 3 50. 6. -14.5 0.4 732
752 | 734 3 18. 11.5 -10.5 0.4 723
753 | 735 3 12. 12. -10. 0.4 734
754 | 736 3 8.5 13. -10. 0.4 735
755 | 737 3 6. 16. -10. 0.4 736
756 | 738 3 6. 18. -11.5 0.4 737
757 | 739 3 18. 9.5 -8. 0.4 722
758 | 740 3 21. 9. -8. 0.4 739
759 | 741 3 24. 8. -8. 0.4 740
760 | 742 3 21.5 10. -8. 0.4 741
761 | 743 3 20.5 11. -8. 0.4 742
762 | 744 3 25.5 9.5 -8. 0.4 743
763 | 745 3 30. 8.5 -8. 0.4 744
764 | 746 3 33.5 9. -8. 0.4 745
765 | 747 3 38.5 8.5 -8. 0.4 746
766 | 748 3 44.5 7.5 -8. 0.4 747
767 | 749 3 51. 7.5 -8. 0.4 748
768 | 750 3 56. 5.5 -8. 0.4 749
769 | 751 3 63.5 6. -8. 0.4 750
770 | 752 3 69. 5.5 -7.5 0.4 751
771 | 753 3 75. 7. -7. 0.4 752
772 | 754 3 79.5 8.5 -7. 0.4 753
773 | 755 3 85.5 6.5 -7. 0.4 754
774 | 756 3 88. 4. -7. 0.4 755
775 | 757 3 89. 0.5 -7. 0.4 756
776 | 758 3 0.15 1.56 -10.53 2.15 286
777 | 759 3 3.15 -1.44 -0.03 2.15 758
778 | 760 3 7.15 -4.94 7.97 0.850 759
779 | 761 3 4.65 -7.44 11.47 0.850 760
780 | 762 3 3.15 -9.94 13.97 0.850 761
781 | 763 3 3.15 -13.44 15.97 0.850 762
782 | 764 3 4.15 -16.44 18.47 0.6 763
783 | 765 3 4.15 -19.94 21.97 0.6 764
784 | 766 3 3.15 -23.94 24.97 0.6 765
785 | 767 3 2.15 -27.94 27.47 0.6 766
786 | 768 3 1.650 -32.44 27.97 0.6 767
787 | 769 3 2.15 -36.94 27.97 0.6 768
788 | 770 3 2.15 -40.94 30.970 0.6 769
789 | 771 3 2.15 -43.94 33.97 0.6 770
790 | 772 3 3.15 -46.44 36.47 0.6 771
791 | 773 3 4.15 -49.44 35.47 0.6 772
792 | 774 3 4.65 -52.44 34.47 0.6 773
793 | 775 3 4.15 -55.94 38.97 0.6 774
794 | 776 3 4.15 -59.44 43.47 0.6 775
795 | 777 3 5.65 -62.440 47.97 0.6 776
796 | 778 3 7.15 -66.44 47.97 0.6 777
797 | 779 3 6.65 -69.94 47.97 0.6 778
798 | 780 3 6.65 -72.44 48.97 0.6 779
799 | 781 3 8.65 -74.94 51.97 0.6 780
800 | 782 3 4.65 -13.94 20.97 0.6 763
801 | 783 3 5.65 -14.44 26.97 0.6 782
802 | 784 3 5.15 -15.44 30.970 0.6 783
803 | 785 3 3.65 -16.94 33.47 0.6 784
804 | 786 3 1.650 -18.94 33.47 0.6 785
805 | 787 3 -0.350 -21.44 35.47 0.6 786
806 | 788 3 -1.35 -24.44 39.47 0.6 787
807 | 789 3 -1.85 -26.94 43.97 0.6 788
808 | 790 3 -1.85 -27.44 48.47 0.6 789
809 | 791 3 -2.85 -27.44 50.47 0.6 790
810 | 792 3 -4.350 -27.44 52.47 0.6 791
811 | 793 3 -5.850 -27.44 56.47 0.6 792
812 | 794 3 -7.850 -25.94 61.97 0.6 793
813 | 795 3 -9.35 -22.94 64.97 0.6 794
814 | 796 3 -9.85 -20.44 64.97 0.6 795
815 | 797 3 -8.35 -17.44 63.97 0.6 796
816 | 798 3 -7.350 -14.94 63.47 0.6 797
817 | 799 3 -6.850 -11.94 63.47 0.6 798
818 | 800 3 -5.350 -9.94 63.47 0.6 799
819 | 801 3 -2.35 -7.94 64.47 0.6 800
820 | 802 3 -0.850 -6.44 64.47 0.6 801
821 | 803 3 -1.85 -3.44 64.97 0.6 802
822 | 804 3 -1.35 -0.940 64.97 0.6 803
823 | 805 3 -0.350 2.56 65.47 0.6 804
824 | 806 3 -0.850 4.060 64.97 0.6 805
825 | 807 3 -3.85 6.060 64.47 0.6 806
826 | 808 3 -6.350 7.060 58.97 0.6 807
827 | 809 3 -7.850 10.06 53.97 0.6 808
828 | 810 3 -8.85 14.06 49.97 0.6 809
829 | 811 3 -9.85 17.56 50.97 0.6 810
830 | 812 3 -11.35 21.06 50.47 0.6 811
831 | 813 3 -13.85 22.56 47.97 0.6 812
832 | 814 3 -16.85 24.560 46.97 0.6 813
833 | 815 3 -18.85 27.060 45.47 0.6 814
834 | 816 3 -20.35 30.060 39.97 0.6 815
835 | 817 3 -21.85 33.56 32.47 0.6 816
836 | 818 3 -23.35 36.06 29.47 0.6 817
837 | 819 3 -26.35 39.06 31.470 0.6 818
838 | 820 3 -28.35 43.06 35.97 0.6 819
839 | 821 3 -32.35 46.06 39.97 0.6 820
840 | 822 3 -35.85 48.56 45.47 0.6 821
841 | 823 3 -40.35 50.06 49.97 0.6 822
842 | 824 3 -45.35 51.56 52.47 0.6 823
843 | 825 3 -52.35 53.06 54.47 0.6 824
844 | 826 3 10.15 -6.94 12.97 1.150 760
845 | 827 3 13.15 -9.44 16.47 1.150 826
846 | 828 3 16.15 -11.44 18.47 1.150 827
847 | 829 3 16.25 -11.44 18.47 0.950 828
848 | 830 3 19.150 -13.44 16.47 0.4 829
849 | 831 3 22.650 -14.94 15.97 0.4 830
850 | 832 3 25.650 -16.44 15.97 0.4 831
851 | 833 3 28.150 -17.94 15.97 0.4 832
852 | 834 3 31.150 -20.44 16.47 0.4 833
853 | 835 3 33.65 -22.94 16.97 0.4 834
854 | 836 3 37.15 -25.94 16.47 0.4 835
855 | 837 3 40.65 -27.94 14.47 0.4 836
856 | 838 3 44.65 -29.44 13.47 0.4 837
857 | 839 3 48.65 -31.94 13.47 0.4 838
858 | 840 3 52.15 -35.44 13.97 0.4 839
859 | 841 3 55.15 -40.44 15.97 0.4 840
860 | 842 3 18.650 -9.94 18.47 0.850 829
861 | 843 3 22.150 -8.94 18.47 0.850 842
862 | 844 3 22.25 -8.94 18.47 0.850 843
863 | 845 3 24.150 -6.44 24.47 0.4 844
864 | 846 3 26.650 -4.94 29.47 0.4 845
865 | 847 3 29.650 -3.44 31.470 0.4 846
866 | 848 3 33.65 -2.44 33.47 0.4 847
867 | 849 3 37.65 -0.44 34.47 0.4 848
868 | 850 3 41.65 1.06 37.47 0.4 849
869 | 851 3 45.15 2.56 41.47 0.4 850
870 | 852 3 50.15 2.56 44.97 0.4 851
871 | 853 3 56.15 1.06 47.97 0.4 852
872 | 854 3 25.150 -8.44 23.47 0.445 844
873 | 855 3 29.150 -8.94 33.47 0.445 854
874 | 856 3 33.15 -6.94 30.47 0.4 855
875 | 857 3 37.15 -5.44 29.97 0.4 856
876 | 858 3 42.15 -3.94 30.970 0.4 857
877 | 859 3 47.15 -3.44 31.970 0.4 858
878 | 860 3 51.65 -3.44 31.970 0.4 859
879 | 861 3 54.65 -3.44 30.970 0.4 860
880 | 862 3 57.65 -3.44 29.97 0.4 861
881 | 863 3 60.65 -3.44 30.970 0.4 862
882 | 864 3 63.65 -2.94 34.97 0.4 863
883 | 865 3 66.15 -1.44 41.47 0.4 864
884 | 866 3 68.65 -0.940 44.97 0.4 865
885 | 867 3 72.65 -0.940 43.97 0.4 866
886 | 868 3 30.150 -10.44 34.97 0.4 855
887 | 869 3 31.650 -12.44 37.47 0.4 868
888 | 870 3 34.15 -13.94 40.47 0.4 869
889 | 871 3 36.65 -15.44 42.47 0.4 870
890 | 872 3 39.65 -16.44 43.47 0.4 871
891 | 873 3 42.15 -17.94 45.47 0.4 872
892 | 874 3 44.15 -20.44 47.47 0.4 873
893 | 875 3 46.15 -23.94 49.47 0.4 874
894 | 876 3 49.15 -27.94 49.47 0.4 875
895 | 877 3 25.150 -9.94 20.97 0.4 843
896 | 878 3 27.650 -10.94 25.97 0.4 877
897 | 879 3 29.150 -12.44 31.470 0.4 878
898 | 880 3 30.650 -13.94 33.97 0.4 879
899 | 881 3 33.15 -15.44 35.47 0.4 880
900 | 882 3 38.15 -15.94 38.97 0.4 881
901 | 883 3 43.15 -16.94 41.97 0.4 882
902 | 884 3 47.65 -18.44 46.47 0.4 883
903 | 885 3 50.65 -21.44 51.97 0.4 884
904 | 886 3 53.65 -23.44 57.97 0.4 885
905 | 887 3 56.65 -22.94 61.97 0.4 886
906 | 888 3 60.15 -20.94 65.47 0.4 887
907 | 889 3 63.15 -21.44 66.47 0.4 888
908 | 890 3 66.15 -22.94 66.97 0.4 889
909 | 891 3 66.65 -26.44 65.47 0.4 890
910 | 892 3 66.65 -30.44 65.47 0.4 891
911 | 893 3 15.15 -12.44 18.47 0.950 828
912 | 894 3 15.15 -14.44 18.47 0.950 893
913 | 895 3 17.150 -16.44 17.97 0.4 894
914 | 896 3 18.150 -18.44 18.97 0.4 895
915 | 897 3 19.150 -21.44 21.47 0.4 896
916 | 898 3 24.150 -21.94 27.47 0.4 897
917 | 899 3 26.650 -22.44 33.97 0.4 898
918 | 900 3 26.650 -23.94 42.47 0.4 899
919 | 901 3 28.650 -26.44 49.47 0.4 900
920 | 902 3 28.650 -28.44 53.47 0.4 901
921 | 903 3 28.650 -30.44 56.47 0.4 902
922 | 904 3 27.150 -33.94 62.47 0.4 903
923 | 905 3 18.650 -25.94 23.47 0.4 897
924 | 906 3 19.150 -30.44 25.47 0.4 905
925 | 907 3 19.650 -34.94 27.47 0.4 906
926 | 908 3 21.150 -39.44 29.97 0.4 907
927 | 909 3 23.150 -44.44 34.47 0.4 908
928 | 910 3 15.15 -15.44 18.47 0.4 894
929 | 911 3 16.15 -16.94 19.47 0.4 910
930 | 912 3 16.15 -18.94 20.47 0.4 911
931 | 913 3 16.15 -20.94 23.47 0.4 912
932 | 914 3 15.15 -22.94 25.97 0.4 913
933 | 915 3 16.15 -24.44 29.97 0.4 914
934 | 916 3 16.65 -26.44 32.47 0.4 915
935 | 917 3 17.650 -27.94 34.97 0.4 916
936 | 918 3 17.650 -29.94 40.47 0.4 917
937 | 919 3 18.150 -32.94 45.47 0.4 918
938 | 920 3 17.650 -37.94 49.47 0.4 919
939 | 921 3 12.15 -23.44 32.47 0.420 910
940 | 922 3 10.65 -38.44 49.47 0.420 921
941 | 923 1 -16.05 -4.264 -26.580 13.36 1
942 | 924 1 -16.95 -4.486 -27.55 12.68 923
943 | 925 3 -20.45 -2.986 -27.55 1.150 924
944 | 926 3 -26.45 -3.486 -27.55 0.8 925
945 | 927 3 -32.45 -3.486 -27.05 0.8 926
946 | 928 3 -38.95 -1.486 -26.55 0.8 927
947 | 929 3 -44.95 1.514 -26.05 0.8 928
948 | 930 3 -45.15 1.514 -26.05 1.35 929
949 | 931 3 -52.45 2.5140 -27.05 0.4 930
950 | 932 3 -60.45 4.014 -27.55 0.4 931
951 | 933 3 -66.95 5.514 -27.55 0.4 932
952 | 934 3 -71.45 6.514 -27.55 0.4 933
953 | 935 3 -76.95 3.0140 -27.55 0.4 934
954 | 936 3 -82.95 0.0139 -27.55 0.4 935
955 | 937 3 -89.45 -2.986 -27.55 0.4 936
956 | 938 3 -95.45 -5.486 -27.55 0.4 937
957 | 939 3 -101.5 -8.486 -27.55 0.4 938
958 | 940 3 -109.5 -10.99 -27.55 0.4 939
959 | 941 3 -117.5 -12.49 -27.55 0.4 940
960 | 942 3 -123. -13.49 -27.55 0.4 941
961 | 943 3 -125. -13.49 -27.55 0.4 942
962 | 944 3 -73.45 9.014 -27.55 0.4 934
963 | 945 3 -75.95 12.01 -27.55 0.4 944
964 | 946 3 -80.45 14.51 -27.55 0.4 945
965 | 947 3 -83.45 16.51 -27.55 0.4 946
966 | 948 3 -87.95 17.51 -27.55 0.4 947
967 | 949 3 -91.45 18.51 -32.55 0.4 948
968 | 950 3 -95.45 18.51 -39.550 0.4 949
969 | 951 3 -99.45 18.01 -46.550 0.4 950
970 | 952 3 -103. 18.51 -48.550 0.4 951
971 | 953 3 -107.5 18.51 -50.550 0.4 952
972 | 954 3 -112. 19.01 -52.050 0.4 953
973 | 955 3 -116.5 19.51 -54.050 0.4 954
974 | 956 3 -48.45 7.014 -26.05 0.4950 930
975 | 957 3 -53.45 12.51 -27.55 0.4950 956
976 | 958 3 -59.45 17.51 -31.55 0.4950 957
977 | 959 3 -67.45 21.01 -28.55 0.4 958
978 | 960 3 -74.45 23.51 -27.55 0.4 959
979 | 961 3 -78.45 26.01 -26.05 0.4 960
980 | 962 3 -82.45 28.51 -27.05 0.4 961
981 | 963 3 -85.95 31.51 -26.55 0.4 962
982 | 964 3 -89.45 34.01 -26.05 0.4 963
983 | 965 3 -92.95 36.51 -26.05 0.4 964
984 | 966 3 -97.95 40.51 -27.05 0.4 965
985 | 967 3 -104.5 45.01 -29.05 0.4 966
986 | 968 3 -111. 49.01 -33.05 0.4 967
987 | 969 3 -59.95 20.01 -33.55 0.4 958
988 | 970 3 -61.45 23.01 -36.550 0.4 969
989 | 971 3 -63.45 27.01 -39.050 0.4 970
990 | 972 3 -64.95 31.51 -42.050 0.4 971
991 | 973 3 -66.95 34.51 -44.050 0.4 972
992 | 974 3 -68.45 36.01 -47.550 0.4 973
993 | 975 3 -71.45 38.01 -49.550 0.4 974
994 | 976 3 -73.95 41.01 -51.550 0.4 975
995 | 977 3 -76.95 45.51 -56.550 0.4 976
996 | 978 3 -78.45 51.01 -60.050 0.4 977
997 | 979 3 -80.45 57.01 -65.05 0.4 978
998 | 980 3 -48.45 3.0140 -27.05 0.4 929
999 | 981 3 -55.95 5.014 -27.55 0.4 980
1000 | 982 3 -63.95 6.514 -27.55 0.4 981
1001 | 983 3 -71.45 7.514 -27.55 0.4 982
1002 | 984 3 -78.95 4.514 -27.55 0.4 983
1003 | 985 3 -86.95 1.014 -27.55 0.4 984
1004 | 986 3 -95.45 -2.986 -27.55 0.4 985
1005 | 987 3 -102.5 -6.486 -27.55 0.4 986
1006 | 988 3 -74.95 11.01 -30.05 0.4 983
1007 | 989 3 -77.95 15.01 -28.05 0.4 988
1008 | 990 3 -79.45 19.01 -18.05 0.4 989
1009 | 991 3 -80.45 25.51 -8.553 0.4 990
1010 | 992 3 -82.95 30.51 -3.053 0.4 991
1011 | 993 3 -86.45 34.51 -1.553 0.4 992
1012 | 994 3 -90.45 36.51 -2.053 0.4 993
1013 | 995 3 -93.95 39.01 -1.053 0.4 994
1014 | 996 3 -44.45 6.514 -27.55 0.4 928
1015 | 997 3 -45.95 12.51 -28.55 0.4 996
1016 | 998 3 -48.95 20.01 -28.55 0.4 997
1017 | 999 3 -53.45 25.51 -28.05 0.4 998
1018 | 1000 3 -56.45 31.01 -31.05 0.4 999
1019 | 1001 3 -58.95 35.51 -35.550 0.4 1000
1020 | 1002 3 -61.95 42.01 -41.050 0.4 1001
1021 | 1003 3 -65.45 50.01 -45.550 0.4 1002
1022 | 1004 3 -68.45 60.01 -51.550 0.4 1003
1023 | 1005 3 -23.45 0.0139 -30.05 1.150 925
1024 | 1006 3 -27.95 5.014 -31.55 1.150 1005
1025 | 1007 3 -33.95 11.51 -31.55 1.150 1006
1026 | 1008 3 -35.45 16.01 -31.55 0.70 1007
1027 | 1009 3 -38.45 21.51 -33.05 0.70 1008
1028 | 1010 3 -41.45 27.01 -35.050 0.70 1009
1029 | 1011 3 -44.95 33.01 -37.050 0.70 1010
1030 | 1012 3 -47.95 38.01 -39.550 0.70 1011
1031 | 1013 3 -50.45 43.51 -39.550 0.70 1012
1032 | 1014 3 -52.45 48.51 -38.050 0.70 1013
1033 | 1015 3 -57.45 56.01 -42.050 0.70 1014
1034 | 1016 3 -58.45 62.01 -44.550 0.4 1015
1035 | 1017 3 -57.95 68.51 -45.050 0.4 1016
1036 | 1018 3 -57.45 75.51 -48.050 0.4 1017
1037 | 1019 3 -56.95 82.51 -51.550 0.4 1018
1038 | 1020 3 -62.45 59.01 -43.050 0.4 1015
1039 | 1021 3 -67.45 63.01 -44.550 0.4 1020
1040 | 1022 3 -71.45 67.01 -45.550 0.4 1021
1041 | 1023 3 -76.45 71.01 -48.050 0.4 1022
1042 | 1024 3 -81.95 74.01 -51.550 0.4 1023
1043 | 1025 3 -53.45 53.01 -55.050 0.4 1014
1044 | 1026 3 -54.95 57.01 -64.55 0.4 1025
1045 | 1027 3 -56.95 61.51 -67.55 0.4 1026
1046 | 1028 3 -61.45 64.01 -67.55 0.4 1027
1047 | 1029 3 -54.95 65.01 -54.050 0.4 1027
1048 | 1030 3 -55.95 50.01 -35.050 0.4 1013
1049 | 1031 3 -58.45 52.01 -31.55 0.4 1030
1050 | 1032 3 -59.95 55.51 -29.55 0.4 1031
1051 | 1033 3 -60.95 58.51 -27.55 0.4 1032
1052 | 1034 3 -62.95 63.01 -27.55 0.4 1033
1053 | 1035 3 -66.95 67.01 -25.55 0.4 1034
1054 | 1036 3 -70.45 75.51 -23.55 0.4 1035
1055 | 1037 3 -72.95 86.01 -22.05 0.4 1036
1056 | 1038 3 -36.95 15.51 -36.050 0.950 1007
1057 | 1039 3 -40.95 21.01 -46.050 0.950 1038
1058 | 1040 3 -44.45 25.01 -46.050 0.490 1039
1059 | 1041 3 -47.95 29.51 -46.050 0.490 1040
1060 | 1042 3 -51.95 30.51 -48.050 0.4 1041
1061 | 1043 3 -56.45 32.51 -54.050 0.4 1042
1062 | 1044 3 -59.45 35.51 -59.050 0.4 1043
1063 | 1045 3 -62.95 37.01 -63.550 0.4 1044
1064 | 1046 3 -66.95 40.51 -65.05 0.4 1045
1065 | 1047 3 -73.45 45.51 -69.05 0.4 1046
1066 | 1048 3 -49.45 34.01 -49.550 0.4 1041
1067 | 1049 3 -50.95 40.01 -46.550 0.4 1048
1068 | 1050 3 -54.45 45.51 -42.550 0.4 1049
1069 | 1051 3 -58.45 50.01 -33.55 0.4 1050
1070 | 1052 3 -62.45 53.01 -27.55 0.4 1051
1071 | 1053 3 -37.95 27.51 -46.050 0.8 1039
1072 | 1054 3 -34.95 34.51 -47.550 0.8 1053
1073 | 1055 3 -32.45 42.51 -51.550 0.8 1054
1074 | 1056 3 -33.95 48.01 -60.550 0.4 1055
1075 | 1057 3 -35.95 54.01 -64.05 0.4 1056
1076 | 1058 3 -38.95 59.51 -65.55 0.4 1057
1077 | 1059 3 -41.45 64.51 -67.55 0.4 1058
1078 | 1060 3 -29.45 47.01 -52.550 0.4 1055
1079 | 1061 3 -28.45 51.51 -53.050 0.4 1060
1080 | 1062 3 -29.95 56.51 -55.050 0.4 1061
1081 | 1063 3 -32.95 60.51 -58.550 0.4 1062
1082 | 1064 3 -35.95 64.51 -63.550 0.4 1063
1083 | 1065 3 -45.45 17.01 -47.050 0.4150 1038
1084 | 1066 3 -50.45 16.51 -56.050 0.4150 1065
1085 | 1067 3 -56.45 19.01 -74.05 0.4150 1066
1086 | 1068 1 -20.1 -5.039 -28.7 12.49 924
1087 | 1069 1 -21. -5.888 -30.490 10.72 1068
1088 | 1070 1 -21.90 -6.18 -31.05 7.48 1069
1089 | 1071 1 -23.25 -7.350 -34.2 2.2 1070
1090 | 1072 3 -25.25 -7.350 -34.2 2.2 1071
1091 | 1073 3 -26.75 -7.350 -34.2 1.8 1072
1092 | 1074 3 -38.75 -8.85 -30.7 1.8 1073
1093 | 1075 3 -47.25 -9.35 -26.7 1.8 1074
1094 | 1076 3 -51.75 -8.85 -22.2 1.8 1075
1095 | 1077 3 -51.85 -8.85 -22.2 1.90 1076
1096 | 1078 3 -58.75 -14.35 -22.2 1.150 1077
1097 | 1079 3 -63.75 -18.35 -22.2 1.150 1078
1098 | 1080 3 -66.25 -20.35 -22.2 1.150 1079
1099 | 1081 3 -70.25 -26.85 -18.2 0.4 1080
1100 | 1082 3 -74.25 -31.85 -16.2 0.4 1081
1101 | 1083 3 -77.75 -37.35 -15.70 0.4 1082
1102 | 1084 3 -79.25 -41.85 -14.20 0.4 1083
1103 | 1085 3 -80.75 -47.35 -12.70 0.4 1084
1104 | 1086 3 -84.25 -51.35 -11.70 0.4 1085
1105 | 1087 3 -92.25 -56.35 -11.70 0.4 1086
1106 | 1088 3 -104.30 -62.35 -11.70 0.4 1087
1107 | 1089 3 -119.80 -68.850 -11.70 0.4 1088
1108 | 1090 3 -72.75 -24.85 -21.2 0.4 1080
1109 | 1091 3 -77.75 -27.85 -21.2 0.4 1090
1110 | 1092 3 -80.75 -27.85 -21.2 0.4 1091
1111 | 1093 3 -86.25 -28.35 -23.7 0.4 1092
1112 | 1094 3 -90.25 -28.35 -26.2 0.4 1093
1113 | 1095 3 -93.75 -29.35 -29.2 0.4 1094
1114 | 1096 3 -103.30 -31.85 -29.2 0.4 1095
1115 | 1097 3 -113.30 -35.35 -29.2 0.4 1096
1116 | 1098 3 -124.80 -38.85 -31.7 0.4 1097
1117 | 1099 3 -138.3 -42.85 -37.2 0.4 1098
1118 | 1100 3 -102.30 -31.85 -38.7 0.4 1095
1119 | 1101 3 -110.80 -36.85 -44.2 0.4 1100
1120 | 1102 3 -117.80 -42.85 -49.2 0.4 1101
1121 | 1103 3 -121.80 -46.35 -52.2 0.4 1102
1122 | 1104 3 -125.30 -49.35 -55.7 0.4 1103
1123 | 1105 3 -60.25 -11.35 -15.70 0.9 1077
1124 | 1106 3 -65.25 -12.35 -11.70 0.9 1105
1125 | 1107 3 -66.75 -12.35 -10.20 0.9 1106
1126 | 1108 3 -71.75 -18.85 -8.2 0.4 1107
1127 | 1109 3 -80.25 -23.85 -3.2 0.4 1108
1128 | 1110 3 -86.25 -27.85 4.3 0.4 1109
1129 | 1111 3 -91.75 -31.35 10.8 0.4 1110
1130 | 1112 3 -97.75 -31.85 13.8 0.4 1111
1131 | 1113 3 -105.80 -30.85 16.3 0.4 1112
1132 | 1114 3 -113.30 -26.85 19.3 0.4 1113
1133 | 1115 3 -118.30 -23.85 23.8 0.4 1114
1134 | 1116 3 -122.80 -21.35 26.8 0.4 1115
1135 | 1117 3 -126.80 -20.35 29.3 0.4 1116
1136 | 1118 3 -73.25 -10.35 -5.7 0.4 1107
1137 | 1119 3 -77.75 -9.35 -3.7 0.4 1118
1138 | 1120 3 -80.25 -9.85 -3.7 0.4 1119
1139 | 1121 3 -85.75 -11.85 2.30 0.4 1120
1140 | 1122 3 -93.25 -13.35 4.8 0.4 1121
1141 | 1123 3 -101.30 -14.35 6.8 0.4 1122
1142 | 1124 3 -111.30 -15.35 8.3 0.4 1123
1143 | 1125 3 -121.80 -15.85 11.3 0.4 1124
1144 | 1126 3 -132.3 -16.35 11.8 0.4 1125
1145 | 1127 3 -139.8 -16.35 12.3 0.4 1126
1146 | 1128 3 -89.25 -5.350 0.3 0.4 1120
1147 | 1129 3 -98.25 -0.850 3.80 0.4 1128
1148 | 1130 3 -105.30 1.650 4.8 0.4 1129
1149 | 1131 3 -114.80 0.65 4.8 0.4 1130
1150 | 1132 3 -120.80 -2.35 4.3 0.4 1131
1151 | 1133 3 -124.80 -5.850 4.3 0.4 1132
1152 | 1134 3 -52.75 -7.350 -22.2 1.6 1076
1153 | 1135 3 -53.25 -6.850 -22.2 1.6 1134
1154 | 1136 3 -65.25 -8.85 -17.7 0.75 1135
1155 | 1137 3 -74.75 -8.85 -17.2 0.75 1136
1156 | 1138 3 -83.25 -7.350 -22.2 0.75 1137
1157 | 1139 3 -89.75 -5.350 -26.2 0.75 1138
1158 | 1140 3 -93.75 -4.850 -29.2 0.75 1139
1159 | 1141 3 -101.30 -8.35 -28.2 0.4 1140
1160 | 1142 3 -109.30 -11.35 -27.2 0.4 1141
1161 | 1143 3 -115.80 -11.35 -27.2 0.4 1142
1162 | 1144 3 -125.80 -12.85 -26.2 0.4 1143
1163 | 1145 3 -135.8 -13.35 -26.2 0.4 1144
1164 | 1146 3 -146.8 -15.85 -23.7 0.4 1145
1165 | 1147 3 -154.8 -18.35 -19.7 0.4 1146
1166 | 1148 3 -100.30 -2.35 -29.7 0.4 1140
1167 | 1149 3 -106.80 -1.35 -30.2 0.4 1148
1168 | 1150 3 -111.80 -3.85 -27.2 0.4 1149
1169 | 1151 3 -117.30 -5.850 -29.2 0.4 1150
1170 | 1152 3 -123.30 -7.850 -35.7 0.4 1151
1171 | 1153 3 -112.80 2.65 -31.2 0.4 1149
1172 | 1154 3 -119.80 8.15 -33.2 0.4 1153
1173 | 1155 3 -128.3 14.15 -36.2 0.4 1154
1174 | 1156 3 -138.3 19.650 -39.7 0.4 1155
1175 | 1157 3 -54.25 -1.85 -18.7 0.4 1135
1176 | 1158 3 -56.75 2.15 -16.7 0.4 1157
1177 | 1159 3 -60.25 7.15 -16.2 0.4 1158
1178 | 1160 3 -66.75 12.65 -17.2 0.4 1159
1179 | 1161 3 -74.25 18.650 -21.7 0.4 1160
1180 | 1162 3 -82.75 23.650 -26.7 0.4 1161
1181 | 1163 3 -89.25 25.150 -31.2 0.4 1162
1182 | 1164 3 -94.25 26.650 -36.2 0.4 1163
1183 | 1165 3 -100.30 26.650 -42.2 0.4 1164
1184 | 1166 3 -107.80 27.150 -51.7 0.4 1165
1185 | 1167 3 -118.30 28.150 -62.2 0.4 1166
1186 | 1168 3 -28.75 -3.35 -31.7 0.8 1073
1187 | 1169 3 -34.25 2.15 -27.2 0.8 1168
1188 | 1170 3 -39.75 7.65 -22.2 0.8 1169
1189 | 1171 3 -43.25 10.15 -21.2 0.8 1170
1190 | 1172 3 -43.35 10.15 -21.2 0.6 1171
1191 | 1173 3 -43.45 11.15 -21.2 0.4150 1172
1192 | 1174 3 -56.75 12.65 -18.7 0.4 1173
1193 | 1175 3 -68.25 13.15 -15.70 0.4 1174
1194 | 1176 3 -77.75 12.15 -12.20 0.4 1175
1195 | 1177 3 -83.75 9.65 -11.70 0.4 1176
1196 | 1178 3 -89.75 6.65 -11.70 0.4 1177
1197 | 1179 3 -97.25 3.65 -11.70 0.4 1178
1198 | 1180 3 -105.30 0.65 -11.70 0.4 1179
1199 | 1181 3 -113.30 0.15 -11.70 0.4 1180
1200 | 1182 3 -118.30 1.150 -11.70 0.4 1181
1201 | 1183 3 -120.80 2.65 -11.70 0.4 1182
1202 | 1184 3 -45.75 12.15 -15.70 0.4 1173
1203 | 1185 3 -51.75 13.65 -13.70 0.4 1184
1204 | 1186 3 -59.75 15.65 -14.70 0.4 1185
1205 | 1187 3 -67.75 16.15 -13.70 0.4 1186
1206 | 1188 3 -74.75 16.15 -12.20 0.4 1187
1207 | 1189 3 -81.75 13.15 -11.70 0.4 1188
1208 | 1190 3 -88.25 10.65 -11.70 0.4 1189
1209 | 1191 3 -95.25 7.65 -11.70 0.4 1190
1210 | 1192 3 -99.75 5.65 -11.70 0.4 1191
1211 | 1193 3 -102.30 5.15 -11.70 0.4 1192
1212 | 1194 3 -45.75 14.15 -17.2 0.4 1172
1213 | 1195 3 -51.25 19.650 -15.70 0.4 1194
1214 | 1196 3 -55.75 23.650 -15.70 0.4 1195
1215 | 1197 3 -59.75 26.650 -15.70 0.4 1196
1216 | 1198 3 -71.75 32.65 -15.70 0.4 1197
1217 | 1199 3 -78.75 36.15 -15.70 0.4 1198
1218 | 1200 3 -81.75 37.65 -15.70 0.4 1199
1219 | 1201 3 -85.75 41.15 -15.70 0.4 1200
1220 | 1202 3 -91.75 45.15 -15.70 0.4 1201
1221 | 1203 3 -100.80 51.15 -20.7 0.4 1202
1222 | 1204 3 -111.80 58.15 -31.7 0.4 1203
1223 | 1205 3 -62.25 33.15 -23.2 0.4 1197
1224 | 1206 3 -67.25 41.15 -31.7 0.4 1205
1225 | 1207 3 -72.75 50.65 -39.2 0.4 1206
1226 | 1208 3 -78.75 59.65 -41.2 0.4 1207
1227 | 1209 3 -81.75 68.65 -53.2 0.4 1208
1228 | 1210 3 -84.25 61.65 -48.7 0.4 1208
1229 | 1211 3 -90.75 67.65 -50.2 0.4 1210
1230 | 1212 3 -46.25 22.650 -17.2 0.4 1171
1231 | 1213 3 -50.25 32.15 -17.7 0.4 1212
1232 | 1214 3 -54.25 39.65 -19.2 0.4 1213
1233 | 1215 3 -57.25 45.15 -22.2 0.4 1214
1234 | 1216 3 -61.25 52.15 -24.7 0.4 1215
1235 | 1217 3 -64.75 59.65 -28.7 0.4 1216
1236 | 1218 3 -66.75 65.15 -32.2 0.4 1217
1237 | 1219 3 -66.75 68.15 -35.7 0.4 1218
1238 |
--------------------------------------------------------------------------------