{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Reversible binding" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "nbsphinx": "hidden" }, "outputs": [], "source": [ "import random\n", "random.seed(0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can initialize a system of a simple reversible binding interaction as follows:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from pykappa.system import System\n", "\n", "system = System.from_kappa(\n", " mixture={\"A(x[.])\": 100, \"B(x[.])\": 100},\n", " rules=[\n", " \"A(x[.]), B(x[.]) -> A(x[1]), B(x[1]) @ 1\",\n", " \"A(x[1]), B(x[1]) -> A(x[.]), B(x[.]) @ 1\",\n", " ],\n", " observables={\"AB\": \"|A(x[1]), B(x[1])|\"},\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or equivalently from a .ka-style string:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "system = System.from_ka(\n", " \"\"\"\n", " %init: 100 A(x[.])\n", " %init: 100 B(x[.])\n", "\n", " %obs: 'AB' |A(x[1]), B(x[1])|\n", "\n", " A(x[.]), B(x[.]) <-> A(x[1]), B(x[1]) @ 1, 1\n", " \"\"\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "100 instances of molecules of type `A` and of type `B`, each with an empty binding domain `x`, are created, and we track the number of `AB` complexes.\n", "\n", "We're going to simulate this system and plot its behavior, marking certain times of interest. We'll first simulate until time 1:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "times = []\n", "while system.time < 1:\n", " system.update()\n", "times.append(system.time)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll now manually instantiate 50 new `A` and `B` molecules each, start tracking the number of free `A`, and simulate until there are no more than 10 free `A` in the mixture:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "system.mixture.instantiate(\"A(x[.]), B(x[.])\", 50)\n", "\n", "system[\"A\"] = \"|A(x[.])|\"\n", "while system[\"A\"] > 10:\n", " system.update()\n", "times.append(system.time)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's simulate some more time:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "while system.time < 2:\n", " system.update()\n", "times.append(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default simulator provides the most features since it’s written directly in Python, but models can be offloaded to [KaSim](https://github.com/Kappa-Dev/KappaTools), a compiled Kappa simulator, for faster simulation. For example, we could've run:\n", "```python\n", "system.update_via_kasim(time=1)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, let’s plot the history of the quantities we tracked:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "system.monitor.plot(combined=True)\n", "for time in times:\n", " plt.axvline(time, color=\"black\", linestyle=\"dotted\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The system equilibrates relatively early.\n", "Then new `A` is added and the number of `AB` complexes increases, reaching a higher equilibrium concentration." ] } ], "metadata": { "kernelspec": { "display_name": "kappa", "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.12.3" } }, "nbformat": 4, "nbformat_minor": 2 }