{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# How to Use the Unit System\n", "\n", "**Important: The unit system is a feature under development. The following section might not work properly yet.**\n", "\n", "Here, we show some examples using the unit system in `ecell4`. This feature requires Python library, `pint`. Install `pint` before running this example as follows: `pip install pint`. See also the website https://pint.readthedocs.io/en/latest/." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "from ecell4.prelude import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## With no units\n", "\n", "First, imagine a very simple system only with binding and unbinding reactions like:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "with species_attributes():\n", " A | B | C | {'D': 1, 'radius': 0.005}\n", "\n", "with reaction_rules():\n", " A + B == C | (0.01, 0.3)\n", "\n", "m = get_model()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `species_attributes` section defines a diffusion constant and radius of `Species`, `A`, `B` and `C`. For example, the diffusion rate of `A` is `1`, and its dimensionality is expected to be `[length**2/time]`. However, what is the scale? Is it `meter`? Or `mile`?\n", "\n", "Once the base units are determined, e.g. `micrometer` as `[length]` and `second` as `[time]`, all the units must be consistent within the model. The second order rate consant must have dimensionality `[1/(substance/length**3)/time]`, which is `micrometer**3/item/second`. Thus, when the parameter is given as `1/molar/min` in some literature, you have to translate it by yourself." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A | {'D': 1, 'radius': 0.005}\n", "B | {'D': 1, 'radius': 0.005}\n", "C | {'D': 1, 'radius': 0.005}\n", "\n", "A + B > C | 0.01\n", "C > A + B | 0.3\n" ] } ], "source": [ "show(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introducing units\n", "\n", "`ecell4` provides the way to handle units in the modeling environment. Here is an example." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from ecell4.extra.unit import getUnitRegistry\n", "ureg = getUnitRegistry()\n", "Q_ = ureg.Quantity" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, create your own unit system,`ureg`, by using `ecell4.extra.unit.getUnitRegistry`. With this `UnitRegistry`, you can make a quantity with its unit as `ureg.Quantity(value, unit)`. (Please be careful about the type of `Quantity`. It looks same with `Quantity` given by `pint`, but is slightly changed in `ecell4` though all the original functionality in `pint` is availble even in `ecell4`. Please not use `ureg = pint.UnitRegistry()`.)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "with species_attributes():\n", " A | B | C | {'D': Q_(1, 'um**2/s'), 'radius': Q_(0.005, 'um')}\n", "\n", "with reaction_rules():\n", " A + B == C | (Q_(0.01, '1/(item/um**3)/s'), Q_(0.3, '1/s'))\n", "\n", "m = get_model()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default base units are `meter` for `[length]`, `second` for `[time]`, and `item` (which means the number of molecules) for `[substance]`. When you change the default base unit, do like `ureg = getUnitRegistry(length='micrometer')`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A | {'D': Quantity_Real(1e-12, 'meter ** 2 / second'), 'radius': Quantity_Real(5e-09, 'meter')}\n", "B | {'D': Quantity_Real(1e-12, 'meter ** 2 / second'), 'radius': Quantity_Real(5e-09, 'meter')}\n", "C | {'D': Quantity_Real(1e-12, 'meter ** 2 / second'), 'radius': Quantity_Real(5e-09, 'meter')}\n", "\n", "A + B > C | Quantity_Real(1e-20, 'meter ** 3 / item / second')\n", "C > A + B | Quantity_Real(0.3, '1 / second')\n" ] } ], "source": [ "show(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now you can provide quantities in any unit regardless of the base units." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A | {'D': Quantity_Real(1e-12, 'meter ** 2 / second'), 'radius': Quantity_Real(5e-09, 'meter')}\n", "B | {'D': Quantity_Real(1e-12, 'meter ** 2 / second'), 'radius': Quantity_Real(5e-09, 'meter')}\n", "C | {'D': Quantity_Real(1e-12, 'meter ** 2 / second'), 'radius': Quantity_Real(5e-09, 'meter')}\n", "\n", "A + B > C | Quantity_Real(1e-20, 'meter ** 3 / item / second')\n", "C > A + B | Quantity_Real(0.3, '1 / second')\n" ] } ], "source": [ "with species_attributes():\n", " A | B | C | {'D': Q_(1e-8, 'cm**2/s'), 'radius': Q_(5, 'nm')}\n", "\n", "with reaction_rules():\n", " A + B == C | (Q_(6.02214129, '1/uM/s'), Q_(18, '1/min'))\n", "\n", "m = get_model()\n", "show(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can operate quantities, and make a new quantity. See https://pint.readthedocs.io/en/latest/ for more details." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "60.221412900000004 item\n" ] } ], "source": [ "volume = Q_(1, 'fL')\n", "conc = Q_(100, 'nM')\n", "print((volume * conc).to('item'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In addition to the model creation, `run_simulation` (and `ensemble_simulations`) also supports the unit system." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "run_simulation(Q_(0.1, 'min'), y0={'C': Q_(60, 'item')}, volume=Q_(1, 'fL'), model=m, solver='ode')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Even if you change the base units, the behavior of simulations is kept consistent. In the following example, base units are rescaled to `micrometer` and `minute` with no change in the modeling section." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A | {'D': Quantity_Real(60, 'micrometer ** 2 / minute'), 'radius': Quantity_Real(0.005, 'micrometer')}\n", "B | {'D': Quantity_Real(60, 'micrometer ** 2 / minute'), 'radius': Quantity_Real(0.005, 'micrometer')}\n", "C | {'D': Quantity_Real(60, 'micrometer ** 2 / minute'), 'radius': Quantity_Real(0.005, 'micrometer')}\n", "\n", "A + B > C | Quantity_Real(0.6, 'micrometer ** 3 / item / minute')\n", "C > A + B | Quantity_Real(18, '1 / minute')\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "ureg = getUnitRegistry(length='micrometer', time='minute')\n", "Q_ = ureg.Quantity\n", "\n", "with species_attributes():\n", " A | B | C | {'D': Q_(1e-8, 'cm**2/s'), 'radius': Q_(5, 'nm')}\n", "\n", "with reaction_rules():\n", " A + B == C | (Q_(6.02214129, '1/uM/s'), Q_(18, '1/min'))\n", "\n", "m = get_model()\n", "show(m)\n", "run_simulation(Q_(0.1, 'min'), y0={'C': Q_(60, 'item')}, volume=Q_(1, 'fL'), model=m, solver='ode')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Checking dimensionality\n", "\n", "
\n", "\n", "This feature is still being developed. Please report issues when getting the wrong behavior.\n", "\n", "
\n", "\n", "You can check units in the model by `ecell4.extra.unit.check_model`.\n", "\n", "For example, the dimensionality of a diffusion constant must be `[length**2/time]`. When you give a unit with a wrong dimensionality, an exception `DimensionalityMismatchError` would be thrown as:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "from ecell4.extra.unit import check_model, DimensionalityMismatchError\n", "ureg = getUnitRegistry()\n", "Q_ = ureg.Quantity" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: Attribute [D] in Species [A] has wrong dimensionality. [[length]**2/[time]] is expected.\n" ] } ], "source": [ "with species_attributes():\n", " A | {'radius': Q_(0.005, 'um'), 'D': Q_(1.0, 'um/s')}\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When checking dimensionality of units in the model by `check_model`, you can omit no unit." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: Attribute [radius] in Species [A] has wrong dimensionality. [[length]] is expected.\n" ] } ], "source": [ "with species_attributes():\n", " A | {'radius': 0.005, 'D': Q_(1.0, 'um**2/s')}\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A kinetic rate constant of reactions is verified based on the order of the reaction. The first order reaction rate should have `[1/time]`, and the second order should have `[l/(substance/length**3)/time]` in volume." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: ReactionRule [A+B>C|0.3] has wrong dimensionality [1 / [time]]. [[length]**3/[substance]/[time]] is expected.\n" ] } ], "source": [ "with reaction_rules():\n", " A + B > C | Q_(0.3, '1/s')\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The dimensionality of a synthetic reaction depends on the dimension which the products belongs to." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: ReactionRule [>A|0.3] has wrong dimensionality [1 / [time]]. [[substance]/[time]/[length]**3] is expected.\n" ] } ], "source": [ "with reaction_rules():\n", " ~A > A | Q_(0.3, '1/s')\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An unit of the reaction rate between a molecule and structure is also tested." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: ReactionRule [A+M>B|0.3] has wrong dimensionality [1 / [time]]. [[length]**1/[time]] is expected.\n" ] } ], "source": [ "with species_attributes():\n", " B | {'location': 'M'}\n", " M | {'dimension': 2}\n", "\n", "with reaction_rules():\n", " A + M > B | Q_(0.3, '1/s')\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Additionally, rate law representations accept quantities with a unit too. See the example below:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "with reaction_rules():\n", " S > P | Q_(1.0, 'uM/s') * S / (Q_(100, 'nM') + S)\n", "\n", "check_model(get_model())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, the reaction above has two quantities, `Vmax = Q_(1.0, 'uM/s')` and `Km = Q_(100, 'nM')`. First, `Km` must have the same dimensionality with `S`, which is `[concentration]`." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: Failed to evaluate [((Quantity_Real(6.02214129e+20, 'item / meter ** 3 / second') * S) / (Quantity_Real(6.02214129e+19, 'item / meter ** 3 / second') + S))] (1*S>1*P|0). Cannot convert from 'item / meter ** 3 / second' ([substance] / [length] ** 3 / [time]) to 'item / meter ** 3' ([substance] / [length] ** 3)\n" ] } ], "source": [ "with reaction_rules():\n", " S > P | Q_(1.0, 'uM/s') * S / (Q_(100, 'nM/s') + S)\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Secondly, the dimensionality of a rate equation must be `[concentration/time]`. Therefore, the dimensionality of `Vmax` should be `[concentration/time]` too." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DimensionalityMismatchError: ReactionRule [1*S>1*P|0] has wrong dimensionality [1 / [time]]. [[substance]/[length]**3/[time]] is expected.\n" ] } ], "source": [ "with reaction_rules():\n", " S > P | Q_(1.0, '1/s') * S / (Q_(100, 'nM') + S)\n", "\n", "try:\n", " check_model(get_model())\n", "except DimensionalityMismatchError as e:\n", " print('{}: {}'.format(e.__class__.__name__, e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you give a value with no unit, it is regarded as `dimensionless`." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "S > P | ((Quantity_Real(6.02214129e+20, 'item / meter ** 3 / second') * pow(S, 2)) / (Quantity_Real(3.626618571672287e+39, 'item ** 2 / meter ** 6') + pow(S, 2)))\n" ] } ], "source": [ "with reaction_rules():\n", " S > P | 10.0 * Q_(0.1, 'uM/s') * S**2 / (Q_(100, 'nM')**2 + S**2)\n", "\n", "m = get_model()\n", "show(m)\n", "check_model(m)" ] } ], "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.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }