{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d76bf35f",
   "metadata": {},
   "source": [
    "# Cell in BrainCell\n",
    "\n",
    "This notebook is the direct sequel to `1.morphology.ipynb`.\n",
    "\n",
    "In the previous tutorial, we focused on geometry and topology. Here we move one layer upward and ask a new question:\n",
    "\n",
    "**How does a morphology become a simulation-ready cell object?**\n",
    "\n",
    "We will focus on four ideas:\n",
    "\n",
    "1. Build a `Cell` directly from an existing morphology.\n",
    "2. Inspect control volumes (`CV`s), which are the basic structural units of the cell layer.\n",
    "3. Compare different `cv_policy` choices.\n",
    "4. Use the declarative APIs `paint(...)` and `place(...)`.\n",
    "\n",
    "To keep this notebook focused on the cell layer, we will load a ready-made morphology from `../../data/morphology/example_tree.swc` instead of rebuilding one by hand."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "29de2ae579fae760",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:00.973398300Z",
     "start_time": "2026-04-22T08:02:50.190416600Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ERROR:2026-04-25 19:08:31,720:jax._src.xla_bridge:444: Jax plugin configuration error: Exception when calling jax_plugins.xla_cuda12.initialize()\n",
      "Traceback (most recent call last):\n",
      "  File \"/home/swl/anaconda3/envs/braincell/lib/python3.10/site-packages/jax/_src/xla_bridge.py\", line 442, in discover_pjrt_plugins\n",
      "    plugin_module.initialize()\n",
      "  File \"/home/swl/anaconda3/envs/braincell/lib/python3.10/site-packages/jax_plugins/xla_cuda12/__init__.py\", line 324, in initialize\n",
      "    _check_cuda_versions(raise_on_first_error=True)\n",
      "  File \"/home/swl/anaconda3/envs/braincell/lib/python3.10/site-packages/jax_plugins/xla_cuda12/__init__.py\", line 257, in _check_cuda_versions\n",
      "    cublas_version = _version_check(\"cuBLAS\", cuda_versions.cublas_get_version,\n",
      "  File \"/home/swl/anaconda3/envs/braincell/lib/python3.10/site-packages/jax_plugins/xla_cuda12/__init__.py\", line 217, in _version_check\n",
      "    raise RuntimeError(msg)\n",
      "RuntimeError: Outdated cuBLAS installation found.\n",
      "Version JAX was built against: 120803\n",
      "Minimum supported: 120100\n",
      "Installed version: 120001\n",
      "The local installation version must be no lower than 120100.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "os.environ.setdefault(\"JAX_PLATFORMS\", \"cpu\")\n",
    "\n",
    "import braincell\n",
    "import brainstate\n",
    "import brainunit as u\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from braincell import Cell, Morphology\n",
    "from braincell import CVPerBranch, MaxCVLen\n",
    "from braincell.filter import BranchSlice, RootLocation, at\n",
    "from braincell.mech import CableProperty, Channel, CurrentClamp, StateProbe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "vis-palette-setup",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "VisDefaults(layout_2d_default='fan', shape_2d_default='frustum', mode_3d_default='geometry', branch_type_colors={'soma': (47, 49, 54), 'axon': (108, 142, 173), 'basal_dendrite': (190, 134, 111), 'apical_dendrite': (214, 173, 98), 'dendrite': (158, 170, 132), 'custom': (154, 164, 175)}, branch_type_edge_colors_2d=None, alpha_2d=0.8, alpha_2d_poly=None, alpha_2d_line=None, frustum_edge_linewidth_2d=0.9, alpha_3d_tube=1.0, highlight_color=(255, 215, 0), highlight_alpha=0.9, marker_color=(30, 144, 255), marker_size_2d=36.0, marker_radius_3d_um=1.5)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Keep any vis examples in this notebook aligned with the shared 2D/3D palette.\n",
    "braincell.vis.configure_defaults(\n",
    "    branch_type_colors={\n",
    "        \"soma\": \"#2f3136\",\n",
    "        \"axon\": \"#6c8ead\",\n",
    "        \"basal_dendrite\": \"#be866f\",\n",
    "        \"apical_dendrite\": \"#d6ad62\",\n",
    "        \"dendrite\": \"#9eaa84\",\n",
    "        \"custom\": \"#9aa4af\",\n",
    "    },\n",
    ")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f88955f9",
   "metadata": {},
   "source": [
    "## 1. From morphology to `Cell`\n",
    "\n",
    "A `Cell` starts from a morphology, but it adds an important new layer: **discretization**.\n",
    "\n",
    "Instead of working directly with whole branches, the cell layer works with **control volumes** (`CV`s). These are the structural units on which cable properties and mechanisms are assigned.\n",
    "\n",
    "The simplest entry point is therefore:\n",
    "\n",
    "- load a morphology\n",
    "- pass it into `Cell(...)`\n",
    "- inspect the resulting CV structure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b3cd6763",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:01.058398300Z",
     "start_time": "2026-04-22T08:03:00.976916900Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:00.830983Z",
     "iopub.status.busy": "2026-04-21T10:55:00.830647Z",
     "iopub.status.idle": "2026-04-21T10:55:00.850709Z",
     "shell.execute_reply": "2026-04-21T10:55:00.849374Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "soma\n",
      "├── axon_0\n",
      "│   └── axon_1\n",
      "└── basal_dendrite_0\n",
      "    ├── basal_dendrite_1\n",
      "    │   ├── basal_dendrite_2\n",
      "    │   └── basal_dendrite_3\n",
      "    ├── basal_dendrite_4\n",
      "    └── basal_dendrite_5\n",
      "Cell(root='soma', n_branches=9, n_paint_rules=1, n_place_rules=0, initialized=False)\n"
     ]
    }
   ],
   "source": [
    "morpho = Morphology.from_swc(\"../../data/morphology/example_tree.swc\")\n",
    "\n",
    "print(morpho.topo())\n",
    "\n",
    "cell = Cell(morpho)\n",
    "print(cell)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a724a7fd",
   "metadata": {},
   "source": [
    "### Useful `Cell` summary fields\n",
    "\n",
    "The compact string form of `Cell` shows a few high-level counters.\n",
    "\n",
    "| Field | Meaning |\n",
    "| --- | --- |\n",
    "| `root` | Name of the root branch in the cloned morphology |\n",
    "| `n_branches` | Total number of morphology branches inside the cell |\n",
    "| `n_paint_rules` | Number of recorded `paint(...)` declarations, including the default global cable-property rule |\n",
    "| `n_place_rules` | Number of recorded `place(...)` declarations |\n",
    "\n",
    "The preview count `cell.n_cv` (and the full CV tuple `cell.cvs`) is computed lazily from the policy and paint rules — it is not part of the repr but is always available as a property."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "b7cf9abc",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:01.135373800Z",
     "start_time": "2026-04-22T08:03:01.077018400Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:00.852958Z",
     "iopub.status.busy": "2026-04-21T10:55:00.852772Z",
     "iopub.status.idle": "2026-04-21T10:55:00.856722Z",
     "shell.execute_reply": "2026-04-21T10:55:00.855785Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "n_cv: 9\n",
      "len(cell.cvs): 9\n",
      "first three CV intervals:\n",
      "  CV 0: branch_id=0, branch_type=soma, prox=0.0, dist=1.0\n",
      "  CV 1: branch_id=1, branch_type=axon, prox=0.0, dist=1.0\n",
      "  CV 2: branch_id=2, branch_type=axon, prox=0.0, dist=1.0\n"
     ]
    }
   ],
   "source": [
    "print(\"n_cv:\", cell.n_cv)\n",
    "print(\"len(cell.cvs):\", len(cell.cvs))\n",
    "print(\"first three CV intervals:\")\n",
    "for cv in cell.cvs[:3]:\n",
    "    print(f\"  CV {cv.id}: branch_id={cv.branch_id}, branch_type={cv.branch_type}, prox={cv.prox}, dist={cv.dist}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35db2a12",
   "metadata": {},
   "source": [
    "## 2. What is a `CV`?\n",
    "\n",
    "A `CV` (control volume) is the basic structural object in the cell layer.\n",
    "\n",
    "Conceptually, one CV corresponds to one interval on one branch. It stores:\n",
    "\n",
    "- geometry, such as length and area\n",
    "- cable properties, such as `cm`, `ra`, `v`, and `temp`\n",
    "- topology, such as parent/child CV relationships\n",
    "- attached mechanisms, split into `density_mech` and `point_mech`\n",
    "\n",
    "In other words, morphology tells us **where the cable is**, while CVs tell us **where the cell model will actually live**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe8aeb98",
   "metadata": {},
   "source": [
    "### Useful `CV` attributes\n",
    "\n",
    "| Attribute | Meaning |\n",
    "| --- | --- |\n",
    "| `id` | Unique CV index within the cell |\n",
    "| `branch_id` | Which morphology branch this CV belongs to |\n",
    "| `branch_type` | The branch type, such as `soma` or `basal_dendrite` |\n",
    "| `prox` | Proximal boundary of the CV on its branch, in normalized branch coordinates |\n",
    "| `dist` | Distal boundary of the CV on its branch, in normalized branch coordinates |\n",
    "| `parent_cv` | Parent CV id, or `None` for the root CV |\n",
    "| `children_cv` | Child CV ids attached downstream |\n",
    "| `length` | Physical length of this CV |\n",
    "| `area` | Membrane area of this CV |\n",
    "| `cm` | Membrane capacitance density at the CV midpoint |\n",
    "| `ra` | Axial resistivity at the CV midpoint |\n",
    "| `v` | Resting / initial membrane potential at the CV midpoint |\n",
    "| `temp` | Temperature stored at the CV midpoint |\n",
    "| `r_axial` | Total axial resistance across the CV |\n",
    "| `r_axial_prox` | Axial resistance from the midpoint to the proximal end |\n",
    "| `r_axial_dist` | Axial resistance from the midpoint to the distal end |\n",
    "| `density_mech` | Density mechanisms assigned to this CV |\n",
    "| `point_mech` | Point mechanisms assigned to this CV |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "386f6dbd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:01.273817200Z",
     "start_time": "2026-04-22T08:03:01.158273700Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:00.859573Z",
     "iopub.status.busy": "2026-04-21T10:55:00.859239Z",
     "iopub.status.idle": "2026-04-21T10:55:00.929982Z",
     "shell.execute_reply": "2026-04-21T10:55:00.928751Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CV(id=0, branch_id=0, branch_type='soma', prox=0.0, dist=1.0, parent_cv=None, children_cv=(1, 3), length=Quantity(10., \"um\"), area=Quantity(314.15927, \"um^2\"), cm=Quantity(1., \"uF / cm^2\"), ra=Quantity(100., \"cm * ohm\"), v=Quantity(-65., \"mV\"), temp=Quantity(309.15, \"K\"), r_axial=Quantity(127323.95, \"ohm\"), r_axial_prox=Quantity(63661.977, \"ohm\"), r_axial_dist=Quantity(63661.977, \"ohm\"), radius_prox=Quantity(5., \"um\"), radius_mid=Quantity(5., \"um\"), radius_dist=Quantity(5., \"um\"), density_mech=(), point_mech=())\n",
      "id: 0\n",
      "branch_id: 0\n",
      "branch_type: soma\n",
      "parent_cv: None\n",
      "children_cv: (1, 3)\n",
      "length: 10. um\n",
      "area: 314.15927 um^2\n",
      "r_axial: 127323.95 ohm\n",
      "cm: 1. uF / cm^2\n",
      "ra: 100. cm * ohm\n",
      "v: -65. mV\n",
      "temp: 309.15 K\n",
      "density_mech: ()\n",
      "point_mech: ()\n"
     ]
    }
   ],
   "source": [
    "cv0 = cell.cvs[0]\n",
    "print(cv0)\n",
    "\n",
    "# Identity and topology.\n",
    "print(\"id:\", cv0.id)\n",
    "print(\"branch_id:\", cv0.branch_id)\n",
    "print(\"branch_type:\", cv0.branch_type)\n",
    "print(\"parent_cv:\", cv0.parent_cv)\n",
    "print(\"children_cv:\", cv0.children_cv)\n",
    "\n",
    "# Geometry.\n",
    "print(\"length:\", cv0.length)\n",
    "print(\"area:\", cv0.area)\n",
    "print(\"r_axial:\", cv0.r_axial)\n",
    "\n",
    "# Cable properties defined at the CV midpoint.\n",
    "print(\"cm:\", cv0.cm)\n",
    "print(\"ra:\", cv0.ra)\n",
    "print(\"v:\", cv0.v)\n",
    "print(\"temp:\", cv0.temp)\n",
    "\n",
    "# Mechanism containers are empty at this stage.\n",
    "print(\"density_mech:\", cv0.density_mech)\n",
    "print(\"point_mech:\", cv0.point_mech)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a597444",
   "metadata": {},
   "source": [
    "## 3. CV policies\n",
    "\n",
    "The morphology does not uniquely determine the number of CVs. That job belongs to the **CV policy**.\n",
    "\n",
    "Three useful cases are:\n",
    "\n",
    "- `Cell(morpho)`: use the default `CVPerBranch()` policy\n",
    "- `Cell(morpho, cv_policy=CVPerBranch(cv_per_branch=2))`: force every branch to use two CVs\n",
    "- `Cell(morpho, cv_policy=MaxCVLen(max_cv_len=...))`: choose the number of CVs automatically from physical branch length\n",
    "\n",
    "This is the main structural knob of the cell layer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c1a7a2f5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:01.355108600Z",
     "start_time": "2026-04-22T08:03:01.276825400Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:00.931992Z",
     "iopub.status.busy": "2026-04-21T10:55:00.931812Z",
     "iopub.status.idle": "2026-04-21T10:55:00.958025Z",
     "shell.execute_reply": "2026-04-21T10:55:00.957161Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "default policy\n",
      "Cell(root='soma', n_branches=9, n_paint_rules=1, n_place_rules=0, initialized=False)\n",
      "\n",
      "CVPerBranch(cv_per_branch=2)\n",
      "Cell(root='soma', n_branches=9, n_paint_rules=1, n_place_rules=0, initialized=False)\n",
      "\n",
      "MaxCVLen(max_cv_len=20 um)\n",
      "Cell(root='soma', n_branches=9, n_paint_rules=1, n_place_rules=0, initialized=False)\n",
      "\n",
      "first four CV intervals under CVPerBranch(cv_per_branch=2):\n",
      "  CV 0: branch_id=0, prox=0.0, dist=0.5\n",
      "  CV 1: branch_id=0, prox=0.5, dist=1.0\n",
      "  CV 2: branch_id=1, prox=0.0, dist=0.5\n",
      "  CV 3: branch_id=1, prox=0.5, dist=1.0\n"
     ]
    }
   ],
   "source": [
    "default_cell = Cell(morpho)\n",
    "split_cell = Cell(morpho, cv_policy=CVPerBranch(cv_per_branch=2))\n",
    "auto_cell = Cell(morpho, cv_policy=MaxCVLen(max_cv_len=20.0 * u.um))\n",
    "\n",
    "print(\"default policy\")\n",
    "print(default_cell)\n",
    "print()\n",
    "print(\"CVPerBranch(cv_per_branch=2)\")\n",
    "print(split_cell)\n",
    "print()\n",
    "print(\"MaxCVLen(max_cv_len=20 um)\")\n",
    "print(auto_cell)\n",
    "print()\n",
    "print(\"first four CV intervals under CVPerBranch(cv_per_branch=2):\")\n",
    "for cv in split_cell.cvs[:4]:\n",
    "    print(f\"  CV {cv.id}: branch_id={cv.branch_id}, prox={cv.prox}, dist={cv.dist}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b9c74db",
   "metadata": {},
   "source": [
    "## 4. The node tree\n",
    "\n",
    "A `Cell` holds only declarations. The execution-oriented view — the **node tree** — is built later, together with all runtime state, by calling `cell.init_state()`, which flips the cell into its INITIALIZED phase.\n",
    "\n",
    "For this tutorial you only need two facts:\n",
    "\n",
    "- `cell.cvs` is the membrane-oriented view, available directly on the declaration\n",
    "- `cell.node_tree` is the point/edge execution view, available after `cell.init_state()` runs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1422bb5b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:02.934865400Z",
     "start_time": "2026-04-22T08:03:01.375920100Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:00.960038Z",
     "iopub.status.busy": "2026-04-21T10:55:00.959849Z",
     "iopub.status.idle": "2026-04-21T10:55:01.594185Z",
     "shell.execute_reply": "2026-04-21T10:55:01.593518Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-----------------------------------\n",
      "n_nodes       | 28\n",
      "n_edges        | 27\n",
      "root_node_id  | 0\n",
      "-----------------------------------\n",
      "\n",
      "n_nodes: 28\n",
      "n_edges: 27\n",
      "expected n_nodes = n_cv + n_branches + 1: 28\n"
     ]
    }
   ],
   "source": [
    "split_cell.init_state()\n",
    "node_tree = split_cell.node_tree\n",
    "print(node_tree)\n",
    "print(\"n_nodes:\", len(node_tree.nodes))\n",
    "print(\"n_edges:\", len(node_tree.edges))\n",
    "print(\"expected n_nodes = n_cv + n_branches + 1:\", split_cell.n_cv + len(split_cell.morpho.branches) + 1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4ca5c0c",
   "metadata": {},
   "source": [
    "## 5. `paint(...)`: declarative region-based assignment\n",
    "\n",
    "`paint(...)` is the main API for assigning properties or density mechanisms over a region of the cell.\n",
    "\n",
    "Its general shape is:\n",
    "\n",
    "- `cell.paint(region, *mechanisms)`\n",
    "\n",
    "Here:\n",
    "\n",
    "- `region` is a region expression such as `BranchSlice(...)`\n",
    "- the remaining arguments are declarative mechanism objects\n",
    "\n",
    "A useful mental model is that `paint(...)` does not directly run a mechanism. It **declares** what should exist on which part of the cell."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ef9f85f",
   "metadata": {},
   "source": [
    "### Painting cable properties\n",
    "\n",
    "Every `Cell` starts with one default global cable-property rule. A later `paint(...)` call can locally override those midpoint properties on the CVs that fall inside the painted region."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f6e7f718c99e22d3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:03.141529200Z",
     "start_time": "2026-04-22T08:03:03.002517800Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:01.596743Z",
     "iopub.status.busy": "2026-04-21T10:55:01.596419Z",
     "iopub.status.idle": "2026-04-21T10:55:01.619970Z",
     "shell.execute_reply": "2026-04-21T10:55:01.619252Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cell(root='soma', n_branches=9, n_paint_rules=2, n_place_rules=0, initialized=False)\n",
      "painted soma CV example:\n",
      "v: -70. mV\n",
      "cm: 2. uF / cm^2\n",
      "ra: 200. cm * ohm\n",
      "temp: 293.15 K\n"
     ]
    }
   ],
   "source": [
    "cable_cell = Cell(morpho, cv_policy=CVPerBranch(cv_per_branch=2))\n",
    "cable_cell.paint(\n",
    "    BranchSlice(branch_index=0, prox=0.0, dist=1.0),\n",
    "    CableProperty(\n",
    "        resting_potential=-70.0 * u.mV,\n",
    "        membrane_capacitance=2.0 * (u.uF / u.cm ** 2),\n",
    "        axial_resistivity=200.0 * (u.ohm * u.cm),\n",
    "        temperature=u.celsius2kelvin(20.0),\n",
    "    ),\n",
    ")\n",
    "\n",
    "print(cable_cell)\n",
    "print(\"painted soma CV example:\")\n",
    "print(\"v:\", cable_cell.cvs[0].v)\n",
    "print(\"cm:\", cable_cell.cvs[0].cm)\n",
    "print(\"ra:\", cable_cell.cvs[0].ra)\n",
    "print(\"temp:\", cable_cell.cvs[0].temp)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52e2fc1a",
   "metadata": {},
   "source": [
    "### Painting a density mechanism\n",
    "\n",
    "A density mechanism is distributed over a region rather than attached to a single point.\n",
    "\n",
    "In the example below, `Channel(\"IL\", ...)` is a declarative channel specification. The cell runtime lowers it into a dense layout over the active CV midpoints."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ca83b927af189041",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:03.971485800Z",
     "start_time": "2026-04-22T08:03:03.143506400Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:01.622032Z",
     "iopub.status.busy": "2026-04-21T10:55:01.621740Z",
     "iopub.status.idle": "2026-04-21T10:55:02.189694Z",
     "shell.execute_reply": "2026-04-21T10:55:02.188719Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "layout.kind: channel:IL\n",
      "layout.target: density\n",
      "layout.n_active: 2\n",
      "layout.source_cv_ids: (0, 1)\n",
      "layout.point_index: [1, 3]\n",
      "sample g_max at one active point: 4. mS / cm^2\n",
      "sample E at one active point: -68. mV\n"
     ]
    }
   ],
   "source": [
    "channel_cell = Cell(morpho)\n",
    "channel_cell.paint(\n",
    "    BranchSlice(branch_index=[0, 1], prox=0.0, dist=1.0),\n",
    "    Channel(\"IL\", g_max=4.0 * (u.mS / u.cm ** 2), E=-68.0 * u.mV),\n",
    ")\n",
    "\n",
    "# All runtime inspection — layouts, per-point state — lives on the Cell after init_state().\n",
    "channel_cell.init_state()\n",
    "layout = channel_cell.layouts[0]\n",
    "point_id = int(layout.point_index[0])\n",
    "\n",
    "print(\"layout.kind:\", layout.kind)\n",
    "print(\"layout.target:\", layout.target)\n",
    "print(\"layout.n_active:\", layout.n_active)\n",
    "print(\"layout.source_cv_ids:\", layout.source_cv_ids)\n",
    "print(\"layout.point_index:\", layout.point_index.tolist())\n",
    "print(\"sample g_max at one active point:\", channel_cell.get_point_state(point_id)[layout.id][\"g_max\"])\n",
    "print(\"sample E at one active point:\", channel_cell.get_point_state(point_id)[layout.id][\"E\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd19c76d",
   "metadata": {},
   "source": [
    "## 6. `place(...)`: declarative point mechanisms\n",
    "\n",
    "`place(...)` is the companion API for mechanisms that should live at a single location instead of over a region.\n",
    "\n",
    "Its general shape is:\n",
    "\n",
    "- `cell.place(locset, *mechanisms)`\n",
    "\n",
    "Here:\n",
    "\n",
    "- `locset` is a location expression such as `RootLocation(...)`\n",
    "- the remaining arguments are point mechanisms such as `CurrentClamp`\n",
    "\n",
    "This is the right API for clamps, probes, and other point-like declarations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "688559d4a5c8b095",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:04.138005200Z",
     "start_time": "2026-04-22T08:03:04.003428200Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:02.192066Z",
     "iopub.status.busy": "2026-04-21T10:55:02.191851Z",
     "iopub.status.idle": "2026-04-21T10:55:02.244902Z",
     "shell.execute_reply": "2026-04-21T10:55:02.243949Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cell(root='soma', n_cv=18, n_point=28, initialized=True)\n",
      "layout.kind: CurrentClamp\n",
      "layout.target: point\n",
      "layout.n_active: 1\n",
      "layout.point_index: [2]\n",
      "amplitudes: [[0.1]] nA\n",
      "durations: [[2.]] ms\n",
      "delay: [1.] ms\n"
     ]
    }
   ],
   "source": [
    "place_cell = Cell(morpho, cv_policy=CVPerBranch(2))\n",
    "place_cell.place(\n",
    "    RootLocation(x=0.5),\n",
    "    CurrentClamp(delay=1.0 * u.ms, durations=2.0 * u.ms, amplitudes=0.1 * u.nA),\n",
    ")\n",
    "\n",
    "place_cell.init_state()\n",
    "layout = place_cell.layouts[0]\n",
    "\n",
    "print(place_cell)\n",
    "print(\"layout.kind:\", layout.kind)\n",
    "print(\"layout.target:\", layout.target)\n",
    "print(\"layout.n_active:\", layout.n_active)\n",
    "print(\"layout.point_index:\", layout.point_index.tolist())\n",
    "print(\"amplitudes:\", place_cell.get_state(layout.id, \"amplitudes\"))\n",
    "print(\"durations:\", place_cell.get_state(layout.id, \"durations\"))\n",
    "print(\"start:\", place_cell.get_state(layout.id, \"start\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2baeb494",
   "metadata": {},
   "source": [
    "## 7. A minimal simulation\n",
    "\n",
    "So far we have only declared structure and mechanisms. To actually run the cell, we follow a two-step recipe:\n",
    "\n",
    "1. Call `cell.init_state()` to lower the declaration and allocate runtime state on the same `Cell`.\n",
    "2. Call `cell.run(dt=..., duration=...)` to advance it over time. (`run` auto-calls `init_state()` on first use.)\n",
    "\n",
    "`Cell` has two phases: DECLARING (paint/place/config mutable) and INITIALIZED (runtime surface live). `reset()` returns a cell to DECLARING while keeping paint/place rules so you can re-initialize.\n",
    "\n",
    "We use a simple HH-style configuration:\n",
    "\n",
    "- passive leak current `IL`\n",
    "- sodium current `Nav1p6_MA24_PC`\n",
    "- potassium current `IK_HH1952`\n",
    "- a point current clamp at the root midpoint\n",
    "- a `StateProbe` on the soma recording membrane voltage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "457d3a26fa45e810",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2026-04-22T08:03:09.659651Z",
     "start_time": "2026-04-22T08:03:04.141035500Z"
    },
    "execution": {
     "iopub.execute_input": "2026-04-21T10:55:02.246839Z",
     "iopub.status.busy": "2026-04-21T10:55:02.246661Z",
     "iopub.status.idle": "2026-04-21T10:55:05.872572Z",
     "shell.execute_reply": "2026-04-21T10:55:05.871559Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sim_cell = Cell(\n",
    "    morpho,\n",
    "    cv_policy=CVPerBranch(cv_per_branch=2),\n",
    "    solver=\"staggered\",\n",
    ")\n",
    "\n",
    "sim_cell.paint(\n",
    "    BranchSlice(branch_index=[0, 1], prox=0.0, dist=1.0),\n",
    "    Channel(\"IL\", g_max=0.03 * (u.mS / u.cm ** 2), E=-54.387 * u.mV),\n",
    "    Channel(\"Na_HH1952\", g_max=120.0 * (u.mS / u.cm ** 2)),\n",
    "    Channel(\"K_HH1952\", g_max=36.0 * (u.mS / u.cm ** 2)),\n",
    ")\n",
    "\n",
    "sim_cell.place(\n",
    "    RootLocation(x=0.5),\n",
    "    CurrentClamp(delay=20.0 * u.ms, durations=60.0 * u.ms, amplitudes=0.2 * u.nA),\n",
    ")\n",
    "\n",
    "sim_cell.place(\n",
    "    at(\"soma\", 0.5),\n",
    "    StateProbe(),\n",
    ")\n",
    "\n",
    "sim_cell.init_state()\n",
    "sim_cell.reset_state()\n",
    "# init_state() already called above\n",
    "\n",
    "dt = 0.1 * u.ms\n",
    "duration = 100.0 * u.ms\n",
    "\n",
    "result1 = sim_cell.run(dt=dt, duration=duration)\n",
    "\n",
    "times_ms = u.math.concatenate([result1.time])\n",
    "vs_mV = u.math.concatenate([\n",
    "    result1.traces[\"soma(0.5)_v\"],\n",
    "])\n",
    "\n",
    "\n",
    "plt.rcParams['font.family'] = 'DejaVu Sans'\n",
    "plt.style.use('default')\n",
    "fig, ax = plt.subplots(figsize=(6, 4))\n",
    "line, = ax.plot(times_ms, vs_mV, label=\"soma(0.5)_v\", linewidth=2, color=\"#f8a413\")\n",
    "ax.fill_between(times_ms, vs_mV, alpha=0., color=\"#ffffff\") \n",
    "# ax.set_xlabel(\"Time (ms)\", fontsize=14)\n",
    "# ax.set_ylabel(\"Voltage (mV)\", fontsize=14)\n",
    "ax.legend(frameon=True, fancybox=True, shadow=True, loc='best')\n",
    "ax.grid(True, linestyle='-', alpha=0.15, linewidth=0.5)\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "\n",
    "\n",
    "# fig, axes = plt.subplots(1, 1, figsize=(5, 5))\n",
    "# sim_cell.vis_cv(\n",
    "#     value=\"V\",\n",
    "#     cmap=\"viridis\",\n",
    "#     vmin=-80.0,\n",
    "#     vmax=-40.0,\n",
    "#     value_label=\"Voltage\",\n",
    "#     ax=axes,  # note: with subplots(1, 1), axes is a single object, not a list\n",
    "#     show=False,\n",
    "# )\n",
    "# plt.show()  # add this line to render"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aad7ae91",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "You have now seen the main ideas of the cell layer in BrainCell:\n",
    "\n",
    "- A `Cell` starts in DECLARING — morphology, CV policy, `paint(...)` rules, `place(...)` rules are freely mutable. `init_state()` transitions it to INITIALIZED, where the runtime surface is live.\n",
    "- Discretization produces a list of `CV`s; the CV policy is the main structural knob.\n",
    "- `cell.init_state()` lowers the declaration and allocates the runtime (node tree, layouts, integrator state, probes) on the same `Cell`.\n",
    "- All runtime inspection (`layouts`, `get_point_state(...)`, `get_state(...)`, `node_tree`, `run(...)`, `current_time`, `sample_probes()`) is available on the `Cell` after `init_state()` (and raises `RuntimeError` in DECLARING).\n",
    "- Building twice produces two independent runnables, so a single declaration can seed many parallel simulations.\n",
    "\n",
    "A natural next step is `3.vis.ipynb`, where the structural and runtime views become easier to inspect visually."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "braincell",
   "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.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
