{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1537d3aa",
   "metadata": {},
   "source": [
    "# NEST-compatible modeling with ``brainpy.state``\n",
    "\n",
    "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/chaobrain/brainx/blob/main/docs/tutorials/brainpy.state_NEST_compatible.ipynb)\n",
    "[![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/chaobrain/brainx/blob/main/docs/tutorials/brainpy.state_NEST_compatible.ipynb)\n",
    "\n",
    "This tutorial follows the NEST-style workflow exposed by `brainpy.state`:\n",
    "\n",
    "1. **Create** model nodes and devices;\n",
    "2. **Connect** populations, projections, and recorders;\n",
    "3. **Simulate** the network for a duration;\n",
    "4. **Record** traces and spike events from the result object.\n",
    "\n",
    "After the one-neuron path, the tutorial expands the same ideas to `NodeView` algebra, connection rules, a small excitatory/inhibitory network, and practical cautions for porting NEST scripts into the BrainX ecosystem.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d6e5608",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "Enable JAX x64 before importing `brainpy.state`, then give each `Simulator` an explicit unit-aware time step. The examples below use milliseconds, picoamperes, and millivolts from `brainunit`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "74031e1a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:30.272668Z",
     "iopub.status.busy": "2026-06-22T01:52:30.272668Z",
     "iopub.status.idle": "2026-06-22T01:52:36.919233Z",
     "shell.execute_reply": "2026-06-22T01:52:36.919233Z"
    }
   },
   "outputs": [],
   "source": [
    "import jax\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import brainunit as u\n",
    "import brainpy.state as bp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19cced9d",
   "metadata": {},
   "source": [
    "## 1. Create: model nodes\n",
    "\n",
    "`Simulator.create()` is the `brainpy.state` counterpart of NEST's `Create`. It returns a `NodeView`, which is a handle to the created population or device.\n",
    "\n",
    "The example below creates one `iaf_psc_alpha` neuron. Parameters use NEST-compatible names such as `I_e`, `V_th`, `V_reset`, and `E_L`, while values remain explicit `brainunit` quantities.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4ab7338b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:36.922414Z",
     "iopub.status.busy": "2026-06-22T01:52:36.921422Z",
     "iopub.status.idle": "2026-06-22T01:52:39.861580Z",
     "shell.execute_reply": "2026-06-22T01:52:39.861580Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<brainpy.state.NodeView object at 0x000001B7D49A62D0>\n",
      "number of nodes = 1\n"
     ]
    }
   ],
   "source": [
    "sim = bp.Simulator(dt=0.1 * u.ms)\n",
    "\n",
    "neuron = sim.create(\n",
    "    bp.iaf_psc_alpha,\n",
    "    params={\n",
    "        \"I_e\": 376.0 * u.pA,\n",
    "        \"V_th\": -55.0 * u.mV,\n",
    "        \"V_reset\": -70.0 * u.mV,\n",
    "        \"E_L\": -70.0 * u.mV,\n",
    "    },\n",
    ")\n",
    "\n",
    "print(neuron)\n",
    "print(f\"number of nodes = {len(neuron)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1beaeafa",
   "metadata": {},
   "source": [
    "## 2. Connect: recording devices\n",
    "\n",
    "Recording devices follow NEST's connection direction:\n",
    "\n",
    "- a `voltmeter` observes a neuron, so connect `voltmeter -> neuron`;\n",
    "- a `spike_recorder` receives spike events, so connect `neuron -> spike_recorder`.\n",
    "\n",
    "The same `Simulator.connect()` method registers either a projection or a recorder tap depending on the source and target types.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "03ff21d6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:39.864589Z",
     "iopub.status.busy": "2026-06-22T01:52:39.863582Z",
     "iopub.status.idle": "2026-06-22T01:52:39.868591Z",
     "shell.execute_reply": "2026-06-22T01:52:39.868591Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "recorders are connected\n"
     ]
    }
   ],
   "source": [
    "vm = sim.create(bp.voltmeter, interval=0.1 * u.ms)\n",
    "sr = sim.create(bp.spike_recorder)\n",
    "\n",
    "sim.connect(vm, neuron)      # voltmeter observes the neuron\n",
    "sim.connect(neuron, sr)      # spike_recorder receives emitted spikes\n",
    "\n",
    "print(\"recorders are connected\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b42e4ca",
   "metadata": {},
   "source": [
    "## 3. Simulate: run the model\n",
    "\n",
    "`Simulator.simulate()` is the explicit runner. It returns a `SimulationResult` object with helper methods for recorded variables:\n",
    "\n",
    "- `trace(recorder, \"V_m\")` returns a membrane-potential trace from a voltmeter or multimeter;\n",
    "- `spikes(recorder)` returns a time-by-node spike matrix;\n",
    "- `n_events(recorder)` counts recorded spikes;\n",
    "- `rate(recorder)` reports the mean firing rate in spikes per second.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2c70142c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:39.869723Z",
     "iopub.status.busy": "2026-06-22T01:52:39.869723Z",
     "iopub.status.idle": "2026-06-22T01:52:40.521676Z",
     "shell.execute_reply": "2026-06-22T01:52:40.521676Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "V_m shape     = (800, 1)\n",
      "spikes shape  = (800, 1)\n",
      "spike count   = 1\n",
      "firing rate   = 12.50 Hz\n"
     ]
    }
   ],
   "source": [
    "result = sim.simulate(80.0 * u.ms)\n",
    "\n",
    "V_m = result.trace(vm, \"V_m\")\n",
    "spikes = result.spikes(sr)\n",
    "times = result.times\n",
    "\n",
    "print(f\"V_m shape     = {V_m.shape}\")\n",
    "print(f\"spikes shape  = {spikes.shape}\")\n",
    "print(f\"spike count   = {result.n_events(sr)}\")\n",
    "print(f\"firing rate   = {result.rate(sr):.2f} Hz\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ba48e34",
   "metadata": {},
   "source": [
    "## 4. Record: visualize traces and events\n",
    "\n",
    "The result object separates simulation from analysis. Once the run has finished, use recorder handles to extract arrays and plot them with ordinary Python tools. This mirrors the NEST habit of attaching devices first and reading them after `Simulate`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6606f9c9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:40.523686Z",
     "iopub.status.busy": "2026-06-22T01:52:40.523686Z",
     "iopub.status.idle": "2026-06-22T01:52:40.899699Z",
     "shell.execute_reply": "2026-06-22T01:52:40.899699Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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ERGZjIEFERERERGZzOwDi3PnzmHTpk1ISEhQjzmDNhERERFR8TPbwOL27dvo1KkTqlevjsceewxhYWFq/QsvvIDx48dr3TwiIiIiIqtitoHF2LFjYW9vjytXrsDV1dW4/plnnsHGjRs1bRsRERERkbWxh5navHmzGgJVrly5TOurVauGy5cva9YuIiIiIiJrZLY9FnFxcZl6KgwiIyPh5OSkSZuIiIiIiKyV2QYWbdu2xbJly4yPbWxsoNPp8P7776N9+/aato2IiIiIyNqY7VAoCSA6duyIgwcPIjk5GW+++SZOnDiheix27dqldfOIiIiIiKyK2fZY1K1bF2fOnEGbNm3Qo0cPNTSqV69e+Oeff1ClShWtm0dEREREZFXMtsdix44dasjT5MmT79u2aNEijBo1SpN2ERERERFZI7PtsZDeiUOHDt23/uOPP8akSZM0aRMRERERkbUy28Bi7ty56NatG0JCQozr5s2bh3feeQcbNmzQtG1ERERERNbGbIdCvfjiiypRW2bf/vvvv/H9999j9uzZ+O2339C6dWutm0dEREREZFXMNrAQUgnq9u3baNq0KdLS0tSEeQ899JDWzSIiIiIisjpmFVgsWLDgvnVly5ZVE+U9/PDD2L9/v1rEmDFjNGghEREREZF1MqvA4sMPP8x2vZ2dnZq7wjB/hUyWx8CCiIiIiKj4mFVgcfHiRa2bQEREREREllQVioiIiIiISg6z6rEYN24cZs6cCTc3N3U/N/Pnzy+2dhERERERWTuzCiz++ecfpKSkGO/nRHIsiIiIiIio+JhVYLFjx45s7xMRERERkbYsIsciNDRULUREREREpA2zDSxSU1Px9ttvw9PTE8HBwWqR+1OmTDEOlyIiIiIiouJhVkOhMnrllVewZs0avP/++2jZsqVat2fPHkybNk3Nxv3pp59q3UQiIiIiIqthtoHFypUrsWrVKnTr1s24rn79+ihfvjyee+45BhZERERERMXIbIdCOTk5qeFPWVWqVAmOjo6atImIiIiIyFqZbWAxevRoNadFUlKScZ3cnzVrltpGRERERETFx2yHQsk8Ftu2bUO5cuXQoEEDte7o0aNITk5Gx44d0atXL+O+kotBRERERERFx2wDCy8vL/Tu3TvTOsmvICIiIiKi4me2gcX//vc/6HQ6uLm5qceXLl3CunXrUKtWLXTp0kXr5hERERERWRWzzbHo0aMHli9fru7fvXsXDz30EObNm4eePXuyIhQRERERUTEz28Di8OHDaNu2rbr/008/ISAgAJcvX8ayZcuwYMECrZtHRERERGRVzDawiI+Ph7u7u7q/efNmlaxta2urei4kwCAiIiIiouJjtoFF1apVVU5FaGgoNm3ahM6dO6v14eHh8PDw0Lp5RERERERWxWwDi3feeQevv/66miSvRYsWaNmypbH3olGjRlo3j4iIiIjIqphtVag+ffqgTZs2CAsLM85jIWQOi6eeekrTthERERERWRuzDSxEYGCgWjJq3ry5Zu0hIiIiIrJWZjsUioiIiIiISg4GFkREREREZDIGFkREREREZDIGFkREREREZDIGFkREREREZDIGFkREREREZDIGFkREREREZDIGFkREREREZDIGFvcsWrQIwcHBcHZ2RosWLbB//36tm0REREREZDYYWAD4/vvvMW7cOEydOhWHDx9GgwYN0KVLF4SHh2vdNCIiIiIis8DAAsD8+fMxbNgwDBkyBLVr18Znn30GV1dXLF68WOumERERERGZBXtYueTkZBw6dAiTJk0yrrO1tUWnTp2wZ88elHS/HL2OU2HRWjeDiIjIIly9k2C8f+xaFN7bGKJpe4gMejcui6r+7ijJrD6wuHXrFtLS0hAQEJBpvTwOCcn+j0lSUpJaDKKjtTux33bqJn4+cl2zn09ERGSpQm7EqIWoJGha0ZuBhSWaM2cOpk+fjpLgkep+8HVz0roZREREFiMuKRWR8cko7+2qdVOIjMr7lPzPo9UHFqVLl4adnR1u3ryZab08DgwMzPY5MmxKkr0z9liUL18eWujVuBx6NdbkRxMRERERGVl9YOHo6IgmTZpg27Zt6Nmzp1qn0+nU49GjR2f7HCcnJ7UY6PV6zYdEEREREREVNsP5reF8NzdWH1gI6X0YNGgQmjZtiubNm+Ojjz5CXFycqhKVFzEx6eMvteq1ICIiIiIqSnK+6+npmes+DCwAPPPMM4iIiMA777yDGzduoGHDhti4ceN9Cd05CQoKQmhoKNzd3WFjY4PiZBiGJT/fw8OjWH+2JeDxKzgeO9Pw+BUcj51pePwKjsfONDx+5nnspKdCggo5330QBhb3yLCnnIY+PYiUpy1Xrhy0JB8y/ictOB6/guOxMw2PX8Hx2JmGx6/geOxM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",
      "text/plain": [
       "<Figure size 800x400 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(2, 1, figsize=(8, 4), sharex=True, height_ratios=[3, 1])\n",
    "\n",
    "axes[0].plot(times, V_m[:, 0])\n",
    "axes[0].axhline(-55.0 * u.mV, color=\"tab:red\", ls=\"--\", lw=0.9, label=\"threshold\")\n",
    "axes[0].set_ylabel(\"V_m\")\n",
    "axes[0].set_title(\"One iaf_psc_alpha neuron\")\n",
    "axes[0].legend(loc=\"best\")\n",
    "\n",
    "axes[1].plot(times, spikes[:, 0], drawstyle=\"steps-post\")\n",
    "axes[1].set_ylabel(\"spike\")\n",
    "axes[1].set_xlabel(\"time\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0757577",
   "metadata": {},
   "source": [
    "## 5. NodeView algebra: populations, slices, and groups\n",
    "\n",
    "A `NodeView` can refer to a full population, a slice of one population, or a concatenation of several views. This gives you a compact way to express NEST-like population algebra while keeping Python objects explicit.\n",
    "\n",
    "A practical constraint: a single `spike_recorder` records one population segment. If you concatenate two populations, use one recorder per population when you want spike recordings from both groups.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "fa228460",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:40.901713Z",
     "iopub.status.busy": "2026-06-22T01:52:40.901713Z",
     "iopub.status.idle": "2026-06-22T01:52:40.972206Z",
     "shell.execute_reply": "2026-06-22T01:52:40.971703Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "exc size           = 6\n",
      "inh size           = 3\n",
      "first_two_exc size = 2\n",
      "combined size      = 9\n"
     ]
    }
   ],
   "source": [
    "pop_sim = bp.Simulator(dt=0.1 * u.ms)\n",
    "\n",
    "exc = pop_sim.create(bp.iaf_psc_alpha, 6, params={\"I_e\": 400.0 * u.pA})\n",
    "inh = pop_sim.create(bp.iaf_psc_alpha, 3, params={\"I_e\": 360.0 * u.pA})\n",
    "\n",
    "first_two_exc = exc[:2]\n",
    "all_neurons = exc + inh\n",
    "\n",
    "print(f\"exc size           = {len(exc)}\")\n",
    "print(f\"inh size           = {len(inh)}\")\n",
    "print(f\"first_two_exc size = {len(first_two_exc)}\")\n",
    "print(f\"combined size      = {len(all_neurons)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6363f91",
   "metadata": {},
   "source": [
    "## 6. Connect: population projections\n",
    "\n",
    "Connection rules are passed to `sim.connect()` through the `rule` argument. The common pattern is:\n",
    "\n",
    "```python\n",
    "sim.connect(pre, post, rule=..., weight=..., delay=..., seed=...)\n",
    "```\n",
    "\n",
    "Positive weights drive excitatory current channels, while negative weights drive inhibitory current channels for current-based NEST-compatible neurons. Delays are unit-aware time quantities.\n",
    "\n",
    "For known dense examples, the default communication path is fine. For larger sparse networks, `comm=\"sparse\"` routes event delivery through sparse communication while preserving the same high-level `connect()` interface.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "bd6c8905",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:40.973217Z",
     "iopub.status.busy": "2026-06-22T01:52:40.973217Z",
     "iopub.status.idle": "2026-06-22T01:52:42.617659Z",
     "shell.execute_reply": "2026-06-22T01:52:42.617659Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "E/I projections are connected\n"
     ]
    }
   ],
   "source": [
    "# E -> I: sparse random excitatory projection.\n",
    "pop_sim.connect(\n",
    "    exc,\n",
    "    inh,\n",
    "    rule=bp.pairwise_bernoulli(0.5),\n",
    "    weight=20.0 * u.pA,\n",
    "    delay=1.0 * u.ms,\n",
    "    seed=1,\n",
    ")\n",
    "\n",
    "# I -> E: sparse random inhibitory projection.\n",
    "pop_sim.connect(\n",
    "    inh,\n",
    "    exc,\n",
    "    rule=bp.pairwise_bernoulli(0.5),\n",
    "    weight=-45.0 * u.pA,\n",
    "    delay=1.0 * u.ms,\n",
    "    seed=2,\n",
    ")\n",
    "\n",
    "print(\"E/I projections are connected\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0517857a",
   "metadata": {},
   "source": [
    "### Deterministic connection rules\n",
    "\n",
    "The same interface also covers deterministic rules. This cell uses a separate simulator only to show the API shape without interfering with the E/I example above.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "17272358",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:42.620671Z",
     "iopub.status.busy": "2026-06-22T01:52:42.619673Z",
     "iopub.status.idle": "2026-06-22T01:52:42.829135Z",
     "shell.execute_reply": "2026-06-22T01:52:42.829135Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EventProjection\n",
      "EventProjection\n"
     ]
    }
   ],
   "source": [
    "rule_sim = bp.Simulator(dt=0.1 * u.ms)\n",
    "pre = rule_sim.create(bp.iaf_psc_alpha, 3, params={\"I_e\": 380.0 * u.pA})\n",
    "post = rule_sim.create(bp.iaf_psc_alpha, 3)\n",
    "\n",
    "one_to_one_proj = rule_sim.connect(\n",
    "    pre,\n",
    "    post,\n",
    "    rule=bp.one_to_one,\n",
    "    weight=15.0 * u.pA,\n",
    "    delay=1.0 * u.ms,\n",
    ")\n",
    "\n",
    "all_to_all_proj = rule_sim.connect(\n",
    "    pre,\n",
    "    post,\n",
    "    rule=bp.all_to_all,\n",
    "    weight=5.0 * u.pA,\n",
    "    delay=1.0 * u.ms,\n",
    ")\n",
    "\n",
    "print(type(one_to_one_proj).__name__)\n",
    "print(type(all_to_all_proj).__name__)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04dd8c34",
   "metadata": {},
   "source": [
    "## 7. Record: a small E/I network\n",
    "\n",
    "Now attach one spike recorder to the excitatory population and one to the inhibitory population. This keeps each recorder tied to a single population segment, which is the supported recording layout for spike recorders.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f0c7641f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:42.830584Z",
     "iopub.status.busy": "2026-06-22T01:52:42.830584Z",
     "iopub.status.idle": "2026-06-22T01:52:43.978546Z",
     "shell.execute_reply": "2026-06-22T01:52:43.978546Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "exc_spikes shape = (800, 6)\n",
      "inh_spikes shape = (800, 3)\n",
      "exc events       = 12\n",
      "inh events       = 2\n",
      "exc rate         = 25.00 Hz\n",
      "inh rate         = 8.33 Hz\n"
     ]
    }
   ],
   "source": [
    "exc_rec = pop_sim.create(bp.spike_recorder)\n",
    "inh_rec = pop_sim.create(bp.spike_recorder)\n",
    "\n",
    "pop_sim.connect(exc, exc_rec)\n",
    "pop_sim.connect(inh, inh_rec)\n",
    "\n",
    "net_result = pop_sim.simulate(80.0 * u.ms)\n",
    "\n",
    "exc_spikes = net_result.spikes(exc_rec)\n",
    "inh_spikes = net_result.spikes(inh_rec)\n",
    "\n",
    "print(f\"exc_spikes shape = {exc_spikes.shape}\")\n",
    "print(f\"inh_spikes shape = {inh_spikes.shape}\")\n",
    "print(f\"exc events       = {net_result.n_events(exc_rec)}\")\n",
    "print(f\"inh events       = {net_result.n_events(inh_rec)}\")\n",
    "print(f\"exc rate         = {net_result.rate(exc_rec):.2f} Hz\")\n",
    "print(f\"inh rate         = {net_result.rate(inh_rec):.2f} Hz\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "56a1d951",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-22T01:52:43.980561Z",
     "iopub.status.busy": "2026-06-22T01:52:43.980561Z",
     "iopub.status.idle": "2026-06-22T01:52:44.198557Z",
     "shell.execute_reply": "2026-06-22T01:52:44.198557Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxUAAAFUCAYAAABShhHqAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAAQqJJREFUeJzt3Ql8FOX9x/FfCCEQjnDIqVyCgIByqkVUpIKI1IvW2ooWwaMKVgW1iq0KWC4VPGrLoRz+VaTaaj0qKlBEUVQQFagVRFEicqmQgEASkvm/vg/udrPZhITNZjabz/v1GsjO7O48M/PM7POb55gkz/M8AwAAAIAjVOVIPwgAAAAAQlABAAAAICoEFQAAAACiQlABAAAAICoEFQAAAACiQlABAAAAICoEFQAAAACiQlABAAAAICoEFQAAAACiQlABRGnevHmWlJRkX375ZXBeq1at7Gc/+5mv6arIXn31VevatatVr17d7dvdu3f7naRKQft67NixxeZtJBZdq6644opCx3zVqlWH/eyZZ57pJsQnHZvOnTv7nQxUIgQVqHTWrl1rv/jFL6xly5au0Hr00Udb//797c9//rPfSYs777zzjitklmeh/rvvvrNf/vKXVqNGDfvLX/5iTzzxhNWsWbPc1o/SUx5RQbRx48a2b9++QssjBdl6f1HTtddeW+C9L730kvXp08caNWpkaWlpduyxx7o8ouAzUHgq7vsCU2jAVJn4cR4fCQU3RR07Xasj6dGjh40YMSL4+Vq1apkf/vrXv7qADKjMqvqdAKC8f1z79u1rLVq0sKuvvtqaNGliGRkZ9u6779pDDz1kv/vd70r9nZdffrn96le/stTUVEvE/TVu3Dj3Y123bt1yWefKlSttz549ds8991i/fv3KZZ0oGzt27LDp06fbzTffXKL3K5j/zW9+U2h+u3btgn/ff//9duutt7qgYsyYMS6o2Lhxoy1evNgWLFhg55xzjv3hD3+wq666qkAeevjhh+2OO+6w448/Pjj/xBNPtMqouPN4/fr1VqVK/Nxf1HX0scceKzQ/OTm50LytW7fahx9+aOPHjze/Kag46qijCtT6AJUNQQUqlQkTJlh6erordIT/uKpAdCT0YxfpB6+8HThwwKpVqxZXBYSi6G62CoeRBI5DSYKY4r4H5U9N1u677z5351g1TYej4OGyyy4rcvnBgwddcKng4/XXXy8yr2h5KN3VVlCh+TTPKV683QypWrVqsXki1MKFC92x/ulPfxrzdFUkP/zwA7W78EX8lz6AMvT5559bp06dIhZY1bQilKrcr7/+envqqaesffv27sdLVe1vvvlmgfeVtN35448/7n4wddc14L333nN3WhXoqHCsu7Fvv/32YbfjjTfecOvUndo//vGPrgmXPp+VlWXff/+93XLLLXbCCSe4pgB16tSxgQMH2scff1zoe9TkS/tDn61Xr5717NnT5s+f75apuUQgra1btw42QwjdzieffNLtExUg69ev72psVPMTqV3vBx98YGeccYZbl+4gR6L3Dh061P190kknufUF7vwV9z0qXF555ZWu+Y2OU5cuXdz+DqV06/t051vNqtSERt9x9tlnuzR7nucKsMccc4zbngsuuMDty8NZs2aNS6O+T+tW7dfw4cNdM66SKO4YBI6D0r1hwwZX2FJeadiwod15550uzUq70qrjrHVPnTq1wPfn5OTYXXfd5Y6TPqvCxumnn25Lly61sqb1bN++3dVWlIVvv/3W5enevXtHXB5+zkbj008/dU2qtG91/HXOqwYklO6K61zSvta5ddZZZ7lazkjXg+XLl9sNN9zgvk/Xm9/+9rfuWKgJkmpndKw1/f73v3fHMVI+feCBB1wzTaVH14Z169aVOu8d7jwO71MRGrArzQ0aNHDbqzTv2rXrsPsxOzvb7r77bmvbtq0LWJo3b+62UfPL2r/+9S9X81ySADZUoJnUli1b7MILL3R/6zjpupmXl1fgvfn5+fbggw+6c1T7WNcY7ZfQfaF9+J///MeWLVsW3L+6XulY64aTAtzQPK0bP9qvocf9uuuuc8cv1LPPPhu8vqoWROe/0hxpW/Tbdu6551rt2rVtyJAhRW67gnNda37961+7oB0oS9RUoFLRD/SKFSvcj3NJOrDpR+Jvf/ubKxzoB1JV3AoC3n///VJ1gJs1a5ZrJ65C8J/+9Cc379///rcroOhHQz/C+qGZO3euu+v21ltv2cknn3zY71UhWLUT+jHUj7b+/uSTT+yf//ynXXzxxa4QoULezJkzXaFEy5o1a+Y+++ijj7rtUv+SG2+80dV0qJCiQOfSSy+1wYMHu4Ls008/7Qo3+lET/fgGan1UsFVBTE1Pdu7c6QrIKvCr8BUauKmQo21V0KEfRv0w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qqTl7aieqP3111+7CQAAAEDlVeqgQg+7Gz9+vItYWrZs6aa6devaPffcU+hBeAAAAAASX6n7VPzhD3+w2bNn2+TJk613795u3vLly23s2LGuE/eECRNikU4AAAAAidKnolmzZu4BeOeff36B+S+88IKNGDHCtmzZYuWFPhUAAABABexT8f3331uHDh0Kzdc8LQMAAABQuZQ6qOjSpYs98sgjheZrnpYBAAAAqFxK3afi3nvvtUGDBrmH3/Xq1cvNW7FihWVkZNgrr7wSizQCAAAASKSaij59+tiGDRvsoosust27d7tp8ODBtn79ejv99NNjk0oAAAAAiVFTkZuba+ecc47rqM0oTwAAAABKXVORkpJia9asYc8BAAAAOPLmT5dddpl7TgUAAAAAHFFH7YMHD9qcOXNcR+0ePXpYzZo1CyyfNm0aexYAAACoREodVKxbt866d+/u/laH7VBJSUlllzIAAAAAiRlULF26NDYpAQAAAFA5+lQAAAAAQFQ1FX379i22mdO///3v0n4lAAAAgMoUVHTt2rXQsys++ugj19di6NChZZk2AAAAAIkYVDzwwAMR548dO9b27t1bFmkCAAAAUBn7VOj5FRpqtjSmT59uJ554otWpU8dNvXr1soULF1pFciA3zzK+3+f+BwAAqAgov8D3moqirFixwqpXr16qzxxzzDE2efJkO+6448zzPHv88cftggsusA8//NA6depk8Swv37MHFm2w2cs32f7cPKuRkmxXntbaRvVvZ8lVGFoXAADEH8oviJugYvDgwQVeKxjYunWrrVq1yu68885Sfdd5551X4PWECRNc7cW7774b90GFTshHlm4MvtaJGXh9y4D2PqYMAAAgMsoviJvmT+np6QWm+vXr25lnnmmvvPKK3X333UeckLy8PFuwYIH98MMPrhlUJNnZ2ZaVlVVg8oOqChXhRzLn7U1UJQIAgLhD+QVxVVMxd+7cMk3A2rVrXRBx4MABq1Wrlj3//PPWsWPHiO+dNGmSjRs3zvy2c0+2i+wj2ZeT55Y3r59W7ukCAAAoCuUXxF1H7d27d9tjjz1mY8aMse+//97NW716tW3ZsqXU39W+fXs3JO17771n1113nRuW9pNPPon4Xq0vMzMzOGVkZJgfGtZOdW0QI0mrluyWAwAAxBPKL4iroGLNmjWuY/WUKVPs/vvvdwGG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",
      "text/plain": [
       "<Figure size 800x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def raster_points(spike_matrix, offset=0):\n",
    "    t_idx, neuron_idx = np.where(np.asarray(spike_matrix) > 0)\n",
    "    return t_idx, neuron_idx + offset\n",
    "\n",
    "exc_t, exc_id = raster_points(exc_spikes, offset=0)\n",
    "inh_t, inh_id = raster_points(inh_spikes, offset=len(exc))\n",
    "\n",
    "time_values = np.asarray(net_result.times.to_decimal(u.ms))\n",
    "\n",
    "plt.figure(figsize=(8, 3.5))\n",
    "if len(exc_t):\n",
    "    plt.scatter(time_values[exc_t], exc_id, s=18, label=\"E\", color=\"tab:blue\")\n",
    "if len(inh_t):\n",
    "    plt.scatter(time_values[inh_t], inh_id, s=18, label=\"I\", color=\"tab:orange\")\n",
    "\n",
    "plt.axhline(len(exc) - 0.5, color=\"0.5\", lw=0.8, ls=\"--\")\n",
    "plt.xlabel(\"time (ms)\")\n",
    "plt.ylabel(\"neuron index\")\n",
    "plt.title(\"Spike raster from a small NEST-compatible E/I network\")\n",
    "plt.legend(loc=\"upper right\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ef0e492",
   "metadata": {},
   "source": [
    "## 8. Translate NEST scripts carefully\n",
    "\n",
    "### Quick translation map\n",
    "\n",
    "| NEST concept | `brainpy.state` pattern | Notes |\n",
    "| --- | --- | --- |\n",
    "| `nest.Create(\"iaf_psc_alpha\", n, params=...)` | `sim.create(bp.iaf_psc_alpha, n, params=...)` | Model names are Python classes, not strings. |\n",
    "| `nest.Connect(pre, post, conn_spec, syn_spec)` | `sim.connect(pre, post, rule=..., weight=..., delay=...)` | Connection rule and synaptic parameters are explicit keyword arguments. |\n",
    "| `nest.Simulate(t)` | `sim.simulate(t * u.ms)` | Duration is a `brainunit` quantity. |\n",
    "| `voltmeter -> neuron` | `sim.connect(vm, neuron)` | Analog recorders observe the target population. |\n",
    "| `neuron -> spike_recorder` | `sim.connect(neuron, sr)` | Spike recorders receive events from one population segment. |\n",
    "| NodeCollection slicing | `node_view[:k]`, `view_a + view_b` | Concatenated views are useful for population algebra, but some devices require one segment. |\n",
    "\n",
    "### Porting cautions\n",
    "\n",
    "| Area | What changes in BrainX | Practical guidance |\n",
    "| --- | --- | --- |\n",
    "| Units | Physical quantities are explicit objects, not bare numbers. | Write `20.0 * u.pA`, `1.0 * u.ms`, and `-55.0 * u.mV`; convert deliberately when plotting or exporting. |\n",
    "| Model identifiers | Models are imported Python classes/functions. | Use `bp.iaf_psc_alpha`, `bp.voltmeter`, and `bp.spike_recorder` instead of string model names. |\n",
    "| Device direction | Recorder connections keep NEST-style direction. | Connect `voltmeter -> neuron` for analog traces and `neuron -> spike_recorder` for spikes. |\n",
    "| Recorder scope | Spike recorders are tied to a population segment. | Use separate recorders for excitatory and inhibitory groups when you need separate raster data. |\n",
    "| JAX execution | Arrays and simulations are JAX-compatible and may be compiled internally. | Keep model construction outside repeated simulation loops; pass changing inputs and parameters explicitly. |\n",
    "| Validation | Compatibility focuses on documented semantics, not byte-for-byte equality with every NEST run. | Check units, time step, delays, seeds, and documented model assumptions when comparing results. |\n",
    "\n",
    "For model physiology, use the upstream NEST model documentation. For `brainpy.state`, focus on the Python API, unit handling, simulator semantics, and documented validation status.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "144a2cc0",
   "metadata": {},
   "source": [
    "## 9. Summary\n",
    "\n",
    "The NEST-compatible layer in `brainpy.state` gives you a familiar workflow while staying inside the BrainX/JAX ecosystem:\n",
    "\n",
    "1. create model nodes and devices with `Simulator.create()`;\n",
    "2. wire populations, projections, and recorders with `Simulator.connect()`;\n",
    "3. run a simulation window with `Simulator.simulate()`;\n",
    "4. inspect traces and events with `SimulationResult.trace()`, `spikes()`, `n_events()`, and `rate()`.\n",
    "\n",
    "When porting NEST scripts, preserve the workflow but adopt BrainX idioms: explicit units, Python model objects, JAX-compatible arrays, and stateful simulation objects managed by `brainpy.state` and `brainstate`.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Ecosystem-py",
   "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.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
