{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1607cbd0",
   "metadata": {},
   "source": [
    "# Cells\n",
    "\n",
    "A *cell* is the top-level object you simulate. `braincell` offers two cell\n",
    "classes for two modeling regimes, both descended from the common base\n",
    "{class}`braincell.HHTypedNeuron`.\n",
    "\n",
    "## Single-compartment vs. multi-compartment\n",
    "\n",
    "```{list-table}\n",
    ":header-rows: 1\n",
    ":widths: 24 38 38\n",
    "\n",
    "* -\n",
    "  - {class}`~braincell.SingleCompartment`\n",
    "  - {class}`~braincell.Cell`\n",
    "* - **Geometry**\n",
    "  - none — one isopotential point\n",
    "  - a full {class}`~braincell.Morphology`\n",
    "* - **Spatial structure**\n",
    "  - voltage is uniform\n",
    "  - voltage spreads along dendrites/axons\n",
    "* - **How you build it**\n",
    "  - subclass and add ions/channels in `__init__`\n",
    "  - instantiate, then `paint` and `place` declarations\n",
    "* - **Best for**\n",
    "  - channel prototyping, point-neuron networks, fitting\n",
    "  - dendritic computation, distributed channels, synaptic integration\n",
    "```\n",
    "\n",
    "Because both share the same ion, channel, and integrator machinery, the\n",
    "biophysics you learn in one transfers directly to the other.\n",
    "\n",
    "## Single-compartment cells\n",
    "\n",
    "A {class}`~braincell.SingleCompartment` treats the neuron as a single\n",
    "well-mixed compartment. You define one by subclassing and attaching mechanisms\n",
    "imperatively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67103eff",
   "metadata": {},
   "outputs": [],
   "source": [
    "import brainunit as u\n",
    "import braincell\n",
    "\n",
    "class HH(braincell.SingleCompartment):\n",
    "    def __init__(self, size, solver='exp_euler'):\n",
    "        super().__init__(size, solver=solver)\n",
    "\n",
    "        self.na = braincell.ion.SodiumFixed(size, E=50. * u.mV)\n",
    "        self.na.add(INa=braincell.channel.Na_HH1952(size))\n",
    "\n",
    "        self.k = braincell.ion.PotassiumFixed(size, E=-77. * u.mV)\n",
    "        self.k.add(IK=braincell.channel.K_HH1952(size))\n",
    "\n",
    "        self.IL = braincell.channel.IL(size, E=-54.387 * u.mV,\n",
    "                                       g_max=0.03 * (u.mS / u.cm ** 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc897c17",
   "metadata": {},
   "source": [
    "- `size` is a **batch dimension**: `HH(100)` simulates 100 independent neurons.\n",
    "- `solver` names the integrator (see {doc}`integration`).\n",
    "- Channels attach to the ion whose reversal potential drives them (see\n",
    "  {doc}`ions_channels`).\n",
    "\n",
    "You then `init_state()` and step the model with `brainstate`. The full runnable\n",
    "loop is in {doc}`../getting_started/first_steps`.\n",
    "\n",
    "## Multi-compartment cells\n",
    "\n",
    "A {class}`~braincell.Cell` wraps a morphology and is decorated declaratively.\n",
    "The pattern is **paint** (distribute a density mechanism over a region) and\n",
    "**place** (attach a point mechanism at a location):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b03f8f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import brainunit as u\n",
    "import braincell\n",
    "import braincell.mech as mech\n",
    "from braincell.filter import AllRegion, RootLocation, branch_in\n",
    "\n",
    "# 1. geometry\n",
    "morpho = braincell.Morphology.from_swc(\"neuron.swc\")\n",
    "cell = braincell.Cell(morpho)\n",
    "\n",
    "# 2. passive cable everywhere\n",
    "cell.paint(AllRegion(), mech.CableProperty(\n",
    "    resting_potential=-65. * u.mV,\n",
    "    membrane_capacitance=1.0 * u.uF / u.cm**2,\n",
    "    axial_resistivity=100. * u.ohm * u.cm,\n",
    "))\n",
    "\n",
    "# 3. channels onto regions\n",
    "cell.paint(AllRegion(), mech.Channel(\"IL\", g_max=0.0003 * u.S / u.cm**2, E=-70. * u.mV))\n",
    "cell.paint(branch_in(\"type\", \"soma\"), mech.Channel(\"Na_Ba2002\", g_max=0.12 * u.S / u.cm**2))\n",
    "\n",
    "# 4. stimulus at the soma\n",
    "cell.place(RootLocation(0.5),\n",
    "           mech.CurrentClamp(delay=10 * u.ms, durations=50 * u.ms, amplitudes=0.2 * u.nA))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e0e3c9f",
   "metadata": {},
   "source": [
    "`paint` targets a **region** (a set of cable); `place` targets a **locset** (a\n",
    "set of points). Those selection expressions come from {mod}`braincell.filter` —\n",
    "see {doc}`regions_locsets`. The mechanisms themselves are covered in\n",
    "{doc}`mechanisms`.\n",
    "\n",
    "```{note}\n",
    "The multi-compartment build-and-run pipeline (`Cell.run`, probe sampling) is\n",
    "under active development. The declarative `paint`/`place` front end shown here\n",
    "is stable; the worked multi-compartment notebooks in\n",
    "{doc}`../tutorials/index` track the current runnable workflow.\n",
    "```\n",
    "\n",
    "## The shared base: `HHTypedNeuron`\n",
    "\n",
    "Both classes inherit from {class}`braincell.HHTypedNeuron`, a\n",
    "Hodgkin–Huxley-style neuron that owns the integrator and the ion/channel\n",
    "registry. You rarely instantiate it directly, but it is the reason the two cell\n",
    "types feel so similar.\n",
    "\n",
    "## See also\n",
    "\n",
    "- {doc}`morphology` — building the geometry a `Cell` wraps.\n",
    "- {doc}`discretization` — how a `Cell`'s geometry becomes control volumes.\n",
    "- {doc}`../tutorials/index` — hands-on tutorials."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
