{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9dfae642",
   "metadata": {},
   "source": [
    "# Model anatomy\n",
    "\n",
    "**What you'll learn / who it's for (simulation *and* training).** The shared\n",
    "``Dynamics`` contract behind every neuron and synapse — the state variables they\n",
    "own, the ``update()`` step, the ``get_spike()`` output, and how a neuron receives\n",
    "current. This contract is exactly what projections rely on, so it sets up the\n",
    "keystone chapter that follows."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2520c059",
   "metadata": {},
   "source": [
    "## One contract: `Dynamics`\n",
    "\n",
    "``brainpy.state`` models form a small, deliberate hierarchy:\n",
    "\n",
    "```text\n",
    "brainstate.nn.Module\n",
    "└── Dynamics            (anything that evolves in time)\n",
    "    ├── Neuron          (a population that integrates current and emits spikes)\n",
    "    └── Synapse         (temporal filtering of a spike train)\n",
    "```\n",
    "\n",
    "Every ``Dynamics`` honors the same four-part contract:\n",
    "\n",
    "1. **Declare state** in ``__init__`` (e.g. membrane potential ``V``, conductance\n",
    "   ``g``).\n",
    "2. **Allocate it** via ``init_all_states`` (which calls each object's\n",
    "   ``init_state``).\n",
    "3. **Advance one step** with ``update(...)`` — called for you when you invoke the\n",
    "   module.\n",
    "4. **Expose outputs** — neurons add ``get_spike()``.\n",
    "\n",
    "Because the contract is uniform, components compose: a ``Synapse`` filters spikes\n",
    "into a current, and a ``Neuron`` integrates that current — and a *projection*\n",
    "(next chapter) snaps the two together across populations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6ca91527",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-17T09:11:00.731390Z",
     "iopub.status.busy": "2026-06-17T09:11:00.731070Z",
     "iopub.status.idle": "2026-06-17T09:11:04.695845Z",
     "shell.execute_reply": "2026-06-17T09:11:04.695194Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "An NVIDIA GPU may be present on this machine, but a CUDA-enabled jaxlib is not installed. Falling back to cpu.\n"
     ]
    }
   ],
   "source": [
    "import brainpy\n",
    "import brainstate\n",
    "import braintools\n",
    "import brainunit as u\n",
    "import jax.numpy as jnp\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48def7b2",
   "metadata": {},
   "source": [
    "## Neurons: integrate current, emit spikes\n",
    "\n",
    "A neuron population owns a membrane potential ``V`` (a state) and a set of unitful\n",
    "parameters (``tau``, ``V_th``, ``V_reset``, ``V_rest``, ``R``). Calling the neuron\n",
    "with an input current advances ``V`` one ``dt`` and, when ``V`` crosses threshold,\n",
    "emits a spike and resets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d5fde5a5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-17T09:11:04.698306Z",
     "iopub.status.busy": "2026-06-17T09:11:04.697896Z",
     "iopub.status.idle": "2026-06-17T09:11:07.759590Z",
     "shell.execute_reply": "2026-06-17T09:11:07.758738Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "state variable V: (100,) float32\n"
     ]
    }
   ],
   "source": [
    "neuron = brainpy.state.LIFRef(\n",
    "    100,\n",
    "    V_rest=-65. * u.mV, V_th=-50. * u.mV, V_reset=-65. * u.mV,\n",
    "    tau=10. * u.ms, tau_ref=2. * u.ms,\n",
    "    V_initializer=braintools.init.Normal(-65., 2., unit=u.mV),\n",
    ")\n",
    "brainstate.nn.init_all_states(neuron)\n",
    "\n",
    "print('state variable V:', neuron.V.value.shape, neuron.V.value.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bef5ab4e",
   "metadata": {},
   "source": [
    "### `get_spike()`: the spike output\n",
    "\n",
    "A neuron's spike output is read with ``get_spike()``. During training it is a\n",
    "*surrogate* — a smooth, differentiable stand-in for the hard threshold (see\n",
    "{doc}`/concepts/differentiability`) — but its role in wiring is always the same: it\n",
    "is the signal a projection transmits to downstream populations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "afd94dff",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-17T09:11:07.761650Z",
     "iopub.status.busy": "2026-06-17T09:11:07.761249Z",
     "iopub.status.idle": "2026-06-17T09:11:07.985095Z",
     "shell.execute_reply": "2026-06-17T09:11:07.984363Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "voltage trace: (1000, 100)\n",
      "spike trace:   (1000, 100)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total spikes:  1100\n"
     ]
    }
   ],
   "source": [
    "def step(t):\n",
    "    with brainstate.environ.context(t=t):\n",
    "        neuron(jnp.ones(100) * 30. * u.mA)   # drive every neuron\n",
    "        return neuron.V.value, neuron.get_spike()\n",
    "\n",
    "with brainstate.environ.context(dt=0.1 * u.ms):\n",
    "    times = u.math.arange(0. * u.ms, 100. * u.ms, brainstate.environ.get_dt())\n",
    "    vs, spikes = brainstate.transform.for_loop(step, times)\n",
    "\n",
    "print('voltage trace:', vs.shape)      # (time, neurons)\n",
    "print('spike trace:  ', spikes.shape)  # (time, neurons)\n",
    "print('total spikes: ', int(u.math.sum(spikes)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f885f6b",
   "metadata": {},
   "source": [
    "### How a neuron receives current\n",
    "\n",
    "Synaptic input does not overwrite a neuron's drive — it **accumulates** into it.\n",
    "Internally a neuron sums all current contributions delivered during a step before\n",
    "integrating ``V``. From your side this means you simply *call the neuron* with any\n",
    "direct input, and projections add their synaptic current on top:\n",
    "\n",
    "```python\n",
    "self.proj(pre_spikes)   # projection deposits synaptic current into `post`\n",
    "self.post(external)     # neuron integrates synaptic + external current\n",
    "```\n",
    "\n",
    "That additive convention is what lets several projections target the same\n",
    "population and have their effects sum — the basis of the **automatic merging** you\n",
    "will see in the keystone."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7303a642",
   "metadata": {},
   "source": [
    "## Synapses: temporal filtering of spikes\n",
    "\n",
    "A synapse turns a discrete spike train into a continuous signal. The most common is\n",
    "the **exponential** synapse: each arriving spike bumps a conductance ``g`` that then\n",
    "decays.\n",
    "\n",
    "$$\\tau \\frac{dg}{dt} = -g, \\qquad g \\leftarrow g + 1 \\text{ on each spike.}$$\n",
    "\n",
    "That ``g ← g + 1`` increment is *identity-agnostic* — it does not matter which\n",
    "presynaptic neuron fired — and that single fact is what makes the AlignPost\n",
    "reduction in the next chapter exact. Keep it in mind."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2ee9275a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-17T09:11:07.986611Z",
     "iopub.status.busy": "2026-06-17T09:11:07.986464Z",
     "iopub.status.idle": "2026-06-17T09:11:08.298653Z",
     "shell.execute_reply": "2026-06-17T09:11:08.297800Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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w0Fa/su2lLTMshowYACOHDmCd999Fy1btoSFhQW0Wi169uxZqrMaj5s0aRL69u2LTZs2YceOHfjkk08QGhqKPXv2oFWrVgCAJk2awMfHB7/88guGDRuGX375BUqlEgMGDCi0vNJs7/jx47FixQpMmjQJfn5+UKvVkMlkGDRo0H/aBplMhg0bNuDYsWP4888/sWPHDowYMQJz587FsWPHdPvI0dERv/76a5HLcHBwqJD1Pkl5HxsF5e/Hn3/+Gc7OzoWm5z/SYe3atbo/UDy+/rlz52L48OHYvHkz/v77b0yYMAGhoaE4duwY3NzcnrpGAGjatCkSExPx888/Y/To0Xo/6/nbMGfOHLRs2bLI+Uvax4D+meOyLnfAgAHo2LEjNm7ciL///htz5szBrFmz8Mcff6BXr14lrvtplOb4KOnnt7THAREZFv7kEpHkHBwcYGlpCY1GA39//xL7nz17Fp999hmCgoIQHh6ON954A+fOndMb6AHI+49aZGSk7q/lAHD58mUA0A0k4OnpiV27diElJUXvbN6lS5d00ytyW0qrtIOlPHjwALt378ann36KqVOn6trz/1r/X9WtWxdvv/023n77bVy5cgUtW7bE3Llz8csvv+j6DBs2DCEhIbh79y5Wr16NPn366F1KVhYbNmxAYGAg5s6dq2vLzMxEYmJikf2vXLmCrl276j6npqbi7t276N27t16/du3aoV27dvjiiy+wevVqDB06FGvWrMEbb7yBunXrYteuXejQoUOh//Q/rSet92l4enpCq9Xi+vXremfLCo7OWpz8S2YdHR2feKwGBARg586dxU5v3rw5mjdvjo8//hhHjhxBhw4dsGTJEt3AKEDRx9/ly5dhZmZWYni2t7fHhg0b8Oyzz6Jbt244dOgQXF1d9bbBysqqXH/eyrpcFxcXjB07FmPHjkVcXBxat26NL774Qi/k3blzB2lpaXpn84r6fXT27FlotVq9s3n/9fdRwe0p7ue3tMcBERkWXq5JRJJTKBTo378/fv/9d5w/f77Q9IKXc+Xk5GD48OFwdXXF/PnzsXLlSsTGxmLy5MlFLnvBggW690IILFiwAMbGxujWrRsAoHfv3tBoNHr9AOCbb76BTCYr81/iy7ItZWFubl6qy87y/7L/+JmeefPm/af1pqenIzMzU6+tbt26sLS0LHTJ4eDBgyGTyTBx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PuzYsYPHeAV60n7ncV4xLC0t9e7vBQBzc3PY2dnp2g3qeJd6eE8S4rvvvhMeHh5CqVSKtm3bimPHjkldUrU1cOBA4eLiIpRKpahVq5YYOHCguHr1qtRlVTt79+4VAAq9AgMDhRB5j1H45JNPhJOTk1CpVKJbt24iIiJC2qIN3JP2eXp6uujRo4dwcHAQxsbGwtPTU4waNUrExMRIXbZBK2p/AxArVqzQ9cnIyBBjx44VNjY2wszMTPTr10/cvXtXuqINXEn7PDo6WnTq1EnY2toKlUol6tWrJ959912RlJQkbeEGbMSIEcLT01MolUrh4OAgunXrJv7++2/ddB7jFeNJ+53HeeV5/FEVhnS8y4QQojJDJREREREREVUc3pNHRERERERUjTDkERERERERVSMMeURERERERNUIQx4REREREVE1wpBHRERERERUjTDkERERERERVSMMeURERERERNUIQx4REREREVE1wpBHRERERERUjTDkERFRtbdv3z7IZDIkJiZKsv7du3ejcePG0Gg0FbaOdu3a4ffff6+w5RMRkeGQCSGE1EUQERGVly5duqBly5aYN2+eri07Oxv379+Hk5MTZDJZpdfk4+ODkJAQDB06tMLW8ddff2Hy5MmIiIiAXM6/4RIR1WT8V4CIiKo9pVIJZ2dnSQLeoUOHcO3aNfTv379C19OrVy+kpKRg27ZtFboeIiKq+hjyiIio2hg+fDj279+P+fPnQyaTQSaTISoqqtDlmitXroS1tTX++usvNGzYEGZmZnjllVeQnp6OVatWwcvLCzY2NpgwYYLeJZZZWVl45513UKtWLZibm8PX1xf79u17Yk1r1qxB9+7dYWJiomubPn06WrZsieXLl8PDwwMWFhYYO3YsNBoNZs+eDWdnZzg6OuKLL77QzSOEwPTp0+Hh4QGVSgVXV1dMmDBBN12hUKB3795Ys2ZN+exMIiIyWEZSF0BERFRe5s+fj8uXL6NZs2b47LPPAAAODg6Iiooq1Dc9PR3ffvst1qxZg5SUFLz88svo168frK2tsXXrVkRGRqJ///7o0KEDBg4cCAAYN24c/v33X6xZswaurq7YuHEjevbsiXPnzqF+/fpF1nTw4EEMGTKkUPu1a9ewbds2bN++HdeuXcMrr7yCyMhINGjQAPv378eRI0cwYsQI+Pv7w9fXF7///ju++eYbrFmzBk2bNkVMTAzOnDmjt8y2bdti5syZT7kXiYjI0DHkERFRtaFWq6FUKmFmZgZnZ+cn9s3JycHixYtRt25dAMArr7yCn3/+GbGxsbCwsECTJk3QtWtX7N27FwMHDkR0dDRWrFiB6OhouLq6AgDeeecdbN++HStWrMCXX35Z5Hpu3Lih61+QVqvF8uXLYWlpqVtXREQEtm7dCrlcjoYNG2LWrFnYu3cvfH19ER0dDWdnZ/j7+8PY2BgeHh5o27at3jJdXV1x8+ZNaLVa3pdHRFSD8V8AIiKqkczMzHQBDwCcnJzg5eUFCwsLvba4uDgAwLlz56DRaNCgQQNYWFjoXvv378e1a9eKXU9GRobepZr5vLy8YGlpqbeuJk2a6IWzgut/9dVXkZGRgTp16mDUqFHYuHEjcnNz9ZZpamoKrVaLrKysMu4NIiKqTngmj4iIaiRjY2O9zzKZrMg2rVYLAEhNTYVCoUBYWBgUCoVev4LB8HH29vZ48ODBU6/f3d0dERER2LVrF3bu3ImxY8dizpw52L9/v26++/fvw9zcHKampk/adCIiquYY8oiIqFpRKpUV8jy6Vq1aQaPRIC4uDh07dizTfP/++2+51GBqaoq+ffuib9++CA4ORqNGjXDu3Dm0bt0aAHD+/Hm0atWqXNZFRESGiyGPiIiqFS8vLxw/fhxRUVGwsLCAra1tuSy3QYMGGDp0KIYNG4a5c+eiVatWuHfvHnbv3o0WLVqgT58+Rc4XEBCAVatWPfX6V65cCY1GA19fX5iZmeGXX36BqakpPD09dX0OHjyIHj16PPW6iIjIsPGePCIiqlbeeecdKBQKNGnSBA4ODoiOji63Za9YsQLDhg3D22+/jYYNG+Kll17CyZMn4eHhUew8Q4cOxYULFxAREfFU67a2tsayZcvQoUMHtGjRArt27cKff/4JOzs7AMDt27dx5MgRBAUFPdV6iIjI8MmEEELqIoiIiKqzd999F8nJyfj+++8rbB3vv/8+Hjx4gKVLl1bYOoiIyDDwTB4REVEF++ijj+Dp6akbRKUiODo6YsaMGRW2fCIiMhw8k0dERERERFSN8EweERERERFRNcKQR0REREREVI0w5BEREREREVUjDHlERERERETVCEMeERERERFRNcKQR0REREREVI0w5BEREREREVUjDHlERERERETVCEMeERERERFRNfJ/mZXNo1aWUrMAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 900x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "syn = brainpy.state.Expon(1, tau=5. * u.ms,\n",
    "                          g_initializer=braintools.init.Constant(0. * u.mS))\n",
    "brainstate.nn.init_all_states(syn)\n",
    "\n",
    "def syn_step(t):\n",
    "    with brainstate.environ.context(t=t):\n",
    "        # a single spike at t = 0, nothing afterwards\n",
    "        spike = u.math.where(t == 0. * u.ms, 1.0 * u.mS, 0.0 * u.mS)\n",
    "        return syn(spike)\n",
    "\n",
    "with brainstate.environ.context(dt=0.1 * u.ms):\n",
    "    times = u.math.arange(0. * u.ms, 40. * u.ms, brainstate.environ.get_dt())\n",
    "    g = brainstate.transform.for_loop(syn_step, times)\n",
    "\n",
    "plt.figure(figsize=(9, 3))\n",
    "plt.plot(times.to_decimal(u.ms), g.to_decimal(u.mS).squeeze())\n",
    "plt.xlabel('time (ms)'); plt.ylabel('g (mS)'); plt.title('exponential synapse: single-spike response')\n",
    "plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e687d701",
   "metadata": {},
   "source": [
    "The family extends well beyond the single exponential — ``DualExpon`` and ``Alpha``\n",
    "add a rise time; ``AMPA``, ``GABAa``, and ``BioNMDA`` model receptor kinetics, some\n",
    "of them *nonlinear* in the conductance. That linear-vs-nonlinear distinction decides\n",
    "which projection alignment applies, the central question of the next chapter. (Note\n",
    "the names: it is ``GABAa`` and ``BioNMDA``, not ``GABA``/``NMDA``.)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6febd3bb",
   "metadata": {},
   "source": [
    "## Outputs: from conductance to current\n",
    "\n",
    "A synapse produces a conductance; an **output** converts it into the current the\n",
    "postsynaptic neuron actually feels. The choice encodes the biophysics:\n",
    "\n",
    "- **CUBA** (current-based): $I = g$. Simple, fast, voltage-independent.\n",
    "- **COBA** (conductance-based): $I = g\\,(E - V)$, with a reversal potential ``E``.\n",
    "  Self-limiting and biologically realistic — excitatory with ``E = 0 mV``,\n",
    "  inhibitory with ``E = -80 mV``.\n",
    "- **MgBlock** (NMDA): COBA plus a voltage-dependent magnesium block.\n",
    "\n",
    "You do not wire an output by hand — it is one of the four components a *projection*\n",
    "assembles, which is precisely where we go next."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3eda2529",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-17T09:11:08.300487Z",
     "iopub.status.busy": "2026-06-17T09:11:08.300317Z",
     "iopub.status.idle": "2026-06-17T09:11:08.304984Z",
     "shell.execute_reply": "2026-06-17T09:11:08.304159Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CUBA(\n",
      "  scale=Unit(\"V\")\n",
      ") COBA(\n",
      "  E=Quantity(0., \"mV\")\n",
      ") COBA(\n",
      "  E=Quantity(-80., \"mV\")\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "cuba = brainpy.state.CUBA()\n",
    "exc = brainpy.state.COBA(E=0. * u.mV)\n",
    "inh = brainpy.state.COBA(E=-80. * u.mV)\n",
    "print(cuba, exc, inh)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85de1dbe",
   "metadata": {},
   "source": [
    "## Recap\n",
    "\n",
    "- Neurons and synapses share one **``Dynamics``** contract: declare state →\n",
    "  allocate → ``update()`` → expose outputs.\n",
    "- A **neuron** integrates current and emits spikes via ``get_spike()``; synaptic\n",
    "  input **accumulates** additively into its drive.\n",
    "- A **synapse** filters spikes into a conductance; the exponential synapse's\n",
    "  ``g ← g + 1`` increment is *identity-agnostic*.\n",
    "- An **output** (CUBA / COBA / MgBlock) turns conductance into current.\n",
    "\n",
    "These four pieces — communication, synapse, output, postsynaptic population — are\n",
    "exactly what a projection composes.\n",
    "\n",
    "## See also\n",
    "\n",
    "- {doc}`/concepts/alignpre-alignpost` — **the keystone**: how projections wire\n",
    "  these pieces across populations, memory-efficiently and exactly.\n",
    "- {doc}`/concepts/state-paradigm` — the state and ``transform`` machinery used\n",
    "  above.\n",
    "- {doc}`/concepts/physical-units` — the units every parameter carries.\n",
    "- {doc}`/apis/index` — the full catalog of neuron, synapse, and output models."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
