{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "e1699266", "metadata": {}, "source": [ "# Simple SBML example\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ef7315d5", "metadata": {}, "source": [ "This notebook creates a simple model in [SBML version 3 level 1](https://synonym.caltech.edu/documents/specifications/level-3/version-1/core/release-3/) for illustration. We then use [BasiCO](https://basico.readthedocs.io/en/latest/) to build and run a simulation of the SBML model. BasiCO is a simplified interface to using COPASI from python." ] }, { "attachments": {}, "cell_type": "markdown", "id": "c59a3e71", "metadata": {}, "source": [ "## 1) Including libraries" ] }, { "cell_type": "code", "execution_count": 16, "id": "4b7c5a24", "metadata": {}, "outputs": [], "source": [ "import os\n", "import libsbml\n", "from combine_notebooks import RESULTS_DIR\n", "from basico import load_model, run_time_course, get_reaction_parameters, get_species\n", "from combine_notebooks.validation.validation_sbml import validate_sbml" ] }, { "attachments": {}, "cell_type": "markdown", "id": "dfb6d8d0", "metadata": {}, "source": [ "## 2) Declaring the SBML model" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f544db5b", "metadata": { "lines_to_next_cell": 0 }, "source": [ "Create an empty SBMLDocument object. It's a good idea to check for\n", "possible errors. Even when the parameter values are hardwired like\n", "this, it is still possible for a failure to occur (e.g., if the\n", "operating system runs out of memory)." ] }, { "cell_type": "code", "execution_count": 17, "id": "ae6bbf46", "metadata": { "lines_to_next_cell": 0 }, "outputs": [], "source": [ "try:\n", " document = libsbml.SBMLDocument(3, 1)\n", "except ValueError:\n", " raise SystemExit('Could not create SBMLDocument object')" ] }, { "cell_type": "markdown", "id": "a2426962", "metadata": {}, "source": [ "Create the basic Model object inside the SBMLDocument object. To\n", "produce a model with complete units for the reaction rates, we need\n", "to set the 'timeUnits' and 'extentUnits' attributes on Model. We\n", "set 'substanceUnits' too, for good measure, though it's not strictly\n", "necessary here because we also set the units for individual species\n", "in their definitions." ] }, { "cell_type": "code", "execution_count": 18, "id": "63e6af9a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model = document.createModel()\n", "model.setTimeUnits(\"second\")\n", "model.setExtentUnits(\"mole\")\n", "model.setSubstanceUnits('mole')" ] }, { "cell_type": "markdown", "id": "800b6957", "metadata": {}, "source": [ "Create a unit definition we will need later. Note that SBML Unit\n", "objects must have all four attributes 'kind', 'exponent', 'scale'\n", "and 'multiplier' defined." ] }, { "cell_type": "code", "execution_count": 19, "id": "58e1cd4a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "per_second = model.createUnitDefinition()\n", "per_second.setId('per_second')\n", "unit = per_second.createUnit()\n", "unit.setKind(libsbml.UNIT_KIND_SECOND)\n", "unit.setExponent(-1)\n", "unit.setScale(0)\n", "unit.setMultiplier(1)" ] }, { "cell_type": "markdown", "id": "b3277911", "metadata": {}, "source": [ "Create a compartment inside this model, and set the required\n", "attributes for an SBML compartment in SBML Level 3." ] }, { "cell_type": "code", "execution_count": 20, "id": "e5ec79db", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c1 = model.createCompartment()\n", "c1.setId('c1')\n", "c1.setConstant(True)\n", "c1.setSize(1)\n", "c1.setSpatialDimensions(3)\n", "c1.setUnits('litre')" ] }, { "cell_type": "markdown", "id": "0ec2e677", "metadata": {}, "source": [ "Create two species inside this model, set the required attributes\n", "for each species in SBML Level 3 (which are the 'id', 'compartment',\n", "'constant', 'hasOnlySubstanceUnits', and 'boundaryCondition'\n", "attributes), and initialize the amount of the species along with the\n", "units of the amount." ] }, { "cell_type": "code", "execution_count": 21, "id": "2a942cb8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s1 = model.createSpecies()\n", "s1.setId('S1')\n", "s1.setCompartment('c1')\n", "s1.setConstant(False)\n", "s1.setInitialAmount(5)\n", "s1.setSubstanceUnits('mole')\n", "s1.setBoundaryCondition(False)\n", "s1.setHasOnlySubstanceUnits(False)\n", "\n", "s2 = model.createSpecies()\n", "s2.setId('S2')\n", "s2.setCompartment('c1')\n", "s2.setConstant(False)\n", "s2.setInitialAmount(0)\n", "s2.setSubstanceUnits('mole')\n", "s2.setBoundaryCondition(False)\n", "s2.setHasOnlySubstanceUnits(False)" ] }, { "cell_type": "markdown", "id": "0d118d66", "metadata": {}, "source": [ "Create a parameter object inside this model, set the required\n", "attributes 'id' and 'constant' for a parameter in SBML Level 3, and\n", "initialize the parameter with a value along with its units." ] }, { "cell_type": "code", "execution_count": 22, "id": "8e4d6ce7", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "k = model.createParameter()\n", "k.setId('k')\n", "k.setConstant(True)\n", "k.setValue(1)\n", "k.setUnits('per_second')" ] }, { "cell_type": "markdown", "id": "8cd2796b", "metadata": {}, "source": [ "Create a reaction inside this model, set the reactants and products,\n", "and set the reaction rate expression (the SBML \"kinetic law\"). We\n", "set the minimum required attributes for all of these objects. The\n", "units of the reaction rate are determined from the 'timeUnits' and\n", "'extentUnits' attributes on the Model object." ] }, { "cell_type": "code", "execution_count": 23, "id": "f03557f6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r1 = model.createReaction()\n", "r1.setId('r1')\n", "r1.setReversible(False)\n", "r1.setFast(False)\n", "\n", "species_ref1 = r1.createReactant()\n", "species_ref1.setSpecies('S1')\n", "species_ref1.setConstant(True)\n", "\n", "species_ref2 = r1.createProduct()\n", "species_ref2.setSpecies('S2')\n", "species_ref2.setConstant(True)\n", "\n", "math_ast = libsbml.parseL3Formula('k * S1 * c1')\n", "\n", "kinetic_law = r1.createKineticLaw()\n", "kinetic_law.setMath(math_ast)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "39c5e5d1", "metadata": {}, "source": [ "## 3) Write, print and validate the generated model" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b726b49b", "metadata": {}, "source": [ "And we're done creating the basic model. Here we will check if the SBML is valid." ] }, { "cell_type": "code", "execution_count": 25, "id": "f407d8bc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------------------------------------\n", "validation error(s) : 0\n", "validation warning(s) : 0\n", "--------------------------------------------------------------------------------\n" ] } ], "source": [ "# validate file\n", "validate_sbml(document, units_consistency=False)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "44c1bfd6", "metadata": {}, "source": [ "Now save a text string containing the model into an XML file." ] }, { "cell_type": "code", "execution_count": 26, "id": "199d4f04", "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " k \n", " S1 \n", " c1 \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "\n" ] } ], "source": [ "file_loc = str(RESULTS_DIR) + \"/hello_world_sbml.xml\"\n", "os.makedirs(os.path.dirname(file_loc), exist_ok=True)\n", "libsbml.writeSBMLToFile(document, file_loc)\n", "xml = open(file_loc).read()\n", "print(xml)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "a8b6a58c", "metadata": {}, "source": [ "## 4) Simulating the model" ] }, { "attachments": {}, "cell_type": "markdown", "id": "cf6ef008", "metadata": {}, "source": [ "Now we will load to model into COPASI (basico) so we can run a simulation." ] }, { "cell_type": "code", "execution_count": 27, "id": "0ad895c1", "metadata": {}, "outputs": [], "source": [ "model = load_model(file_loc)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d1d249d1", "metadata": {}, "source": [ "To verify our species parameters for s1 and s2 we can call get_species, which returns a dataframe with all information about the species." ] }, { "cell_type": "code", "execution_count": 28, "id": "9d3a22c9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
compartmenttypeunitinitial_concentrationinitial_particle_numberinitial_expressionexpressionconcentrationparticle_numberrateparticle_number_ratekeysbml_id
name
S1c1reactionsmol/l5.03.011071e+245.03.011071e+24-5.0-3.011071e+24Metabolite_0S1
S2c1reactionsmol/l0.00.000000e+000.00.000000e+005.03.011071e+24Metabolite_1S2
\n", "
" ], "text/plain": [ " compartment type unit initial_concentration \\\n", "name \n", "S1 c1 reactions mol/l 5.0 \n", "S2 c1 reactions mol/l 0.0 \n", "\n", " initial_particle_number initial_expression expression concentration \\\n", "name \n", "S1 3.011071e+24 5.0 \n", "S2 0.000000e+00 0.0 \n", "\n", " particle_number rate particle_number_rate key sbml_id \n", "name \n", "S1 3.011071e+24 -5.0 -3.011071e+24 Metabolite_0 S1 \n", "S2 0.000000e+00 5.0 3.011071e+24 Metabolite_1 S2 " ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "get_species()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ed4a40af", "metadata": {}, "source": [ "To see the kinetic paramters of our recation we can use get_reaction_parameters." ] }, { "cell_type": "code", "execution_count": 29, "id": "fd520554", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valuereactiontypemapped_to
name
(r1).k11.0r1globalk
\n", "
" ], "text/plain": [ " value reaction type mapped_to\n", "name \n", "(r1).k1 1.0 r1 global k" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "get_reaction_parameters()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3c4f4e61", "metadata": {}, "source": [ "Now lets simulate our model for 10 seconds." ] }, { "cell_type": "code", "execution_count": 30, "id": "5255243c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "result = run_time_course(duration=10)\n", "result.plot()" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" }, "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.11.1" } }, "nbformat": 4, "nbformat_minor": 5 }