diff --git a/README.md b/README.md index 393b887..c63bc78 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,11 @@ Levels 0, 1, and 2 can recreate the _fast_ artefacts seen in patch clamp experim To fit experimental data, these fast artefacts are less important, and so **level 3 is good to match data from the fastest currents**. For slower currents, levels 4 or 5 can be used. +**For a quick overview of levels 5, 4, 3, and 0, see the [Model Tour](./tutorial/tour.ipynb).** + ## Tutorials -To understand these models, we provide [four tutorial notebooks](./tutorial/README.md). +To understand these models, we provide four [Tutorial Notebooks](./tutorial/README.md). The first derives a basic model of a patch clamp amplifier, and the second adds compensation and filtering, leading to the "Level 0" model. In the third notebook, this model is used to simulate the early stages of a (manual) patch-clamp experiment. diff --git a/tutorial/img/vc-level-3-post.png b/tutorial/img/vc-level-3-post.png new file mode 100644 index 0000000..4fdd584 Binary files /dev/null and b/tutorial/img/vc-level-3-post.png differ diff --git a/tutorial/img/vc-level-4-post.png b/tutorial/img/vc-level-4-post.png new file mode 100644 index 0000000..2683680 Binary files /dev/null and b/tutorial/img/vc-level-4-post.png differ diff --git a/tutorial/img/vc-level-5-post.png b/tutorial/img/vc-level-5-post.png new file mode 100644 index 0000000..ac1d5fb Binary files /dev/null and b/tutorial/img/vc-level-5-post.png differ diff --git a/tutorial/tour.ipynb b/tutorial/tour.ipynb new file mode 100644 index 0000000..6192c3e --- /dev/null +++ b/tutorial/tour.ipynb @@ -0,0 +1,355 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "cf0eda98", + "metadata": {}, + "source": [ + "# A quick tour of voltage-clamp models\n", + "\n", + "The voltage-clamp models are available in different levels of detail, ranging from the \"full\" model (level 0) to a greatly simplified one (level 5).\n", + "Here, we provide a quick tour of the most important models, and provide guidance for setting parameter values.\n", + "\n", + "_This notebook presents, but does not derive or explain the models. For that, please see the tutorial notebooks_." + ] + }, + { + "cell_type": "markdown", + "id": "c9f1d4b0-093e-40a3-aed5-765ecd37038b", + "metadata": {}, + "source": [ + "## Level 5 model\n", + "\n", + "This model calculates membrane potential $V_m$ from command potential $V_c$, and observed current $I_\\text{obs}$ from ionic current $I$.\n", + "\n", + "\n", + "\n", + "It includes:\n", + "\n", + "- A voltage offset $E^\\dagger_\\text{off}$, representing the remaining voltage error after zeroing\n", + "- A leak current $I_\\text{leak}$\n", + "- The effect of series resistance $R_s$ on the membrane potential\n", + "- Series resistance compensation, $\\alpha$, and prediction, $\\beta$, both specified as fractions between 0 and 1." + ] + }, + { + "cell_type": "markdown", + "id": "db45980e-56ec-4a79-b1f2-935834dcdb5c", + "metadata": {}, + "source": [ + "\\begin{align}\n", + "5.1. && C_m \\dot{V}_m = \\frac{V_c + E_\\text{off}^\\dagger - V_m}{(1 - \\beta) R_s} - \\frac{1 - \\alpha}{1 - \\beta}(I + I_\\text{leak})\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "5.2. && I_\\text{obs} = I + I_\\text{leak}\n", + "\\end{align}\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "6d59f32b-7b30-4c3e-b4a2-0484d787cf74", + "metadata": {}, + "source": [ + "| Variable | Units | Meaning |\n", + "|-----------------|-------|-----------------------------------------------------------|\n", + "| $V_m$ | mV | Membrane potential |\n", + "| $V_c$ | mV | The command potential, set by the voltage clamp protocol |\n", + "| $I$ | pA | The ionic current |\n", + "| $I_\\text{obs}$ | pA | The observed (measured/output) current |\n", + "| $I_\\text{leak}$ | pA | A leak current, e.g. $g_\\text{leak}(V_m - I_\\text{leak})$ |\n", + "\n", + "The variables $I$ and $I_\\text{leak}$ should be supplied by an ionic current model and leak model, respectively.\n", + "\n", + "| Parameter | Units | Meaning | Typical value |\n", + "|-----------|-----------|-----------------------------------------------------|-----------------|\n", + "| $C_m$ | pF | The cell capacitance, from the amplifier estimate | 25 pF |\n", + "| $R_s$ | G$\\Omega$ | The series resistance, from the amplifier estimate | 0.005 G$\\Omega$ |\n", + "| $\\alpha$ | - | Fraction of $R_s$ compensation, read from amplifier | 0.7 |\n", + "| $\\beta$ | - | Fraction of $R_s$ compensation, read from amplifier | 0.7 |\n", + "| $E^\\dagger_\\text{off}$ | mV | Remaining voltage offset after zeroing | 0 mV |\n", + "\n", + "In a simple simulation $E^\\dagger_\\text{off}$ is chosen by the user.\n", + "In inference settings, $E^\\dagger_\\text{off}$ may be a parameter inferred from the data." + ] + }, + { + "cell_type": "markdown", + "id": "1fd1aba6-145f-40e3-b757-fa509ffdf4e6", + "metadata": {}, + "source": [ + "## Level 4 model" + ] + }, + { + "cell_type": "markdown", + "id": "d987b0d8-8491-4ec4-96b7-93180d6292fd", + "metadata": {}, + "source": [ + "\n", + "\n", + "This level adds\n", + "\n", + "- A distinction between estimated and true membrane capacitance and series resistance\n", + "- A state-estimator used to approximate $V_e$ in the \"prediction\" pathway" + ] + }, + { + "cell_type": "markdown", + "id": "107f74b6-ed11-4fb2-b9bd-ec57f0940b91", + "metadata": {}, + "source": [ + "\\begin{align}\n", + "4.1. && C_m\\dot{V}_m = \\frac{V_c + E_\\text{off}^\\dagger - V_m - (\\alpha - \\beta) R_s^* C_m^* \\dot{V}_e}{R_s - \\alpha R_s^*} - I_\\text{leak} - I\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "4.2. && \\dot{V}_e &= \\frac{V_c - V_e}{(1 - \\beta) R_s^* C_m^*} \n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "4.3. && I_\\text{obs} = I + I_\\text{leak} + C_m \\dot{V}_m - C_m^* \\dot{V}_e\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "id": "bfa3cb04-e71e-442e-aee2-970c7ab3e975", + "metadata": {}, + "source": [ + "New or changed variables and parameters are\n", + "\n", + "| Variable | Units | Meaning |\n", + "|----------|-------|-------------------------------------------------------|\n", + "| $V_e$ | mV | An estimate of $V_m$ used in the \"prediction\" pathway |\n", + "\n", + "And\n", + "\n", + "| Parameter | Units | Meaning | Typical value |\n", + "|-----------|-----------|---------------------------------------------------------|-----------------|\n", + "| $C_m$ | pF | The true cell capacitance, unknown in real experiments | 25 pF |\n", + "| $C^*_m$ | pF | The estimated cell capacitance, read from amplifier | 25 pF |\n", + "| $R_s$ | G$\\Omega$ | The true series resistance, unknown in real experiments | 0.005 G$\\Omega$ |\n", + "| $R^*_s$ | G$\\Omega$ | The series resistance, read from amplifier | 0.005 G$\\Omega$ |\n", + "\n", + "For a straightforward simulation, $C_m$ and $R_s$ can be chosen by the user.\n", + "In an inference setting, $C_m$ and $R_s$ may be inferred from the data long with $E^\\dagger_\\text{off}$." + ] + }, + { + "cell_type": "markdown", + "id": "dceee631-de83-43c3-af45-7b18abb080a0", + "metadata": {}, + "source": [ + "## Level 3 model\n", + "\n", + "\n", + "\n", + "This level adds\n", + "\n", + "- An explicit measurement resistor $R_f$\n", + "- A first-order low-pass filter in the series resistance compensation pathway\n", + "- A first-order low-pass filter over the command potential (the \"stimulus filter\")\n", + "- A first-order low-pass filter over the output" + ] + }, + { + "cell_type": "markdown", + "id": "d00cfab5-45e6-4588-b0cd-5c1dae9a6401", + "metadata": {}, + "source": [ + "\\begin{align}\n", + "3.1. && C_m\\dot{V}_m = \\frac{V_r + E_\\text{off}^\\dagger - V_m}{R_s} - I_\\text{leak} - I\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "3.2. && V_r = V_s + \\alpha \\frac{R_s^*}{R_f} V_\\text{rc} + \\beta R_s^* C_m^* \\dot{V}_e\n", + " = \\alpha \\frac{R_s^*}{R_f} V_\\text{rc} + \\frac{V_s - \\beta V_e}{1 - \\beta}\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "3.3. && \\dot{V}_e &= \\frac{V_s - V_e}{(1 - \\beta)R_s^*C_m^*} \n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "3.4 && I_1 &= \\frac{V_r + E_\\text{off}^\\dagger - V_m}{R_s} - C_m^* \\dot{V_e}\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "3.5 && \\tau_\\text{rc} \\dot{V}_\\text{rc} &= R_f I_1 - V_\\text{rc}\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "3.6. && \\tau_s \\dot{V_s} = V_c - V_s\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "3.7. && \\tau_o \\dot{I}_\\text{obs} = I_1 - I_\\text{obs}\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "id": "c4845a2c-d7a9-4228-a456-28d2f297be46", + "metadata": {}, + "source": [ + "New variables and parameters are\n", + "\n", + "| Variable | Units | Meaning |\n", + "|----------|-------|-------------------------------------------------------------|\n", + "| $V_r$ | mV | The voltage on one side of the measurement electrode |\n", + "| $V_s$ | mV | The filtered command potential |\n", + "| $V_rc$ | mV | The filtered voltage used in series resistance compensation |\n", + "| $V_s$ | mV | The voltage on one side of the measurement electrode |\n", + "| $I_1$ | pA | The output current before filtering |\n", + "\n", + "And\n", + "\n", + "| Parameter | Unit | Meaning | Typical value |\n", + "|------------------|-----------|------------------------------------------------------------|---------------|\n", + "| $\\tau_\\text{RC}$ | ms | Time constant of filter in series resistance compenstation, read from amplifier|0.01 ms|\n", + "| $\\tau_s$ | ms | Time constant of stimlus filter, estimated from fits | 0.025 ms |\n", + "| $\\tau_o$ | ms | Time constant of 1st order approximation of output filter | 0.01 ms |\n", + "| $R_f$ | G$\\Omega$ | The measurement resistor, found in headstage documentation | 0.5 G$\\Omega$ |\n", + "\n", + "To estimate $\\tau_s$ in a real amplifier, you can record the filtered output voltage and fit to it.\n", + "The value above corresponds to the \"slow\" (default) setting on a HEKA EPC-10.\n", + "\n", + "To estimate $\\tau_o$, you can use $\\tau_o \\approx \\frac{1}{2 \\pi f}$, where $f$ is the filter's cut-off frequency in kHz.\n", + "\n", + "Note that exact values of $\\tau_s$ and $\\tau_o$ are seldom crucial." + ] + }, + { + "cell_type": "markdown", + "id": "f0982179-7da0-49d0-ae2f-a1ce724babe7", + "metadata": {}, + "source": [ + "## Level 0: The full model\n", + "\n", + "Next, we jump straight to the Level 0 model.\n", + "\n", + "\n", + "\n", + "This level adds\n", + "\n", + "- A pipette (conventional patch clamp) or parasitic (planar patch clamp) capacitance $C_p$, and its amplifier estimate $C^*p$\n", + "- A stray capacitance on the measurement resistor $\\tilde{C}_f$, and a finite op-amp speed with time constant $\\tau_a$\n", + "- A two-part output filter, where \"Filter 1\" affects series resistance compensation, while \"Filter 2\" does not.\n", + "- Arbitrary equations for the output filters and the stimulus filter (allowing e.g. Bessel formulations)" + ] + }, + { + "cell_type": "markdown", + "id": "175b67aa-e550-48f0-acea-c7656a812398", + "metadata": {}, + "source": [ + "\\begin{align}\n", + "0.1. && C_m\\dot{V}_m = \\frac{V_p + E_\\text{off}^\\dagger - V_m}{R_s} - I_\\text{leak} - I\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.2. && (C_p+\\tilde{C}_f)\\dot{V}_p = \\frac{V_o - V_p}{R_f} - \\frac{V_p + E_\\text{off}^\\dagger - V_m}{R_s} + \\tilde{C}_f\\dot{V}_o + C_m^* \\dot{V}_e + C_p^* \\dot{V}_r\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.3. && \\tau_a \\dot{V}_o = V_r - V_p\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.4. && V_r = V_s + \\alpha \\frac{R_s^*}{R_f} V_\\text{rc} + \\beta R_s^* C_m^* \\dot{V}_e\n", + " = \\alpha \\frac{R_s^*}{R_f} V_\\text{rc} + \\frac{V_s - \\beta V_e}{1 - \\beta}\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.5. && \\dot{V}_e &= \\frac{V_s - V_e}{(1 - \\beta)R_s^*C_m^*} \n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.6. && \\tau_\\text{rc} \\dot{V}_\\text{rc} = V_1 - V_\\text{rc}\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.7. && \\dot{V_s} = f_s(V_c, V_s)\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.8. && \\dot{V}_1 = f_1(V_o - V_r, V_1)\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.9. && \\dot{V}_2 = f_2(V_1, V_2)\n", + "\\end{align}\n", + "\n", + "\\begin{align}\n", + "0.10. && I_\\text{obs} = V_2 / R_f\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "id": "7cc410ae-a332-4fdd-9f04-459790d43ef2", + "metadata": {}, + "source": [ + "# TODO\n", + "\n", + "New variables and parameters are\n", + "\n", + "| Variable | Units | Meaning |\n", + "|----------|-------|-------------------------------------------------------------|\n", + "| $V_r$ | mV | The voltage on one side of the measurement electrode |\n", + "| $V_s$ | mV | The filtered command potential |\n", + "| $V_rc$ | mV | The filtered voltage used in series resistance compensation |\n", + "| $V_s$ | mV | The voltage on one side of the measurement electrode |\n", + "| $I_1$ | pA | The output current before filtering |\n", + "\n", + "And\n", + "\n", + "| Parameter | Unit | Meaning | Typical value |\n", + "|------------------|-----------|------------------------------------------------------------|---------------|\n", + "| $\\tau_\\text{RC}$ | ms | Time constant of filter in series resistance compenstation, read from amplifier|0.01 ms|\n", + "| $\\tau_s$ | ms | Time constant of stimlus filter, estimated from fits | 0.025 ms |\n", + "| $\\tau_o$ | ms | Time constant of 1st order approximation of output filter | 0.01 ms |\n", + "| $R_f$ | G$\\Omega$ | The measurement resistor, found in headstage documentation | 0.5 G$\\Omega$ |\n", + "\n", + "To estimate $\\tau_s$ in a real amplifier, you can record the filtered output voltage and fit to it.\n", + "The value above corresponds to the \"slow\" (default) setting on a HEKA EPC-10.\n", + "\n", + "To estimate $\\tau_o$, you can use $\\tau_o \\approx \\frac{1}{2 \\pi f}$, where $f$ is the filter's cut-off frequency in kHz.\n", + "\n", + "Note that exact values of $\\tau_s$ and $\\tau_o$ are seldom crucial." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2332084c-5e5d-4dc1-aed9-fdc3019ffe8b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}