{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6773b075",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-19T07:56:13.260232Z",
     "iopub.status.busy": "2026-06-19T07:56:13.259985Z",
     "iopub.status.idle": "2026-06-19T07:56:18.791366Z",
     "shell.execute_reply": "2026-06-19T07:56:18.790441Z"
    },
    "tags": [
     "remove-cell"
    ]
   },
   "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": [
    "%matplotlib inline\n",
    "import brainmass\n",
    "import brainstate\n",
    "import brainunit as u\n",
    "import jax.numpy as jnp\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "brainstate.random.seed(0)\n",
    "brainstate.environ.set(dt=0.1 * u.ms)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5dd31b7b",
   "metadata": {},
   "source": [
    "# What Is a Neural Mass Model?\n",
    "\n",
    "A **neural mass model** (NMM) is a low-dimensional dynamical system that describes\n",
    "the *average* activity of a large population of neurons with a handful of state\n",
    "variables and ordinary differential equations (ODEs). Instead of tracking the\n",
    "membrane potential and spikes of every cell, an NMM tracks population-level\n",
    "quantities — a mean firing rate, an average synaptic current, a mean membrane\n",
    "potential — and how they evolve in time.\n",
    "\n",
    "This page explains the core idea, where it sits between single-neuron models and\n",
    "whole-brain models, and the two flavours of NMM you will meet in ``brainmass``. It\n",
    "is *understanding-oriented*: light on code, focused on intuition. For hands-on\n",
    "recipes, see the {doc}`/tutorials/index`; for the package design, see\n",
    "{doc}`/concepts/architecture_overview`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97b1faa4",
   "metadata": {},
   "source": [
    "## The mean-field idea\n",
    "\n",
    "A cortical column or brain region contains on the order of $10^5$–$10^6$ neurons.\n",
    "Simulating each one is expensive and — for many questions about rhythms,\n",
    "large-scale dynamics, and neuroimaging signals — unnecessary. The **mean-field\n",
    "approximation** replaces the population by its *statistics*.\n",
    "\n",
    "The intuition is the law of large numbers. If $N$ neurons each contribute a noisy\n",
    "spike train, the **population-averaged** firing rate\n",
    "\n",
    "$$\n",
    "r(t) \\;=\\; \\frac{1}{N}\\sum_{k=1}^{N} \\text{(spikes of neuron $k$ near time $t$)}\n",
    "$$\n",
    "\n",
    "fluctuates far less than any single neuron and, in the large-$N$ limit, follows a\n",
    "smooth, *deterministic* equation. A neural mass model is a closed set of ODEs for\n",
    "such population averages, for example a mean rate $r$ and a mean membrane potential\n",
    "$v$:\n",
    "\n",
    "$$\n",
    "\\tau \\,\\dot r = F(r, v, \\text{input}), \\qquad\n",
    "\\tau \\,\\dot v = G(r, v, \\text{input}).\n",
    "$$\n",
    "\n",
    "The functions $F$ and $G$ encode the population's input–output behaviour (a\n",
    "sigmoidal *f–I* curve), its synaptic time constants, and its recurrent\n",
    "connectivity. The price of this compression is that you give up single-spike\n",
    "information; the reward is that a whole brain region becomes 1–6 numbers you can\n",
    "simulate, fit, and differentiate cheaply."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e52a75ed",
   "metadata": {},
   "source": [
    "## Populations, not single neurons\n",
    "\n",
    "It helps to place the NMM on a ladder of abstraction:\n",
    "\n",
    "| Level | State per unit | Typical # of units for a brain | Captures |\n",
    "|---|---|---|---|\n",
    "| Single-neuron (Hodgkin–Huxley, LIF) | membrane potential, gating, spikes | $10^9$–$10^{11}$ | individual spikes, biophysics |\n",
    "| **Neural mass / mean field** | mean rate / potential (1–6 vars) | tens–hundreds (one per region) | population rhythms, regional dynamics |\n",
    "| Neural field | activity over a continuous sheet | a field $u(x,t)$ | spatial patterns, travelling waves |\n",
    "\n",
    "The NMM lives at the **population** rung. One \"unit\" is not a neuron — it is an\n",
    "entire population (a column, a region, an excitatory or inhibitory pool). This is\n",
    "exactly the right granularity for whole-brain modelling, where the data\n",
    "(EEG/MEG/fMRI) are themselves spatially coarse and reflect *aggregate* activity,\n",
    "not single cells.\n",
    "\n",
    "A second key move is the **excitatory–inhibitory (E–I) motif**. Many NMMs model a\n",
    "region as coupled excitatory and inhibitory pools, because the push–pull between\n",
    "them generates oscillations (alpha, gamma) and stabilises activity. The\n",
    "Wilson–Cowan and Jansen–Rit models in ``brainmass`` are built from this motif."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc99493d",
   "metadata": {},
   "source": [
    "## Two flavours: phenomenological vs physiological\n",
    "\n",
    "NMMs come in two broad styles, and ``brainmass`` ships both.\n",
    "\n",
    "**Phenomenological** models aim to reproduce the *qualitative dynamics* — limit\n",
    "cycles, bistability, bifurcations — with the simplest possible equations, often a\n",
    "normal form. Their parameters are abstract (a bifurcation parameter, an angular\n",
    "frequency) rather than biophysical. They are ideal for studying *what kind* of\n",
    "dynamics a region can produce and for fast, well-conditioned fitting.\n",
    "\n",
    "- *Hopf / Stuart–Landau* — the normal form of an oscillation; a single\n",
    "  bifurcation parameter switches a region between a quiet fixed point and a\n",
    "  self-sustained rhythm. The canonical \"house\" demo model.\n",
    "- *FitzHugh–Nagumo, Van der Pol* — excitable / relaxation-oscillator dynamics.\n",
    "- *Kuramoto* — phase-only oscillators for studying synchronisation.\n",
    "\n",
    "**Physiological** (biophysical) models keep variables and parameters that map onto\n",
    "measurable biology — synaptic time constants, membrane capacitance, ion-channel\n",
    "conductances, firing-rate transfer functions — so their outputs can be compared to\n",
    "recordings in physical units.\n",
    "\n",
    "- *Jansen–Rit* — three interacting populations producing realistic EEG-like\n",
    "  waveforms in millivolts.\n",
    "- *Wilson–Cowan* — coupled E and I firing rates with sigmoidal transfer.\n",
    "- *Wong–Wang* — synaptic-gating dynamics used for fMRI/BOLD whole-brain models.\n",
    "- *Montbrió–Pazó–Roxin, Coombes–Byrne* — **next-generation / exact** mean fields\n",
    "  derived *exactly* from networks of quadratic-integrate-and-fire neurons, so the\n",
    "  mean rate and potential carry the right biophysical meaning (see\n",
    "  {doc}`/concepts/why_differentiable` for why the exact derivation matters).\n",
    "\n",
    "You can browse the full catalogue with ``brainmass.list_models()`` — let's do\n",
    "that now."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6dd89042",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-19T07:56:18.793884Z",
     "iopub.status.busy": "2026-06-19T07:56:18.793525Z",
     "iopub.status.idle": "2026-06-19T07:56:18.797403Z",
     "shell.execute_reply": "2026-06-19T07:56:18.796520Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name                     category          #states  use_case                                 \n",
      "-----------------------  ----------------  -------  -----------------------------------------\n",
      "HopfStep                 phenomenological  2        Oscillation onset, rhythm generation     \n",
      "VanDerPolStep            phenomenological  2        Nonlinear relaxation oscillations        \n",
      "StuartLandauStep         phenomenological  2        Amplitude-controlled oscillations        \n",
      "FitzHughNagumoStep       phenomenological  2        Excitability, spike generation           \n",
      "ThresholdLinearStep      phenomenological  2        Fast linear E-I responses                \n",
      "Generic2dOscillatorStep  phenomenological  2        Flexible planar dynamics (TVB)           \n",
      "LorenzStep               phenomenological  3        Chaos, coupling test fixture             \n",
      "LinearStep               phenomenological  1        Baseline node, coupling sanity checks    \n",
      "WilsonCowanStep          physiological     2        E-I population firing-rate dynamics      \n",
      "JansenRitStep            physiological     6        EEG generation, alpha rhythms            \n",
      "WongWangStep             physiological     2        Decision making (perceptual choice)      \n",
      "WongWangExcInhStep       physiological     2        Resting-state BOLD/FC, E-I balance       \n",
      "MontbrioPazoRoxinStep    physiological     2        Exact QIF mean-field (theta neurons)     \n",
      "CoombesByrneStep         physiological     2        Next-gen mean-field, conductance synapses\n",
      "LarterBreakspearStep     physiological     3        Conductance-based limit cycles / chaos   \n",
      "EpileptorStep            physiological     6        Seizure onset/offset, epilepsy           \n",
      "KuramotoNetwork          network           1        Phase synchronization                    \n",
      "HORNStep                 network           2        Single coupled-oscillator step           \n",
      "HORNSeqLayer             network           2        Sequential HORN layer                    \n",
      "HORNSeqNetwork           network           2        Multi-layer HORN sequence network        \n"
     ]
    }
   ],
   "source": [
    "import brainmass\n",
    "\n",
    "# A curated registry of the models brainmass ships, with their category,\n",
    "# number of state variables, and a one-line use case.\n",
    "print(brainmass.list_models.to_table())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bf554a7",
   "metadata": {},
   "source": [
    "The ``category`` column is exactly the phenomenological / physiological /\n",
    "network split discussed above, and ``n_state_vars`` is how many ODEs each region\n",
    "costs you — from a single phase variable up to the six-variable Epileptor."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b49b051",
   "metadata": {},
   "source": [
    "## Where NMMs sit in whole-brain modelling\n",
    "\n",
    "A neural mass model is one component in a pipeline that turns anatomy into a\n",
    "predicted neuroimaging signal:\n",
    "\n",
    "$$\n",
    "\\underbrace{\\text{SC}}_{\\text{structural connectivity}}\n",
    "\\;\\longrightarrow\\;\n",
    "\\underbrace{\\text{NMM per region}}_{\\text{local dynamics}}\n",
    "\\;\\longrightarrow\\;\n",
    "\\underbrace{\\text{forward model}}_{\\text{biophysics of measurement}}\n",
    "\\;\\longrightarrow\\;\n",
    "\\underbrace{\\text{signal}}_{\\text{BOLD / EEG / MEG}}\n",
    "$$\n",
    "\n",
    "1. **Structural connectivity (SC).** A matrix of inter-region connection weights\n",
    "   (from diffusion MRI tractography), optionally with a distance matrix that sets\n",
    "   **conduction delays**. This is the wiring diagram.\n",
    "2. **A neural mass per region.** Each node runs its own NMM. Regions exchange\n",
    "   activity through the SC, usually as **diffusive** or **additive** coupling, with\n",
    "   delays from finite axonal conduction speed. The maths and intuition of coupling\n",
    "   live in {doc}`/concepts/coupling_and_delays`.\n",
    "3. **A forward model.** Neural activity is not measured directly. A\n",
    "   hemodynamic model turns it into **BOLD** (fMRI), and lead-field models project\n",
    "   dipolar source currents to **EEG/MEG** sensors. See\n",
    "   {doc}`/concepts/from_activity_to_signals`.\n",
    "4. **The signal.** The output you compare against data — and, in ``brainmass``,\n",
    "   the output you can *backpropagate through* to fit parameters.\n",
    "\n",
    "In ``brainmass`` these four stages map onto ``Network`` (SC + coupling + delays),\n",
    "the model classes (the per-region NMM), the forward/observation models, and the\n",
    "``Simulator`` / ``Fitter`` orchestration."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2dfeece4",
   "metadata": {},
   "source": [
    "## A small illustrative simulation\n",
    "\n",
    "To make the mean-field idea concrete, here is a single region modelled as a Hopf\n",
    "oscillator. With its bifurcation parameter $a > 0$ the region sustains a rhythm;\n",
    "its two state variables $(x, y)$ trace a limit cycle. This is the entire \"model\"\n",
    "— two ODEs standing in for a whole population of neurons."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b4c3f336",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-19T07:56:18.799778Z",
     "iopub.status.busy": "2026-06-19T07:56:18.799488Z",
     "iopub.status.idle": "2026-06-19T07:56:19.009817Z",
     "shell.execute_reply": "2026-06-19T07:56:19.009066Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x shape: (2500, 1)  y shape: (2500, 1)\n",
      "time runs from "
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "50.1 ms to 300. ms\n"
     ]
    }
   ],
   "source": [
    "import brainmass\n",
    "import brainunit as u\n",
    "\n",
    "# One region as a supercritical Hopf oscillator (a > 0 -> sustained rhythm).\n",
    "node = brainmass.HopfStep(in_size=1, a=0.25, w=0.3)\n",
    "\n",
    "res = brainmass.Simulator(node, dt=0.1 * u.ms).run(\n",
    "    300 * u.ms,\n",
    "    monitors=['x', 'y'],\n",
    "    transient=50 * u.ms,\n",
    ")\n",
    "\n",
    "# Two population-level state variables, sampled over time.\n",
    "print('x shape:', res['x'].shape, ' y shape:', res['y'].shape)\n",
    "print('time runs from', res['ts'][0], 'to', res['ts'][-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a0c49e84",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-19T07:56:19.012080Z",
     "iopub.status.busy": "2026-06-19T07:56:19.011840Z",
     "iopub.status.idle": "2026-06-19T07:56:19.215140Z",
     "shell.execute_reply": "2026-06-19T07:56:19.214183Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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WrGxserevXu2effv36+YmBjde++9io2NlZeXlx588EEtX77cJbGlpKTok08+0V133aU33nhDL730kk6cOKHo6Gj7jjAkJERTpkyRJHXq1EkzZszQjBkz1Llz56suNzd9/PXXX9W1a1fdc889evvtt1WyZEn17dvXqcJo4sSJaty4scaPH6/XXnvNPj6LFi1yaDdu3Dj16tVL3t7eGj9+vMaNG6dKlSpp1apVkqQJEyaoYsWKqlOnjr1/L7zwQo7rjImJ0dmzZ7Ot49y5c/r222/VtWvXHL+trlu3rsaPHy/pUoLLWk+rVq3Uq1cvXbx4UbNnz3aYJy0tTXPnzlWXLl2u+WuCFStWKDo6WomJiXrppZc0dOhQrV+/XnfccYf9IKR9+/YKCAjQl19+mW3+2bNn65ZbblH9+vUlSbt27VLz5s21Z88ejRw5Um+//baKFy+ujh07av78+dnmf/LJJ7V7926NGTNGI0eOzDHGa/X/WmbOnKnJkydryJAhGjZsmNauXatu3bpp9OjRWrJkiZ577jkNHDhQ3377rYYPH+4w74wZM+z9fuONN/Tiiy9q9+7duvPOO2/4hjsAbl5X5vUsQ4YM0fbt2zV27Fg98cQT+vbbbzV48GCHNtOmTVNAQICGDh2qiRMnqkmTJtn2nWlpaYqOjtaPP/6oIUOGaNKkSRo4cKB+//13JSUl2du9+uqr6t27t2rWrKl33nlHzzzzjFauXKlWrVo5tLuWbt266cKFC4qNjdV9992n9957TwMHDnRok5ucvm/fPvXo0UP33HOPJk6cqEaNGmnGjBny9fVVy5Yt7fv+xx57zGG+Bx98UOfOndNrr72mAQMGSJKWL1+u33//XY888ojef/99de/eXbNmzdJ99913zTOkucnpkpSenq5Nmzbptttuc2rMriYmJkaZmZl6/fXXFRERoVdeeUUTJkzQPffcowoVKuiNN95QjRo1NHz4cH3//fdXXc5jjz2me+65R5Ls8c+YMeOa6542bZrat2+vU6dOadSoUXr99dfVqFEjLVmyRJJydZxxvWVdK+4RI0bojjvu0MSJE/XII49o5syZio6OVnp6ukPbJk2aSJLDTetQABmgAJo6daqRZFasWGFOnDhhjhw5YmbNmmVKly5t/P39zdGjR822bduMJPPoo486zDt8+HAjyaxatco+rXLlykaS+eqrr+zTkpOTTfny5U3jxo3t08aOHWty+rPIiufAgQP2aa1btzatW7e2v7948aJJTU11mO+vv/4y5cqVM/369bNPO3HihJFkxo4dm209V64/L338/vvv7dMSExONr6+vGTZsWLZ1XencuXMO79PS0kz9+vXNP/7xD/u0/fv3Gw8PD9OpUyeTkZHh0D4zM9P+71tuucVhbLKsXr3aSDKrV6+2z1OhQgXTpUsXh3Zffvlltr5cOd6bNm0ykszUqVOzrScyMtJEREQ4TJs3b57Duq+mUaNGpmzZsubPP/+0T9u+fbvx8PAwvXv3tk/r0aOHKVu2rLl48aJ92h9//GE8PDzM+PHj7dPatGljGjRoYC5cuGCflpmZaVq0aGFq1qxpn5a1jd15550Oy7yaa/W/T58+pnLlyvb3Bw4cMJJMSEiISUpKsk8fNWqUkWQaNmxo0tPTHfrm4+Njj/n06dMmODjYDBgwwGE98fHxJigoKNt0ALiSM3n98nZRUVEOeeXZZ581np6eDvuwK/OWMcY89thjplixYvb919atW40kM2fOnKvGdvDgQePp6WleffVVh+k7duwwXl5e2aZfKSt3P/DAAw7Tn3zySSPJbN++3RiTt5y+ZMmSbOsrXry46dOnz1Xj6NGjR7bPchqr//73v9lybU7HO1fL6Tn59ddfjSTz/vvvZ/vsytxkjMl2PJTVh4EDB9qnXbx40VSsWNHYbDbz+uuv26f/9ddfxt/f32EssvLd5blx0KBBOR7b5SQpKcmUKFHCREREmPPnzzt8dvn26MxxhrPLunJc1q1bZySZmTNnOsyzZMmSHKcbY4yPj4954oknnOoj3IMz3SjQoqKiFBISokqVKql79+4KCAjQ/PnzVaFCBS1evFiSNHToUId5hg0bJknZzp6GhYWpU6dO9veBgYHq3bu3tm7d6pK7Pnp6etqvOc7MzNSpU6d08eJFNW3aVFu2bMnTMnPbx3r16qlly5b29yEhIapdu7Z+//33667L39/f/u+//vpLycnJatmypUPsCxYsUGZmpsaMGZPtuuy8XP9ls9n04IMPavHixTpz5ox9+uzZs1WhQgX7z+Jyq3fv3tqwYYP9DIp06SxvpUqV1Lp166vO98cff2jbtm3q27evSpUqZZ9+66236p577rH//5AufQufmJjocEO8uXPnKjMzUzExMZKkU6dOadWq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mZlpLxRuRkePHtWff/6p8uXLS7o5xskYo8GDB2v+/PlatWqVqlat6vC5M39nkZGR2rFjh8OBW1airFevXv50xGLXG6ecbNu2TZIctqeiPk45yczMVGpqKtsSXCIkJER16tS55svHxydP+29nttGvvvpK27dv17Zt27Rt2zZ98sknki4dCA8aNMjCnueOu8dJknbt2qW7775bffr00auvvmpdZ13Mx8dHTZo0cehfZmamVq5cedXjy8jISIf20qV9V1Z7Z47NChMrxkj6u+Dev3+/VqxYodKlS1vTgXxixTj16tVLP//8s30ftG3bNoWFhWnEiBFaunSpdZ3Jb26+kdtNZ9iwYWbNmjXmwIED5ocffjBRUVGmTJkyJjEx0Rhz6ZEV4eHhZtWqVeann34ykZGRJjIy0s1RW+/06dNm69atZuvWrUaSeeedd8zWrVvtd3d8/fXXTXBwsPn666/Nzz//bDp06JDjI8MaN25sNmzYYP73v/+ZmjVrFqlHYRlz7XE6ffq0GT58uImLizMHDhwwK1asMLfddpupWbOmuXDhgn0ZRX2cnnjiCRMUFGTWrFnj8Kirc+fO2dtc7+8s6zFPbdu2Ndu2bTNLliwxISEhReoxT9cbp19//dWMHz/e/PTTT+bAgQPm66+/NtWqVTOtWrWyL+NmGKeRI0eatWvXmgMHDpiff/7ZjBw50thsNrNs2TJjDNsS8tf19t9Hjx41tWvXNhs2bLBPy+1xxerVqwv13cuNsWacduzYYUJCQszDDz/ssM/MOn4r6GbNmmV8fX3NtGnTzO7du83AgQNNcHCw/ckKvXr1MiNHjrS3/+GHH4yXl5d56623zJ49e8zYsWNzfGTY9Y7NChNXj1FaWpp54IEHTMWKFc22bdsctpvC/PQKK7alKxXFu5dTdOezmJgYU758eePj42MqVKhgYmJizK+//mr//Pz58+bJJ580JUuWNMWKFTOdOnUyf/zxhxsjzh9ZSf7KV58+fYwxlx5N8eKLL5py5coZX19f06ZNG7Nv3z6HZfz555+mR48eJiAgwAQGBppHHnnEnD592g29sc61xuncuXOmbdu2JiQkxHh7e5vKlSubAQMGODyqyJiiP045jY8kM3XqVHsbZ/7ODh48aO69917j7+9vypQpY4YNG2bS09PzuTfWud44HT582LRq1cqUKlXK+Pr6mho1apgRI0Y4PKfbmKI/Tv369TOVK1c2Pj4+JiQkxLRp08ZecBvDtoT8db3994EDB4wks3r1avu03B5XFIWi24pxGjt2bI77zMqVK+djz27M+++/b8LDw42Pj49p1qyZ+fHHH+2ftW7d2n7MleXLL780tWrVMj4+PuaWW24xixYtcvjcmWOzwsaVY5S1neX0unzbK4xcvS1dqSgW3TZjjLHwRDoAAAAAADctrukGAAAAAMAiFN0AAAAAAFiEohsAAAAAAItQdAMAAAAAYBGKbgAAAAAALELRDQAAAACARSi6AQAAAACwCEU3AAAAAAAWoegGcMPWrFkjm82mpKQkd4cCAAAAFCg2Y4xxdxAACpe77rpLjRo10oQJEyRJaWlpOnXqlMqVKyebzebe4AAAAIACxMvdAQAo/Hx8fBQaGuruMAAAAIACh5+XA8iVvn37au3atZo4caJsNptsNpumTZvm8PPyadOmKTg4WAsXLlTt2rVVrFgxde3aVefOndNnn32mKlWqqGTJknrqqaeUkZFhX3ZqaqqGDx+uChUqqHjx4oqIiNCaNWvc01EAAG4iJ06cUGhoqF577TX7tPXr18vHx0crV650Y2RA4ceZbgC5MnHiRP3yyy+qX7++xo8fL0natWtXtnbnzp3Te++9p1mzZun06dPq3LmzOnXqpODgYC1evFi///67unTpojvuuEMxMTGSpMGDB2v37t2aNWuWwsLCNH/+fLVr1047duxQzZo187WfAADcTEJCQvTpp5+qY8eOatu2rWrXrq1evXpp8ODBatOmjbvDAwo1im4AuRIUFCQfHx8VK1bM/pPyvXv3ZmuXnp6uKVOmqHr16pKkrl27asaMGUpISFBAQIDq1aunu+++W6tXr1ZMTIwOHz6sqVOn6vDhwwoLC5MkDR8+XEuWLNHUqVMdvnkHAACud99992nAgAHq2bOnmjZtquLFiys2NtbdYQGFHkU3AEsUK1bMXnBLUrly5VSlShUFBAQ4TEtMTJQk7dixQxkZGapVq5bDclJTU1W6dOn8CRoAgJvcW2+9pfr162vOnDnavHmzfH193R0SUOhRdAOwhLe3t8N7m82W47TMzExJ0pkzZ+Tp6anNmzfL09PTod3lhToAALDOb7/9puPHjyszM1MHDx5UgwYN3B0SUOhRdAPINR8fH4cboLlC48aNlZGRocTERLVs2dKlywYAANeXlpamhx9+WDExMapdu7YeffRR7dixQ2XLlnV3aEChxt3LAeRalSpVtGHDBh08eFAnT560n62+EbVq1VLPnj3Vu3dvzZs3TwcOHNDGjRsVGxurRYsWuSBqAABwLS+88IKSk5P13nvv6bnnnlOtWrXUr18/d4cFFHoU3QBybfjw4fL09FS9evUUEhKiw4cPu2S5U6dOVe/evTVs2DDVrl1bHTt21KZNmxQeHu6S5QMAgJytWbNGEyZM0IwZMxQYGCgPDw/NmDFD69at05QpU9wdHlCo2Ywxxt1BAAAAAABQFHGmGwAAAAAAi1B0AwAAAABgEYpuAAAAAAAsQtENAAAAAIBFKLoBAAAAALAIRTcAAAAAABah6AYAAAAAwCIU3QAAAAAAWISiGwAAAAAAi1B0AwAAAABgEYpuAAAAAAAsQtENAAAAAIBF/h9t/Z5bi2gE0AAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1000x400 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import brainunit as u\n",
    "\n",
    "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n",
    "\n",
    "# Left: the two state variables versus time (the population rhythm).\n",
    "brainmass.viz.plot_timeseries(res['x'], ts=res['ts'], ax=ax1, labels=['x'])\n",
    "brainmass.viz.plot_timeseries(res['y'], ts=res['ts'], ax=ax1, labels=['y'])\n",
    "ax1.set_title('Population activity over time')\n",
    "\n",
    "# Right: the same trajectory in state space -> a limit cycle.\n",
    "brainmass.viz.plot_phase_portrait(res['x'][:, 0], res['y'][:, 0], ax=ax2)\n",
    "ax2.set_title('Phase portrait (limit cycle)')\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "520f1ca3",
   "metadata": {},
   "source": [
    "The left panel shows the population rhythm; the right shows that the two state\n",
    "variables settle onto a closed orbit — a **limit cycle**, the signature of a\n",
    "self-sustained oscillation. A single number, the bifurcation parameter $a$,\n",
    "controls whether this cycle exists at all. That is the power of the mean-field\n",
    "abstraction: rich, data-relevant dynamics from a tiny, tractable system."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4fea468",
   "metadata": {},
   "source": [
    "## Key takeaways\n",
    "\n",
    "- A neural mass model trades single-neuron detail for a **handful of\n",
    "  population-averaged ODEs** per region, justified by the mean-field\n",
    "  approximation.\n",
    "- A \"unit\" is a **population/region**, not a neuron — the right granularity for\n",
    "  whole-brain modelling and coarse neuroimaging data.\n",
    "- **Phenomenological** models capture qualitative dynamics with abstract\n",
    "  parameters; **physiological** (incl. next-generation exact) models keep\n",
    "  biophysical meaning. ``brainmass`` ships both.\n",
    "- An NMM is one stage of the whole-brain pipeline\n",
    "  **SC → NMM → forward model → signal**, and in ``brainmass`` the whole pipeline is\n",
    "  *differentiable*.\n",
    "\n",
    "## See also\n",
    "\n",
    "- {doc}`/concepts/why_differentiable` — why a differentiable JAX core changes how\n",
    "  you fit and train these models.\n",
    "- {doc}`/concepts/architecture_overview` — how the package realises the pipeline.\n",
    "- {doc}`/concepts/coupling_and_delays` — wiring regions together.\n",
    "- {doc}`/concepts/from_activity_to_signals` — turning activity into BOLD / EEG / MEG.\n",
    "- {doc}`/tutorials/index` — hands-on first simulations.\n",
    "\n",
    "## References\n",
    "\n",
    "- Wilson, H. R., & Cowan, J. D. (1972). Excitatory and inhibitory interactions in\n",
    "  localized populations of model neurons. *Biophysical Journal*, 12(1), 1–24.\n",
    "- Jansen, B. H., & Rit, V. G. (1995). Electroencephalogram and visual evoked\n",
    "  potential generation in a mathematical model of coupled cortical columns.\n",
    "  *Biological Cybernetics*, 73(4), 357–366.\n",
    "- Deco, G., Jirsa, V. K., Robinson, P. A., Breakspear, M., & Friston, K. (2008).\n",
    "  The dynamic brain: from spiking neurons to neural masses and cortical fields.\n",
    "  *PLoS Computational Biology*, 4(8), e1000092.\n",
    "- Montbrió, E., Pazó, D., & Roxin, A. (2015). Macroscopic description for networks\n",
    "  of spiking neurons. *Physical Review X*, 5(2), 021028."
   ]
  }
 ],
 "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
}
