Repository: combine-org/combine-notebooks (language: python)

Issue:
Sbml helper functions
Added a helper functions for libsbml notebook.  These functions have their own package.  Makes the libsbml notebook more concise, reducing it by about 200 lines.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index ef17342..10954fe 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -2,10 +2,20 @@ name: CI-CD
 
 on:
   push:
-    branches: [ master, development, experimental, test* ]
+    branches: [ master, development, experimental, test*, precommit ]
   pull_request:
-    branches: [ master, development, experimental, test* ]
+    branches: [ master, development, experimental, test*, precommit ]
 jobs:
+
+  pre-commit:
+      name: Format
+      runs-on: ubuntu-latest
+      steps:
+      - uses: actions/checkout@v1
+      - uses: actions/setup-python@v2
+      - uses: pre-commit/action@v2.0.0
+        with:
+          extra_args: --hook-stage manual --all-files
   test:
     runs-on: ${{ matrix.os }}
     strategy:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..a3d2721
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,25 @@
+repos:
+
+- repo: https://github.com/PyCQA/isort
+  rev: 5.12.0
+  hooks:
+  - id: isort
+    files: 'src/combine_notebooks/*'
+
+- repo: https://github.com/psf/black
+  rev: 23.1.0
+  hooks:
+  - id: black
+    files: 'src/combine_notebooks/*'
+
+- repo: https://github.com/PyCQA/isort
+  rev: 5.12.0
+  hooks:
+  - id: isort
+    files: 'tests/*'
+
+- repo: https://github.com/psf/black
+  rev: 23.1.0
+  hooks:
+  - id: black
+    files: 'tests/*'
\ No newline at end of file
diff --git a/notebooks/cellml.ipynb b/notebooks/cellml.ipynb
new file mode 100644
index 0000000..85c4823
--- /dev/null
+++ b/notebooks/cellml.ipynb
@@ -0,0 +1,534 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "https://libcellml.org/documentation/v0.4.0/user/tutorials/hh_tutorial1/index"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from libcellml import Analyser, Component, Model, Printer, Units, Validator, Variable, cellmlElementTypeAsString\n",
+    "from combine_notebooks.cellml_utilities import print_model"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Setup the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MODEL: 'GateModel'\n",
+      "    UNITS: 0 custom units\n",
+      "    COMPONENTS: 1 components\n",
+      "        [0]: 'gate'\n",
+      "            VARIABLES: 0 variables\n"
+     ]
+    }
+   ],
+   "source": [
+    "#  Setup useful things.\n",
+    "math_header = '<math xmlns=\"http://www.w3.org/1998/Math/MathML\" xmlns:cellml=\"http://www.cellml.org/cellml/2.0#\">\\n'\n",
+    "math_footer = '</math>'\n",
+    "\n",
+    "# The first step is to create a Model item which will later contain the component and \n",
+    "# the units it needs.  \n",
+    "model = Model()\n",
+    "\n",
+    "# Each CellML element must have a name, which is set using the setName() function.\n",
+    "model.setName('GateModel')\n",
+    "\n",
+    "# We'll create a wrapper component whose only job is to encapsulate the other components.\n",
+    "# This makes is a lot easier for this model to be reused, as the connections between\n",
+    "# components internal to this one won't need to be re-established.\n",
+    "# Note that the constructor for all named CellML entities is overloaded, so \n",
+    "# you can pass it the name string at the time of creation.\n",
+    "# Create a component named 'gate'.\n",
+    "gate = Component('gate')\n",
+    "\n",
+    "# Finally we need to add the component to the model.  This sets it at the top-level of \n",
+    "# the components' encapsulation hierarchy.  All other components need to be added \n",
+    "# to this component, rather than the model.\n",
+    "# Add the component to the model using the Model::addComponent() function.\n",
+    "model.addComponent(gate)\n",
+    "\n",
+    "# Print the model to the terminal using the print_model helper function and \n",
+    "# check it is what you'd expect.\n",
+    "print_model(model)\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Create the gateEquations component"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MODEL: 'GateModel'\n",
+      "    UNITS: 0 custom units\n",
+      "    COMPONENTS: 1 components\n",
+      "        [0]: 'gate'\n",
+      "            VARIABLES: 0 variables\n",
+      "            COMPONENT gate has 1 child components:\n",
+      "                [0]: 'gateEquations'\n",
+      "                    VARIABLES: 0 variables\n",
+      "                  Maths in the component is:\n",
+      "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" xmlns:cellml=\"http://www.cellml.org/cellml/2.0#\">\n",
+      "  <apply><eq/>\n",
+      "    <apply><diff/>\n",
+      "      <bvar><ci>t</ci></bvar>\n",
+      "      <ci>X</ci>\n",
+      "    </apply>\n",
+      "    <apply><minus/>\n",
+      "      <apply><times/>\n",
+      "        <ci>alpha_X</ci>\n",
+      "        <apply><minus/>\n",
+      "          <cn cellml:units=\"dimensionless\">1</cn>\n",
+      "          <ci>X</ci>\n",
+      "        </apply>\n",
+      "      </apply>\n",
+      "      <apply><times/>\n",
+      "        <ci>beta_X</ci>\n",
+      "        <ci>X</ci>\n",
+      "      </apply>\n",
+      "    </apply>\n",
+      "  </apply>\n",
+      "</math>\n"
+     ]
+    }
+   ],
+   "source": [
+    "\n",
+    "# Create a gateEquations component and name it 'gateEquations'.\n",
+    "gateEquations = Component('gateEquations')\n",
+    "\n",
+    "# Add the new gateEquations component to the gate component.\n",
+    "gate.addComponent(gateEquations)\n",
+    "\n",
+    "# Add the mathematics to the gateEquations component.\n",
+    "equation = \\\n",
+    "    '  <apply><eq/>\\n'\\\n",
+    "    '    <apply><diff/>\\n'\\\n",
+    "    '      <bvar><ci>t</ci></bvar>\\n'\\\n",
+    "    '      <ci>X</ci>\\n'\\\n",
+    "    '    </apply>\\n'\\\n",
+    "    '    <apply><minus/>\\n'\\\n",
+    "    '      <apply><times/>\\n'\\\n",
+    "    '        <ci>alpha_X</ci>\\n'\\\n",
+    "    '        <apply><minus/>\\n'\\\n",
+    "    '          <cn cellml:units=\"dimensionless\">1</cn>\\n'\\\n",
+    "    '          <ci>X</ci>\\n'\\\n",
+    "    '        </apply>\\n'\\\n",
+    "    '      </apply>\\n'\\\n",
+    "    '      <apply><times/>\\n'\\\n",
+    "    '        <ci>beta_X</ci>\\n'\\\n",
+    "    '        <ci>X</ci>\\n'\\\n",
+    "    '      </apply>\\n'\\\n",
+    "    '    </apply>\\n'\\\n",
+    "    '  </apply>\\n'\n",
+    "\n",
+    "gateEquations.setMath(math_header)\n",
+    "gateEquations.appendMath(equation)\n",
+    "gateEquations.appendMath(math_footer)\n",
+    "\n",
+    "#      Print the model to the terminal using the print_model helper function and \n",
+    "#      check it is what you'd expect.  Include the second argument as True so that \n",
+    "#      the maths is included.\n",
+    "print_model(model, True)\n",
+    "\n",
+    "#  Once the mathematics has been added to the component, and the component to the \n",
+    "#  model, we can make use of the diagnostic messages within the Validator class\n",
+    "#  to tell us what else needs to be done.  "
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Validate the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Create a Validator instance, and pass it your model for processing using the \n",
+    "# validateModel function.  \n",
+    "validator = Validator()\n",
+    "validator.validateModel(model)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Add the variables"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Create items for the missing variables and add them to the gateEquations component.\n",
+    "# You will need to be sure to give them names which match exactly those reported by the\n",
+    "# validator, or are present in the MathML string.  \n",
+    "gateEquations.addVariable(Variable('t'))\n",
+    "gateEquations.addVariable(Variable('alpha_X'))\n",
+    "gateEquations.addVariable(Variable('beta_X'))\n",
+    "gateEquations.addVariable(Variable('X'))\n",
+    "\n",
+    "# Validate again, and expect errors relating to missing units.\n",
+    "# Note that you can use the helper function print_issues(validator) to print your\n",
+    "# issues to the screen instead of repeating the code from 3.b.\n",
+    "validator.validateModel(model)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Add the units"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MODEL: 'GateModel'\n",
+      "    UNITS: 4 custom units\n",
+      "        [0]: ms\n",
+      "        [1]: per_ms\n",
+      "        [2]: ms\n",
+      "        [3]: per_ms\n",
+      "    COMPONENTS: 1 components\n",
+      "        [0]: 'gate'\n",
+      "            VARIABLES: 0 variables\n",
+      "            COMPONENT gate has 1 child components:\n",
+      "                [0]: 'gateEquations'\n",
+      "                    VARIABLES: 4 variables\n",
+      "                        [0]: t [ms]\n",
+      "                        [1]: alpha_X [per_ms]\n",
+      "                        [2]: beta_X [per_ms]\n",
+      "                        [3]: X [dimensionless]\n",
+      "                  Maths in the component is:\n",
+      "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" xmlns:cellml=\"http://www.cellml.org/cellml/2.0#\">\n",
+      "  <apply><eq/>\n",
+      "    <apply><diff/>\n",
+      "      <bvar><ci>t</ci></bvar>\n",
+      "      <ci>X</ci>\n",
+      "    </apply>\n",
+      "    <apply><minus/>\n",
+      "      <apply><times/>\n",
+      "        <ci>alpha_X</ci>\n",
+      "        <apply><minus/>\n",
+      "          <cn cellml:units=\"dimensionless\">1</cn>\n",
+      "          <ci>X</ci>\n",
+      "        </apply>\n",
+      "      </apply>\n",
+      "      <apply><times/>\n",
+      "        <ci>beta_X</ci>\n",
+      "        <ci>X</ci>\n",
+      "      </apply>\n",
+      "    </apply>\n",
+      "  </apply>\n",
+      "</math>\n"
+     ]
+    }
+   ],
+   "source": [
+    "#  The validator has reported that the four variables are missing units attributes.  \n",
+    "#  In this example none of the units exist yet, so we need to create all of them. \n",
+    "#  The variables' units should be:\n",
+    "#      - t, time has units of *milliseconds*\n",
+    "#      - X, gate status has units of *dimensionless*\n",
+    "#      - alpha_X and beta_X, rates, have units of *per millisecond*.\n",
+    "\n",
+    "# Create the units which will be needed by your variables and add them to the model.\n",
+    "ms = Units('ms')\n",
+    "per_ms = Units('per_ms')\n",
+    "\n",
+    "# Add Unit items to the units you created to define them.\n",
+    "ms.addUnit('second', 'milli')\n",
+    "per_ms.addUnit('second', 'milli', -1)\n",
+    "\n",
+    "# Add the Units to the model (not the component) so that other components can make \n",
+    "# use of them too.\n",
+    "model.addUnits(ms)\n",
+    "model.addUnits(per_ms)\n",
+    "\n",
+    "# Use the setUnits function to associate them with the appropriate variables.  \n",
+    "gateEquations.variable('t').setUnits(ms)\n",
+    "gateEquations.variable('alpha_X').setUnits(per_ms)\n",
+    "gateEquations.variable('beta_X').setUnits(per_ms)\n",
+    "gateEquations.variable('X').setUnits('dimensionless')\n",
+    "\n",
+    "# Validate again, and expect no errors.\n",
+    "validator.validateModel(model)\n",
+    "\n",
+    "# Print the model to the terminal and include the optional second argument of true\n",
+    "# to include the MathML.\n",
+    "print_model(model, True)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Analyse the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Create an Analyser item and submit the model for processing. \n",
+    "analyser = Analyser()\n",
+    "analyser.analyseModel(model)\n",
+    "\n",
+    "# In order to avoid hard-coding values here, we will need to connect to external \n",
+    "# values to initialise the X variable and provide the value for alpha_X and beta_X.\n",
+    "# This means that:\n",
+    "#      - we need to create an external component to hold variable values\n",
+    "#      - we need to create external variables in that component \n",
+    "#      - we need to specify the connections between variables and\n",
+    "#      - we need to permit external connections on the variables.\n",
+    "\n",
+    "# Create a component which will store the hard-coded values for initialisation.\n",
+    "# Name it 'gateParameters', and add it to the top-level gate component as a sibling\n",
+    "# of the gateEquations component.\n",
+    "gateParameters = Component('gateParameters')\n",
+    "gate.addComponent(gateParameters)\n",
+    "\n",
+    "#      Create appropriate variables in this component, and set their units.\n",
+    "#      Use the setInitialValue function to initialise them.\n",
+    "X = Variable('X')\n",
+    "X.setUnits('dimensionless')\n",
+    "X.setInitialValue(0)\n",
+    "gateParameters.addVariable(X)\n",
+    "\n",
+    "alpha = Variable('alpha')\n",
+    "alpha.setUnits(per_ms)\n",
+    "alpha.setInitialValue(0.1)\n",
+    "gateParameters.addVariable(alpha)\n",
+    "\n",
+    "beta = Variable('beta')\n",
+    "beta.setUnits(per_ms)\n",
+    "beta.setInitialValue(0.5)\n",
+    "gateParameters.addVariable(beta)\n",
+    "\n",
+    "# Specify a variable equivalence between the gateEquations variables and the parameter variables.\n",
+    "# Validate the model again, expecting errors related to the variable interface types.\n",
+    "Variable.addEquivalence(gateEquations.variable('X'), gateParameters.variable('X'))\n",
+    "Variable.addEquivalence(gateEquations.variable('alpha_X'), gateParameters.variable('alpha'))\n",
+    "Variable.addEquivalence(gateEquations.variable('beta_X'), gateParameters.variable('beta'))\n",
+    "\n",
+    "validator.validateModel(model)\n",
+    "\n",
+    "# Set the variable interface type according to the recommendation from the validator.\n",
+    "# This can either be done individually using the Variable::setInterfaceType() function, or \n",
+    "# en masse for all the model's interfaces using the Model::fixVariableInterfaces() function.\n",
+    "# Validate and analyse again, expecting no errors. \n",
+    "model.fixVariableInterfaces()\n",
+    "\n",
+    "validator.validateModel(model)\n",
+    "\n",
+    "analyser.analyseModel(model)\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Sanity check"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MODEL: 'GateModel'\n",
+      "    UNITS: 4 custom units\n",
+      "        [0]: ms\n",
+      "        [1]: per_ms\n",
+      "        [2]: ms\n",
+      "        [3]: per_ms\n",
+      "    COMPONENTS: 1 components\n",
+      "        [0]: 'gate'\n",
+      "            VARIABLES: 0 variables\n",
+      "            COMPONENT gate has 4 child components:\n",
+      "                [0]: 'gateEquations'\n",
+      "                    VARIABLES: 4 variables\n",
+      "                        [0]: t [ms]\n",
+      "                        [1]: alpha_X [per_ms]\n",
+      "                              └──> gateParameters:alpha [per_ms], gateParameters:alpha [per_ms], gateParameters:alpha [per_ms]\n",
+      "                        [2]: beta_X [per_ms]\n",
+      "                              └──> gateParameters:beta [per_ms], gateParameters:beta [per_ms], gateParameters:beta [per_ms]\n",
+      "                        [3]: X [dimensionless]\n",
+      "                              └──> gateParameters:X [dimensionless], gateParameters:X [dimensionless], gateParameters:X [dimensionless]\n",
+      "                [1]: 'gateParameters'\n",
+      "                    VARIABLES: 3 variables\n",
+      "                        [0]: X [dimensionless], initial = 0\n",
+      "                              └──> gateEquations:X [dimensionless]\n",
+      "                        [1]: alpha [per_ms], initial = 0.1\n",
+      "                              └──> gateEquations:alpha_X [per_ms]\n",
+      "                        [2]: beta [per_ms], initial = 0.5\n",
+      "                              └──> gateEquations:beta_X [per_ms]\n",
+      "                [2]: 'gateParameters'\n",
+      "                    VARIABLES: 3 variables\n",
+      "                        [0]: X [dimensionless], initial = 0\n",
+      "                              └──> gateEquations:X [dimensionless]\n",
+      "                        [1]: alpha [per_ms], initial = 0.1\n",
+      "                              └──> gateEquations:alpha_X [per_ms]\n",
+      "                        [2]: beta [per_ms], initial = 0.5\n",
+      "                              └──> gateEquations:beta_X [per_ms]\n",
+      "                [3]: 'gateParameters'\n",
+      "                    VARIABLES: 3 variables\n",
+      "                        [0]: X [dimensionless], initial = 0\n",
+      "                              └──> gateEquations:X [dimensionless]\n",
+      "                        [1]: alpha [per_ms], initial = 0.1\n",
+      "                              └──> gateEquations:alpha_X [per_ms]\n",
+      "                        [2]: beta [per_ms], initial = 0.5\n",
+      "                              └──> gateEquations:beta_X [per_ms]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Print the model to the terminal using the helper function print_model.\n",
+    "print_model(model)\n",
+    "\n",
+    "# Looking at the printout we see that the top-level component has no variables.  \n",
+    "# Even though this is clearly a valid situation (as proved by 4.f), it's not\n",
+    "# going to make this model easy to reuse.  We need to make sure that any input and\n",
+    "# output variables are also connected into the top level gate component.  \n",
+    "\n",
+    "# Create intermediate variables for time t and gate status X in the gate component,\n",
+    "# and ensure they have a public and private interface to enable two-way connection.\n",
+    "# You may also need to set a public and private connection onto t and X in the\n",
+    "# equations component too.\n",
+    "gate.addVariable(gateEquations.variable('t').clone())\n",
+    "gate.addVariable(gateEquations.variable('X').clone())\n",
+    "\n",
+    "gate.variable('t').setInterfaceType('public_and_private')\n",
+    "gate.variable('X').setInterfaceType('public_and_private')\n",
+    "gateEquations.variable('t').setInterfaceType('public_and_private')\n",
+    "gateEquations.variable('X').setInterfaceType('public_and_private')\n",
+    "\n",
+    "# Connect the intermediate variables to their respective partners in the equations\n",
+    "# component, and recheck the model.\n",
+    "Variable.addEquivalence(gate.variable('t'), gateEquations.variable('t'))\n",
+    "Variable.addEquivalence(gate.variable('X'), gateEquations.variable('X'))\n",
+    "\n",
+    "validator.validateModel(model)\n",
+    "analyser.analyseModel(model)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Serialise and output the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The created model has been written to hello_world_cellml.cellml\n"
+     ]
+    }
+   ],
+   "source": [
+    "from combine_notebooks import RESULTS_DIR\n",
+    "from pathlib import Path\n",
+    "\n",
+    "cellml_path: Path = RESULTS_DIR / 'hello_world_cellml.cellml'\n",
+    "\n",
+    "# Create a Printer instance and use it to serialise the model.  This creates a string\n",
+    "# containing the CellML-formatted version of the model.  Write this to a file called\n",
+    "# 'hello_world_cellml.cellml'.\n",
+    "printer = Printer()\n",
+    "write_file = open(cellml_path, 'w')\n",
+    "write_file.write(printer.printModel(model))\n",
+    "write_file.close()\n",
+    "\n",
+    "print('The created model has been written to hello_world_cellml.cellml')"
+   ]
+  }
+ ],
+ "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.10.6"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/example_sbml_libsbml.ipynb b/notebooks/example_sbml_libsbml.ipynb
index 683b557..1ababd2 100644
--- a/notebooks/example_sbml_libsbml.ipynb
+++ b/notebooks/example_sbml_libsbml.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "c6194f89",
+   "id": "837ca4f9",
    "metadata": {},
    "source": [
     "Create the repressilator step by step.\n",
@@ -14,32 +14,26 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
-   "id": "02e33d32",
+   "execution_count": null,
+   "id": "886ca56a",
    "metadata": {
-    "collapsed": false,
-    "jupyter": {
-     "outputs_hidden": false
-    }
+    "collapsed": false
    },
    "outputs": [],
    "source": [
     "from pathlib import Path\n",
     "\n",
     "import libsbml\n",
-    "\n",
-    "from combine_notebooks.validation.validation_sbml import validate_sbml"
+    "from combine_notebooks.validation.validation_sbml import validate_sbml\n",
+    "from combine_notebooks.helper_functions.utils import *"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
-   "id": "87a15b98",
+   "execution_count": null,
+   "id": "e4bf4d87",
    "metadata": {
-    "collapsed": false,
-    "jupyter": {
-     "outputs_hidden": false
-    }
+    "collapsed": false
    },
    "outputs": [],
    "source": [
@@ -52,538 +46,170 @@
     "    model: libsbml.Model = doc.createModel()\n",
     "\n",
     "    # --- compartments ---\n",
-    "    # add compartment\n",
-    "    c1: libsbml.Compartment = model.createCompartment()\n",
-    "    c1.setId(\"cell\")\n",
-    "    c1.setSize(1.0)\n",
-    "    c1.setMetaId(\"meta_cell\")\n",
-    "    c1.setSBOTerm(\"SBO:0000290\")\n",
-    "    # set annotation\n",
-    "    c1_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    c1_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    c1_cv.setBiologicalQualifierType(libsbml.BQB_IS)\n",
-    "    c1_cv.addResource(\"http://identifiers.org/GO:0005623\")\n",
+    "    # add compartment and set annotation\n",
+    "    c1 = add_compartment(model, \"cell\", 1.0, \"meta_cell\", \"SBO:0000290\")\n",
+    "    c1_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS, \"http://identifiers.org/GO:0005623\")\n",
     "    c1.addCVTerm(c1_cv)\n",
     "\n",
     "    # --- species ---\n",
-    "    # add species for the 3 mRNAs and 3 Proteins\n",
-    "    s1: libsbml.Species = model.createSpecies()\n",
-    "    s1.setId(\"PX\")\n",
-    "    s1.setMetaId(\"PX\")\n",
-    "    s1.setCompartment(\"cell\")\n",
-    "    s1.setName(\"LacI protein\")\n",
-    "    s1.setSBOTerm(\"SBO:0000252\")\n",
-    "    s1.setInitialAmount(0)\n",
-    "    s1.setHasOnlySubstanceUnits(True)\n",
-    "    # set annotation\n",
-    "    s1_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    s1_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    s1_cv.setBiologicalQualifierType(libsbml.BQB_IS)\n",
-    "    s1_cv.addResource(\"http://identifiers.org/uniprot/P03023\")\n",
+    "    # add species for the 3 mRNAs and 3 Proteins and set annotations\n",
+    "    s1 = add_species(model, \"PX\", \"PX\", \"cell\", \"LacI protein\", \"SBO:0000252\", 0, True)\n",
+    "    s1_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS, \"http://identifiers.org/uniprot/P03023\")\n",
     "    s1.addCVTerm(s1_cv)\n",
     "\n",
-    "    s2: libsbml.Species = model.createSpecies()\n",
-    "    s2.setId(\"PY\")\n",
-    "    s2.setMetaId(\"PY\")\n",
-    "    s2.setCompartment(\"cell\")\n",
-    "    s2.setName(\"TetR protein\")\n",
-    "    s2.setSBOTerm(\"SBO:0000252\")\n",
-    "    s2.setInitialAmount(0)\n",
-    "    s2.setHasOnlySubstanceUnits(True)\n",
-    "    # set annotation\n",
-    "    s2_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    s2_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    s2_cv.setBiologicalQualifierType(libsbml.BQB_IS)\n",
-    "    s2_cv.addResource(\"http://identifiers.org/uniprot/P04483\")\n",
+    "    s2 = add_species(model, \"PY\", \"PY\", \"cell\", \"TetR protein\", \"SBO:0000252\", 0, True)\n",
+    "    s2_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS, \"http://identifiers.org/uniprot/P04483\")\n",
     "    s2.addCVTerm(s2_cv)\n",
     "\n",
-    "    s3: libsbml.Species = model.createSpecies()\n",
-    "    s3.setId(\"PZ\")\n",
-    "    s3.setMetaId(\"PZ\")\n",
-    "    s3.setCompartment(\"cell\")\n",
-    "    s3.setName(\"cI protein\")\n",
-    "    s3.setSBOTerm(\"SBO:0000252\")\n",
-    "    s3.setInitialAmount(0)\n",
-    "    s3.setHasOnlySubstanceUnits(True)\n",
-    "    # set annotation\n",
-    "    s3_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    s3_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    s3_cv.setBiologicalQualifierType(libsbml.BQB_IS)\n",
+    "    s3 = add_species(model, \"PZ\", \"PZ\", \"cell\", \"cI protein\", \"SBO:0000252\", 0, True)\n",
+    "    s3_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS, \"http://identifiers.org/uniprot/P03034\")\n",
     "    # example setting a model qualifier\n",
     "    # s3_cv.setQualifierType(libsbml.MODEL_QUALIFIER)\n",
     "    # s3_cv.setBiologicalQualifierType(libsbml.BQM_IS)\n",
-    "    s3_cv.addResource(\"http://identifiers.org/uniprot/P03034\")\n",
     "    s3.addCVTerm(s3_cv)\n",
-    "\n",
-    "    s4: libsbml.Species = model.createSpecies()\n",
-    "    s4.setId(\"X\")\n",
-    "    s4.setMetaId(\"meta_X\")\n",
-    "    s4.setCompartment(\"cell\")\n",
-    "    s4.setName(\"LacI mRNA\")\n",
-    "    s4.setSBOTerm(\"SBO:0000250\")\n",
-    "    s4.setInitialAmount(0)\n",
-    "    s4.setHasOnlySubstanceUnits(True)\n",
-    "    # set annotation\n",
-    "    s4_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    s4_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    s4_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    s4_cv.addResource(\"http://identifiers.org/CHEBI:33699\")\n",
-    "    s4_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    s4_cv.addResource(\"http://identifiers.org/kegg.compound/C00046\")\n",
+    "    \n",
+    "    s4 = add_species(model, \"X\", \"meta_X\", \"cell\", \"LacI mRNA\", \"SBO:0000250\", 0, True)\n",
+    "    s4_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/CHEBI:33699\")\n",
+    "    s4_cv = add_annotation_resource(s4_cv, libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/kegg.compound/C00046\")\n",
     "    s4.addCVTerm(s4_cv)\n",
-    "    s4_cv.setBiologicalQualifierType(libsbml.BQB_ENCODES)\n",
-    "    s4_cv.addResource(\"http://identifiers.org/uniprot/P03023\")\n",
+    "    s4_cv = add_annotation_resource(s4_cv, libsbml.BQB_ENCODES, \"http://identifiers.org/uniprot/P03023\")\n",
     "    s4.addCVTerm(s4_cv)\n",
     "\n",
-    "    s5: libsbml.Species = model.createSpecies()\n",
-    "    s5.setId(\"Y\")\n",
-    "    s5.setMetaId(\"meta_Y\")\n",
-    "    s5.setCompartment(\"cell\")\n",
-    "    s5.setName(\"TetR mRNA\")\n",
-    "    s5.setSBOTerm(\"SBO:0000250\")\n",
-    "    s5.setInitialAmount(20)\n",
-    "    s5.setHasOnlySubstanceUnits(True)\n",
-    "    # set annotation\n",
-    "    s5_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    s5_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    s5_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    s5_cv.addResource(\"http://identifiers.org/CHEBI:33699\")\n",
-    "    s5_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    s5_cv.addResource(\"http://identifiers.org/kegg.compound/C00046\")\n",
+    "    s5 = add_species(model, \"Y\", \"meta_Y\", \"cell\", \"TetR mRNA\", \"SBO:0000250\", 20, True)\n",
+    "    s5_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/CHEBI:33699\")\n",
+    "    s5_cv = add_annotation_resource(s5_cv, libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/kegg.compound/C00046\")\n",
     "    s5.addCVTerm(s5_cv)\n",
-    "    s5_cv.setBiologicalQualifierType(libsbml.BQB_ENCODES)\n",
-    "    s5_cv.addResource(\"http://identifiers.org/uniprot/P04483\")\n",
+    "    s5_cv = add_annotation_resource(s5_cv, libsbml.BQB_ENCODES, \"http://identifiers.org/uniprot/P04483\")\n",
     "    s5.addCVTerm(s5_cv)\n",
     "\n",
-    "    s6: libsbml.Species = model.createSpecies()\n",
-    "    s6.setId(\"Z\")\n",
-    "    s6.setMetaId(\"meta_Z\")\n",
-    "    s6.setCompartment(\"cell\")\n",
-    "    s6.setName(\"cl mRNA\")\n",
-    "    s6.setSBOTerm(\"SBO:0000250\")\n",
-    "    s6.setInitialAmount(0)\n",
-    "    s6.setHasOnlySubstanceUnits(True)\n",
-    "    # set annotation\n",
-    "    s6_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    s6_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    s6_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    s6_cv.addResource(\"http://identifiers.org/CHEBI:33699\")\n",
-    "    s6_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    s6_cv.addResource(\"http://identifiers.org/kegg.compound/C00046\")\n",
+    "    s6 = add_species(model, \"Z\", \"meta_Z\", \"cell\", \"cl mRNA\", \"SBO:0000250\", 0, True)\n",
+    "    s6_cv = create_annotation(libsbml.BIOLOGICAL_QUALIFIER, libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/CHEBI:33699\")\n",
+    "    s6_cv = add_annotation_resource(s6_cv, libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/kegg.compound/C00046\")\n",
     "    s6.addCVTerm(s6_cv)\n",
-    "    s6_cv.setBiologicalQualifierType(libsbml.BQB_ENCODES)\n",
-    "    s6_cv.addResource(\"http://identifiers.org/uniprot/P03034\")\n",
+    "    s6_cv = add_annotation_resource(s6_cv, libsbml.BQB_ENCODES, \"http://identifiers.org/uniprot/P03034\")\n",
     "    s6.addCVTerm(s6_cv)\n",
     "\n",
     "    # --- parameters ---\n",
+    "    # <parameter id=\"tau_mRNA\" name=\"mRNA half life\" value=\"2\" constant=\"true\"/>\n",
+    "    add_parameters(model, \"tau_mRNA\", \"mRNA half life\", True, value=2.0)\n",
     "    # <parameter id=\"kd_mRNA\" constant=\"false\" name=\"kd_mRNA\" sboTerm=\"SBO:0000356\">\n",
-    "    p1: libsbml.Parameter = model.createParameter()\n",
-    "    p1.setId(\"tau_mRNA\")\n",
-    "    p1.setName(\"mRNA half life\")\n",
-    "    p1.setConstant(True)\n",
-    "    p1.setValue(2.0)\n",
-    "\n",
-    "    # <parameter id=\"kd_mRNA\" constant=\"false\" name=\"kd_mRNA\" sboTerm=\"SBO:0000356\">\n",
-    "    p2: libsbml.Parameter = model.createParameter()\n",
-    "    p2.setId(\"kd_mRNA\")\n",
-    "    p2.setName(\"kd_mRNA\")\n",
-    "    p2.setSBOTerm(\"SBO:0000356\")\n",
-    "    p2.setConstant(False)\n",
-    "\n",
+    "    add_parameters(model, \"kd_mRNA\", \"kd_mRNA\", False, sbo_term=\"SBO:0000356\")\n",
     "    # <parameter metaid=\"metaid_0000233\" sboTerm=\"SBO:0000016\" id=\"k_tl\" name=\"k_tl\" constant=\"false\">\n",
-    "    p3: libsbml.Parameter = model.createParameter()\n",
-    "    p3.setId(\"k_tl\")\n",
-    "    p3.setName(\"k_tl\")\n",
-    "    p3.setSBOTerm(\"SBO:0000016\")\n",
-    "    p3.setConstant(False)\n",
-    "\n",
+    "    add_parameters(model, \"k_tl\", \"k_tl\", False, sbo_term=\"SBO:0000016\")\n",
     "    # <parameter metaid=\"metaid_0000025\" id=\"eff\" name=\"translation efficiency\" value=\"20\">\n",
-    "    p4: libsbml.Parameter = model.createParameter()\n",
-    "    p4.setId(\"eff\")\n",
-    "    p4.setName(\"translation efficiency\")\n",
-    "    p4.setConstant(True)\n",
-    "    p4.setValue(20)\n",
-    "\n",
+    "    add_parameters(model, \"eff\", \"translation efficiency\", True, value=20)\n",
     "    # <parameter metaid=\"metaid_0000032\" sboTerm=\"SBO:0000348\" id=\"t_ave\" name=\"average mRNA life time\" constant=\"false\"/>\n",
-    "    p5: libsbml.Parameter = model.createParameter()\n",
-    "    p5.setId(\"t_ave\")\n",
-    "    p5.setName(\"average mRNA life time\")\n",
-    "    p5.setSBOTerm(\"SBO:0000348\")\n",
-    "    p5.setConstant(False)\n",
-    "\n",
+    "    add_parameters(model, \"t_ave\", \"average mRNA life time\", False, sbo_term=\"SBO:0000348\")\n",
     "    # <parameter metaid=\"metaid_0000133\" sboTerm=\"SBO:0000356\" id=\"kd_prot\" name=\"kd_prot\" constant=\"false\">\n",
-    "    p6: libsbml.Parameter = model.createParameter()\n",
-    "    p6.setId(\"kd_prot\")\n",
-    "    p6.setName(\"kd_prot\")\n",
-    "    p6.setSBOTerm(\"SBO:0000356\")\n",
-    "    p6.setConstant(False)\n",
-    "\n",
+    "    add_parameters(model, \"kd_prot\", \"kd_prot\", False, sbo_term=\"SBO:0000356\")\n",
     "    # <parameter metaid=\"metaid_0000128\" sboTerm=\"SBO:0000332\" id=\"tau_prot\" name=\"protein half life\" value=\"10\"/>\n",
-    "    p7: libsbml.Parameter = model.createParameter()\n",
-    "    p7.setId(\"tau_prot\")\n",
-    "    p7.setName(\"protien half life\")\n",
-    "    p7.setConstant(True)\n",
-    "    p7.setValue(10)\n",
-    "\n",
+    "    add_parameters(model, \"tau_prot\", \"protien half life\", True, value=10)\n",
     "    # <parameter metaid=\"metaid_0000234\" sboTerm=\"SBO:0000485\" id=\"a0_tr\" name=\"a0_tr\" constant=\"false\">\n",
-    "    p8: libsbml.Parameter = model.createParameter()\n",
-    "    p8.setId(\"a0_tr\")\n",
-    "    p8.setName(\"a0_tr\")\n",
-    "    p8.setSBOTerm(\"SBO:0000485\")\n",
-    "    p8.setConstant(False)\n",
-    "\n",
+    "    add_parameters(model, \"a0_tr\", \"a0_tr\", False, sbo_term=\"SBO:0000485\")\n",
     "    # <parameter metaid=\"metaid_0500235\" sboTerm=\"SBO:0000485\" id=\"ps_0\" name=\"tps_repr\" value=\"0.0005\">\n",
-    "    p9: libsbml.Parameter = model.createParameter()\n",
-    "    p9.setId(\"ps_0\")\n",
-    "    p9.setName(\"tps_repr\")\n",
-    "    p9.setConstant(True)\n",
-    "    p9.setValue(0.0005)\n",
-    "\n",
+    "    add_parameters(model, \"ps_0\", \"tps_repr\", True, value=0.0005)\n",
     "    # <parameter metaid=\"metaid_0900235\" sboTerm=\"SBO:0000186\" id=\"a_tr\" name=\"a_tr\" constant=\"false\">\n",
-    "    p10: libsbml.Parameter = model.createParameter()\n",
-    "    p10.setId(\"a_tr\")\n",
-    "    p10.setName(\"a_tr\")\n",
-    "    p10.setSBOTerm(\"SBO:0000186\")\n",
-    "    p10.setConstant(False)\n",
-    "\n",
+    "    add_parameters(model, \"a_tr\", \"a_tr\", False, sbo_term=\"SBO:0000186\")\n",
     "    # <parameter metaid=\"metaid_0800235\" sboTerm=\"SBO:0000186\" id=\"ps_a\" name=\"tps_active\" value=\"0.5\">\n",
-    "    p11: libsbml.Parameter = model.createParameter()\n",
-    "    p11.setId(\"ps_a\")\n",
-    "    p11.setName(\"tps_active\")\n",
-    "    p11.setConstant(True)\n",
-    "    p11.setValue(0.5)\n",
-    "\n",
+    "    add_parameters(model, \"ps_a\", \"tps_active\", True, value=0.5)\n",
     "    # <parameter metaid=\"metaid_0000027\" sboTerm=\"SBO:0000288\" id=\"KM\" name=\"KM\" value=\"40\">\n",
-    "    p12: libsbml.Parameter = model.createParameter()\n",
-    "    p12.setId(\"KM\")\n",
-    "    p12.setName(\"KM\")\n",
-    "    p12.setConstant(True)\n",
-    "    p12.setValue(40)\n",
-    "\n",
+    "    add_parameters(model, \"KM\", \"KM\", True, value=40)\n",
     "    # <parameter metaid=\"metaid_0000026\" sboTerm=\"SBO:0000190\" id=\"n\" name=\"n\" value=\"2\">\n",
-    "    p13: libsbml.Parameter = model.createParameter()\n",
-    "    p13.setId(\"n\")\n",
-    "    p13.setName(\"n\")\n",
-    "    p13.setConstant(True)\n",
-    "    p13.setValue(2.0)\n",
+    "    add_parameters(model, \"n\", \"n\", True, value=2.0)\n",
     "\n",
     "    # TODO: a0_tr, a_tr, n, KM\n",
     "\n",
     "    # --- rules ---\n",
-    "    a1: libsbml.AssignmentRule = model.createAssignmentRule()\n",
-    "    a1.setVariable(\"kd_mRNA\")\n",
-    "    math_ast1: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"ln(2) / tau_mRNA\", model\n",
-    "    )\n",
-    "    a1.setMath(math_ast1)\n",
+    "    add_assignment_rule(model, \"kd_mRNA\", \"ln(2) / tau_mRNA\")\n",
+    "    add_assignment_rule(model, \"t_ave\", \"tau_mRNA / ln(2)\")\n",
+    "    add_assignment_rule(model, \"k_tl\", \"eff / t_ave\")\n",
+    "    add_assignment_rule(model, \"kd_prot\", \"ln(2) / tau_prot\")\n",
+    "    add_assignment_rule(model, \"a0_tr\", \"ps_0 * 60\")\n",
+    "    add_assignment_rule(model, \"a_tr\", \"(ps_a - ps_0) * 60\")\n",
     "\n",
-    "    a2: libsbml.AssignmentRule = model.createAssignmentRule()\n",
-    "    a2.setVariable(\"t_ave\")\n",
-    "    math_ast2: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"tau_mRNA / ln(2)\", model\n",
+    "    # --- reaction ---\n",
+    "    # X -> None\n",
+    "    r1 = add_reactions(\n",
+    "        model, \"Reaction1\", \"meta_Reaction1\", \"SBO:0000179\", \"degradation of LacI transcripts\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006402\", \"kd_mRNA * X\", \"SBO:0000049\"\n",
     "    )\n",
-    "    a2.setMath(math_ast2)\n",
-    "\n",
-    "    a3: libsbml.AssignmentRule = model.createAssignmentRule()\n",
-    "    a3.setVariable(\"k_tl\")\n",
-    "    math_ast3: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"eff / t_ave\", model)\n",
-    "    a3.setMath(math_ast3)\n",
+    "    add_reactant_to_reaction(r1, \"X\")\n",
     "\n",
-    "    a4: libsbml.AssignmentRule = model.createAssignmentRule()\n",
-    "    a4.setVariable(\"kd_prot\")\n",
-    "    math_ast4: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"ln(2) / tau_prot\", model\n",
+    "    r2 = add_reactions(\n",
+    "        model, \"Reaction2\", \"meta_Reaction2\", \"SBO:0000179\", \"degradation of TetR transcripts\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006402\", \"kd_mRNA * Y\", \"SBO:0000049\"\n",
     "    )\n",
-    "    a4.setMath(math_ast4)\n",
+    "    add_reactant_to_reaction(r2, \"Y\")\n",
     "\n",
-    "    a5: libsbml.AssignmentRule = model.createAssignmentRule()\n",
-    "    a5.setVariable(\"a0_tr\")\n",
-    "    math_ast5: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"ps_0 * 60\", model)\n",
-    "    a5.setMath(math_ast5)\n",
-    "\n",
-    "    a6: libsbml.AssignmentRule = model.createAssignmentRule()\n",
-    "    a6.setVariable(\"a_tr\")\n",
-    "    math_ast6: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"(ps_a - ps_0) * 60\", model\n",
+    "    r3 = add_reactions(\n",
+    "        model, \"Reaction3\", \"meta_Reaction3\", \"SBO:0000179\", \"degradation of CI transcripts\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006402\", \"kd_mRNA * Z\", \"SBO:0000049\"\n",
     "    )\n",
-    "    a6.setMath(math_ast6)\n",
-    "\n",
-    "    # --- reaction ---\n",
-    "    # X -> None\n",
-    "    r1: libsbml.Reaction = model.createReaction()\n",
-    "    r1.setId(\"Reaction1\"),  # set reaction id\n",
-    "    r1.setMetaId(\"meta_Reaction1\")\n",
-    "    r1.setSBOTerm(\"SBO:0000179\")\n",
-    "    r1.setName(\"degradation of LacI transcripts\")\n",
-    "    r1.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r1_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r1_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r1_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r1_cv.addResource(\"http://identifiers.org/GO:0006402\")\n",
-    "    r1.addCVTerm(r1_cv)\n",
-    "\n",
-    "    species_ref1: libsbml.SpeciesReference = r1.createReactant()\n",
-    "    species_ref1.setSpecies(\"X\")  # assign reactant species\n",
-    "\n",
-    "    math_ast7: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"kd_mRNA * X\", model)\n",
-    "    kinetic_law = r1.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast7)\n",
-    "\n",
-    "    r2 = model.createReaction()\n",
-    "    r2.setId(\"Reaction2\"),  # set reaction id\n",
-    "    r2.setMetaId(\"meta_Reaction2\")\n",
-    "    r2.setSBOTerm(\"SBO:0000179\")\n",
-    "    r2.setName(\"degradation of TetR transcripts\")\n",
-    "    r2.setReversible(False)\n",
-    "\n",
-    "    r2_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r2_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r2_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r2_cv.addResource(\"http://identifiers.org/GO:0006402\")\n",
-    "    r2.addCVTerm(r1_cv)\n",
-    "\n",
-    "    species_ref2 = r2.createReactant()\n",
-    "    species_ref2.setSpecies(\"Y\")  # assign reactant species\n",
-    "\n",
-    "    math_ast8: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"kd_mRNA * Y\", model)\n",
-    "    kinetic_law = r2.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast8)\n",
-    "\n",
-    "    r3 = model.createReaction()\n",
-    "    r3.setId(\"Reaction3\"),  # set reaction id\n",
-    "    r3.setMetaId(\"meta_Reaction3\")\n",
-    "    r3.setSBOTerm(\"SBO:0000179\")\n",
-    "    r3.setName(\"degradation of CI transcripts\")\n",
-    "    r3.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r3_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r3_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r3_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r3_cv.addResource(\"http://identifiers.org/GO:0006402\")\n",
-    "    r3.addCVTerm(r3_cv)\n",
+    "    add_reactant_to_reaction(r3, \"Z\")\n",
     "\n",
-    "    species_ref3 = r3.createReactant()\n",
-    "    species_ref3.setSpecies(\"Z\")  # assign reactant species\n",
-    "\n",
-    "    math_ast9: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"kd_mRNA * Z\", model)\n",
-    "    kinetic_law = r3.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast9)\n",
-    "\n",
-    "    r4 = model.createReaction()\n",
-    "    r4.setId(\"Reaction4\"),  # set reaction id\n",
-    "    r4.setMetaId(\"meta_Reaction4\")\n",
-    "    r4.setSBOTerm(\"SBO:0000184\")\n",
-    "    r4.setName(\"translation of LacI\")\n",
-    "    r4.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r4_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r4_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r4_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r4_cv.addResource(\"http://identifiers.org/GO:0006412\")\n",
-    "    r4.addCVTerm(r4_cv)\n",
-    "\n",
-    "    species_ref4 = r4.createProduct()\n",
-    "    species_ref4.setSpecies(\"PX\")  # assign product species\n",
-    "\n",
-    "    species_ref_4 = r4.createModifier()\n",
-    "    species_ref_4.setSpecies(\"X\")\n",
-    "    species_ref_4.setSBOTerm(\"SBO:0000461\")\n",
-    "\n",
-    "    math_ast10: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"k_tl * X\", model)\n",
-    "    kinetic_law = r4.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast10)\n",
-    "\n",
-    "    r5 = model.createReaction()\n",
-    "    r5.setId(\"Reaction5\"),  # set reaction id\n",
-    "    r5.setMetaId(\"meta_Reaction5\")\n",
-    "    r5.setSBOTerm(\"SBO:0000184\")\n",
-    "    r5.setName(\"translation of TetR\")\n",
-    "    r5.setReversible(False)\n",
-    "    s3_cv = libsbml.CVTerm()\n",
-    "    # set annotation\n",
-    "    r5_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r5_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r5_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r5_cv.addResource(\"http://identifiers.org/GO:0006412\")\n",
-    "    r5.addCVTerm(r5_cv)\n",
-    "\n",
-    "    species_ref5 = r5.createProduct()\n",
-    "    species_ref5.setSpecies(\"PY\")  # assign product species\n",
-    "    species_ref_5 = r5.createModifier()\n",
-    "    species_ref_5.setSpecies(\"Y\")\n",
-    "    species_ref_5.setSBOTerm(\"SBO:0000461\")\n",
-    "\n",
-    "    math_ast11: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"k_tl * Y\", model)\n",
-    "    kinetic_law = r5.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast11)\n",
-    "\n",
-    "    r6 = model.createReaction()\n",
-    "    r6.setId(\"Reaction6\"),  # set reaction id\n",
-    "    r6.setMetaId(\"meta_Reaction6\")\n",
-    "    r6.setSBOTerm(\"SBO:0000184\")\n",
-    "    r6.setName(\"translation of CI\")\n",
-    "    r6.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r6_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r6_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r6_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r6_cv.addResource(\"http://identifiers.org/GO:0006412\")\n",
-    "    r6.addCVTerm(r6_cv)\n",
-    "\n",
-    "    species_ref6 = r6.createProduct()\n",
-    "    species_ref6.setSpecies(\"PZ\")  # assign product species\n",
-    "    species_ref_6 = r6.createModifier()\n",
-    "    species_ref_6.setSpecies(\"Z\")\n",
-    "    species_ref_6.setSBOTerm(\"SBO:0000461\")\n",
-    "\n",
-    "    math_ast12: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"k_tl * Z\", model)\n",
-    "    kinetic_law = r6.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast12)\n",
-    "\n",
-    "    r7 = model.createReaction()\n",
-    "    r7.setId(\"Reaction7\"),  # set reaction id\n",
-    "    r7.setMetaId(\"meta_Reaction7\")\n",
-    "    r7.setSBOTerm(\"SBO:0000179\")\n",
-    "    r7.setName(\"degradation of LacI\")\n",
-    "    r7.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r7_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r7_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r7_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r7_cv.addResource(\"http://identifiers.org/GO:0030163\")\n",
-    "    r7.addCVTerm(r7_cv)\n",
-    "\n",
-    "    species_ref7 = r7.createReactant()\n",
-    "    species_ref7.setSpecies(\"PX\")  # assign reactant species\n",
-    "\n",
-    "    math_ast13: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"kd_prot * PX\", model)\n",
-    "    kinetic_law = r7.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast13)\n",
-    "\n",
-    "    r8 = model.createReaction()\n",
-    "    r8.setId(\"Reaction8\"),  # set reaction id\n",
-    "    r8.setMetaId(\"meta_Reaction8\")\n",
-    "    r8.setSBOTerm(\"SBO:0000179\")\n",
-    "    r8.setName(\"degradation of TetR\")\n",
-    "    r8.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r8_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r8_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r8_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r8_cv.addResource(\"http://identifiers.org/GO:0030163\")\n",
-    "    r8.addCVTerm(r8_cv)\n",
-    "\n",
-    "    species_ref8 = r8.createReactant()\n",
-    "    species_ref8.setSpecies(\"PY\")  # assign reactant species\n",
-    "\n",
-    "    math_ast14: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"kd_prot * PY\", model)\n",
-    "    kinetic_law = r8.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast14)\n",
-    "\n",
-    "    r9 = model.createReaction()\n",
-    "    r9.setId(\"Reaction9\"),  # set reaction id\n",
-    "    r9.setMetaId(\"meta_Reaction9\")\n",
-    "    r9.setSBOTerm(\"SBO:0000179\")\n",
-    "    r9.setName(\"degradation of CI\")\n",
-    "    r9.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r9_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r9_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r9_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r9_cv.addResource(\"http://identifiers.org/GO:0030163\")\n",
-    "    r9.addCVTerm(r9_cv)\n",
-    "\n",
-    "    species_ref9 = r9.createReactant()\n",
-    "    species_ref9.setSpecies(\"PZ\")  # assign reactant species\n",
-    "\n",
-    "    math_ast15: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\"kd_prot * PZ\", model)\n",
-    "    kinetic_law = r9.createKineticLaw()\n",
-    "    kinetic_law.setSBOTerm(\"SBO:0000049\")\n",
-    "    kinetic_law.setMath(math_ast15)\n",
+    "    r4 = add_reactions(\n",
+    "        model, \"Reaction4\", \"meta_Reaction4\", \"SBO:0000184\", \"translation of LacI\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006412\", \"k_tl * X\", \"SBO:0000049\"\n",
+    "    )\n",
+    "    add_product_to_reaction(r4, \"PX\")\n",
+    "    add_modifier_to_reaction(r4, \"X\", \"SBO:0000461\")\n",
     "\n",
-    "    r10 = model.createReaction()\n",
-    "    r10.setId(\"Reaction10\"),  # set reaction id\n",
-    "    r10.setMetaId(\"meta_Reaction10\")\n",
-    "    r10.setSBOTerm(\"SBO:0000183\")\n",
-    "    r10.setName(\"transcription of LacI\")\n",
-    "    r10.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r10_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r10_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r10_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r10_cv.addResource(\"http://identifiers.org/GO:0006351\")\n",
-    "    r10.addCVTerm(r10_cv)\n",
+    "    r5 = add_reactions(\n",
+    "        model, \"Reaction5\", \"meta_Reaction5\", \"SBO:0000184\", \"translation of TetR\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006412\", \"k_tl * Y\", \"SBO:0000049\"\n",
+    "    )\n",
+    "    add_product_to_reaction(r5, \"PY\")\n",
+    "    add_modifier_to_reaction(r5, \"Y\", \"SBO:0000461\")\n",
     "\n",
-    "    species_ref10 = r10.createProduct()\n",
-    "    species_ref10.setSpecies(\"X\")  # assign product species\n",
-    "    species_ref_10 = r10.createModifier()\n",
-    "    species_ref_10.setSpecies(\"PZ\")\n",
-    "    species_ref_10.setSBOTerm(\"SBO:0000536\")\n",
     "\n",
-    "    math_ast16: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"a0_tr + (a_tr * power(KM, n)) / (power(KM, n) + power(PZ, n))\", model\n",
+    "    r6 = add_reactions(\n",
+    "        model, \"Reaction6\", \"meta_Reaction6\", \"SBO:0000184\", \"translation of CI\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006412\", \"k_tl * Z\", \"SBO:0000049\"\n",
     "    )\n",
-    "    kinetic_law = r10.createKineticLaw()\n",
-    "    kinetic_law.setMath(math_ast16)\n",
+    "    add_product_to_reaction(r6, \"PZ\")\n",
+    "    add_modifier_to_reaction(r6, \"Z\", \"SBO:0000461\")\n",
     "\n",
-    "    r11 = model.createReaction()\n",
-    "    r11.setId(\"Reaction11\"),  # set reaction id\n",
-    "    r11.setMetaId(\"meta_Reaction11\")\n",
-    "    r11.setSBOTerm(\"SBO:0000183\")\n",
-    "    r11.setName(\"transcription of TetR\")\n",
-    "    r11.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r11_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r11_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r11_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r11_cv.addResource(\"http://identifiers.org/GO:0006351\")\n",
-    "    r11.addCVTerm(r11_cv)\n",
+    "    r7 = add_reactions(\n",
+    "        model, \"Reaction7\", \"meta_Reaction7\", \"SBO:0000179\", \"degradation of LacI\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0030163\", \"kd_prot * PX\", \"SBO:0000049\"\n",
+    "    )\n",
+    "    add_reactant_to_reaction(r7, \"PX\")\n",
     "\n",
-    "    species_ref11 = r11.createProduct()\n",
-    "    species_ref11.setSpecies(\"Y\")  # assign product species\n",
-    "    species_ref_11 = r11.createModifier()\n",
-    "    species_ref_11.setSpecies(\"PX\")\n",
-    "    species_ref_11.setSBOTerm(\"SBO:0000536\")\n",
+    "    r8 = add_reactions(\n",
+    "        model, \"Reaction8\", \"meta_Reaction8\", \"SBO:0000179\", \"degradation of TetR\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0030163\", \"kd_prot * PY\", \"SBO:0000049\"\n",
+    "    )\n",
+    "    add_reactant_to_reaction(r8, \"PY\")\n",
     "\n",
-    "    math_ast17: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"a0_tr + (a_tr * power(KM, n)) / (power(KM, n) + power(PX, n))\", model\n",
+    "    r9 = add_reactions(\n",
+    "        model, \"Reaction9\", \"meta_Reaction9\", \"SBO:0000179\", \"degradation of CI\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0030163\", \"kd_prot * PZ\", \"SBO:0000049\"\n",
     "    )\n",
-    "    kinetic_law = r11.createKineticLaw()\n",
-    "    kinetic_law.setMath(math_ast17)\n",
+    "    add_reactant_to_reaction(r9, \"PZ\")\n",
     "\n",
-    "    r12 = model.createReaction()\n",
-    "    r12.setId(\"Reaction12\"),  # set reaction id\n",
-    "    r12.setMetaId(\"meta_Reaction12\")\n",
-    "    r12.setSBOTerm(\"SBO:0000183\")\n",
-    "    r12.setName(\"transcription of CI\")\n",
-    "    r12.setReversible(False)\n",
-    "    # set annotation\n",
-    "    r12_cv: libsbml.CVTerm = libsbml.CVTerm()\n",
-    "    r12_cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER)\n",
-    "    r12_cv.setBiologicalQualifierType(libsbml.BQB_IS_VERSION_OF)\n",
-    "    r12_cv.addResource(\"http://identifiers.org/GO:0006351\")\n",
-    "    r12.addCVTerm(r12_cv)\n",
+    "    r10 = add_reactions(\n",
+    "        model, \"Reaction10\", \"meta_Reaction10\", \"SBO:0000183\", \"transcription of LacI\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006351\", \"a0_tr + (a_tr * power(KM, n)) / (power(KM, n) + power(PZ, n))\", \n",
+    "        None\n",
+    "    )\n",
+    "    add_product_to_reaction(r10, \"X\")\n",
+    "    add_modifier_to_reaction(r10, \"PZ\", \"SBO:0000536\")\n",
     "\n",
-    "    species_ref12 = r12.createProduct()\n",
-    "    species_ref12.setSpecies(\"Z\")  # assign product species\n",
-    "    species_ref_12 = r12.createModifier()\n",
-    "    species_ref_12.setSpecies(\"PY\")\n",
-    "    species_ref_12.setSBOTerm(\"SBO:0000536\")\n",
+    "    r11 = add_reactions(\n",
+    "        model, \"Reaction11\", \"meta_Reaction11\", \"SBO:0000183\", \"transcription of TetR\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006351\", \"a0_tr + (a_tr * power(KM, n)) / (power(KM, n) + power(PX, n))\", \n",
+    "        None\n",
+    "    )\n",
+    "    add_product_to_reaction(r11, \"Y\")\n",
+    "    add_modifier_to_reaction(r11, \"PX\", \"SBO:0000536\")\n",
     "\n",
-    "    math_ast18: libsbml.ASTNode = libsbml.parseL3FormulaWithModel(\n",
-    "        \"a0_tr + (a_tr * power(KM, n)) / (power(KM, n) + power(PY, n))\", model\n",
+    "    r12 = add_reactions(\n",
+    "        model, \"Reaction12\", \"meta_Reaction12\", \"SBO:0000183\", \"transcription of CI\", False, libsbml.BIOLOGICAL_QUALIFIER, \n",
+    "        libsbml.BQB_IS_VERSION_OF, \"http://identifiers.org/GO:0006351\", \"a0_tr + (a_tr * power(KM, n)) / (power(KM, n) + power(PY, n))\", \n",
+    "        None\n",
     "    )\n",
-    "    kinetic_law = r12.createKineticLaw()\n",
-    "    kinetic_law.setMath(math_ast18)\n",
+    "    add_product_to_reaction(r12, \"Z\")\n",
+    "    add_modifier_to_reaction(r12, \"PY\", \"SBO:0000536\")\n",
     "\n",
     "    print(\"-\" * 80)\n",
     "    print(libsbml.writeSBMLToString(doc))\n",
@@ -600,624 +226,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
-   "id": "0a18aa9a",
+   "execution_count": null,
+   "id": "2f8eed9a",
    "metadata": {
-    "collapsed": false,
-    "jupyter": {
-     "outputs_hidden": false
-    }
+    "collapsed": false
    },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Create SBML model\n",
-      "--------------------------------------------------------------------------------\n",
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
-      "<sbml xmlns=\"http://www.sbml.org/sbml/level3/version2/core\" level=\"3\" version=\"2\">\n",
-      "  <model>\n",
-      "    <listOfCompartments>\n",
-      "      <compartment metaid=\"meta_cell\" sboTerm=\"SBO:0000290\" id=\"cell\" size=\"1\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_cell\">\n",
-      "              <bqbiol:is>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0005623\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:is>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </compartment>\n",
-      "    </listOfCompartments>\n",
-      "    <listOfSpecies>\n",
-      "      <species metaid=\"PX\" sboTerm=\"SBO:0000252\" id=\"PX\" name=\"LacI protein\" compartment=\"cell\" initialAmount=\"0\" hasOnlySubstanceUnits=\"true\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#PX\">\n",
-      "              <bqbiol:is>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/uniprot/P03023\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:is>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </species>\n",
-      "      <species metaid=\"PY\" sboTerm=\"SBO:0000252\" id=\"PY\" name=\"TetR protein\" compartment=\"cell\" initialAmount=\"0\" hasOnlySubstanceUnits=\"true\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#PY\">\n",
-      "              <bqbiol:is>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/uniprot/P04483\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:is>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </species>\n",
-      "      <species metaid=\"PZ\" sboTerm=\"SBO:0000252\" id=\"PZ\" name=\"cI protein\" compartment=\"cell\" initialAmount=\"0\" hasOnlySubstanceUnits=\"true\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#PZ\">\n",
-      "              <bqbiol:is>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/uniprot/P03034\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:is>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </species>\n",
-      "      <species metaid=\"meta_X\" sboTerm=\"SBO:0000250\" id=\"X\" name=\"LacI mRNA\" compartment=\"cell\" initialAmount=\"0\" hasOnlySubstanceUnits=\"true\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_X\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/CHEBI:33699\"/>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/kegg.compound/C00046\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "              <bqbiol:encodes>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/uniprot/P03023\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:encodes>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </species>\n",
-      "      <species metaid=\"meta_Y\" sboTerm=\"SBO:0000250\" id=\"Y\" name=\"TetR mRNA\" compartment=\"cell\" initialAmount=\"20\" hasOnlySubstanceUnits=\"true\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Y\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/CHEBI:33699\"/>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/kegg.compound/C00046\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "              <bqbiol:encodes>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/uniprot/P04483\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:encodes>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </species>\n",
-      "      <species metaid=\"meta_Z\" sboTerm=\"SBO:0000250\" id=\"Z\" name=\"cl mRNA\" compartment=\"cell\" initialAmount=\"0\" hasOnlySubstanceUnits=\"true\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Z\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/CHEBI:33699\"/>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/kegg.compound/C00046\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "              <bqbiol:encodes>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/uniprot/P03034\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:encodes>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "      </species>\n",
-      "    </listOfSpecies>\n",
-      "    <listOfParameters>\n",
-      "      <parameter id=\"tau_mRNA\" name=\"mRNA half life\" value=\"2\" constant=\"true\"/>\n",
-      "      <parameter sboTerm=\"SBO:0000356\" id=\"kd_mRNA\" name=\"kd_mRNA\" constant=\"false\"/>\n",
-      "      <parameter sboTerm=\"SBO:0000016\" id=\"k_tl\" name=\"k_tl\" constant=\"false\"/>\n",
-      "      <parameter id=\"eff\" name=\"translation efficiency\" value=\"20\" constant=\"true\"/>\n",
-      "      <parameter sboTerm=\"SBO:0000348\" id=\"t_ave\" name=\"average mRNA life time\" constant=\"false\"/>\n",
-      "      <parameter sboTerm=\"SBO:0000356\" id=\"kd_prot\" name=\"kd_prot\" constant=\"false\"/>\n",
-      "      <parameter id=\"tau_prot\" name=\"protien half life\" value=\"10\" constant=\"true\"/>\n",
-      "      <parameter sboTerm=\"SBO:0000485\" id=\"a0_tr\" name=\"a0_tr\" constant=\"false\"/>\n",
-      "      <parameter id=\"ps_0\" name=\"tps_repr\" value=\"0.0005\" constant=\"true\"/>\n",
-      "      <parameter sboTerm=\"SBO:0000186\" id=\"a_tr\" name=\"a_tr\" constant=\"false\"/>\n",
-      "      <parameter id=\"ps_a\" name=\"tps_active\" value=\"0.5\" constant=\"true\"/>\n",
-      "      <parameter id=\"KM\" name=\"KM\" value=\"40\" constant=\"true\"/>\n",
-      "      <parameter id=\"n\" name=\"n\" value=\"2\" constant=\"true\"/>\n",
-      "    </listOfParameters>\n",
-      "    <listOfRules>\n",
-      "      <assignmentRule variable=\"kd_mRNA\">\n",
-      "        <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "          <apply>\n",
-      "            <divide/>\n",
-      "            <apply>\n",
-      "              <ln/>\n",
-      "              <cn type=\"integer\"> 2 </cn>\n",
-      "            </apply>\n",
-      "            <ci> tau_mRNA </ci>\n",
-      "          </apply>\n",
-      "        </math>\n",
-      "      </assignmentRule>\n",
-      "      <assignmentRule variable=\"t_ave\">\n",
-      "        <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "          <apply>\n",
-      "            <divide/>\n",
-      "            <ci> tau_mRNA </ci>\n",
-      "            <apply>\n",
-      "              <ln/>\n",
-      "              <cn type=\"integer\"> 2 </cn>\n",
-      "            </apply>\n",
-      "          </apply>\n",
-      "        </math>\n",
-      "      </assignmentRule>\n",
-      "      <assignmentRule variable=\"k_tl\">\n",
-      "        <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "          <apply>\n",
-      "            <divide/>\n",
-      "            <ci> eff </ci>\n",
-      "            <ci> t_ave </ci>\n",
-      "          </apply>\n",
-      "        </math>\n",
-      "      </assignmentRule>\n",
-      "      <assignmentRule variable=\"kd_prot\">\n",
-      "        <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "          <apply>\n",
-      "            <divide/>\n",
-      "            <apply>\n",
-      "              <ln/>\n",
-      "              <cn type=\"integer\"> 2 </cn>\n",
-      "            </apply>\n",
-      "            <ci> tau_prot </ci>\n",
-      "          </apply>\n",
-      "        </math>\n",
-      "      </assignmentRule>\n",
-      "      <assignmentRule variable=\"a0_tr\">\n",
-      "        <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "          <apply>\n",
-      "            <times/>\n",
-      "            <ci> ps_0 </ci>\n",
-      "            <cn type=\"integer\"> 60 </cn>\n",
-      "          </apply>\n",
-      "        </math>\n",
-      "      </assignmentRule>\n",
-      "      <assignmentRule variable=\"a_tr\">\n",
-      "        <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "          <apply>\n",
-      "            <times/>\n",
-      "            <apply>\n",
-      "              <minus/>\n",
-      "              <ci> ps_a </ci>\n",
-      "              <ci> ps_0 </ci>\n",
-      "            </apply>\n",
-      "            <cn type=\"integer\"> 60 </cn>\n",
-      "          </apply>\n",
-      "        </math>\n",
-      "      </assignmentRule>\n",
-      "    </listOfRules>\n",
-      "    <listOfReactions>\n",
-      "      <reaction metaid=\"meta_Reaction1\" sboTerm=\"SBO:0000179\" id=\"Reaction1\" name=\"degradation of LacI transcripts\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction1\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006402\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfReactants>\n",
-      "          <speciesReference species=\"X\"/>\n",
-      "        </listOfReactants>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> kd_mRNA </ci>\n",
-      "              <ci> X </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction2\" sboTerm=\"SBO:0000179\" id=\"Reaction2\" name=\"degradation of TetR transcripts\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction2\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006402\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfReactants>\n",
-      "          <speciesReference species=\"Y\"/>\n",
-      "        </listOfReactants>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> kd_mRNA </ci>\n",
-      "              <ci> Y </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction3\" sboTerm=\"SBO:0000179\" id=\"Reaction3\" name=\"degradation of CI transcripts\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction3\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006402\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfReactants>\n",
-      "          <speciesReference species=\"Z\"/>\n",
-      "        </listOfReactants>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> kd_mRNA </ci>\n",
-      "              <ci> Z </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction4\" sboTerm=\"SBO:0000184\" id=\"Reaction4\" name=\"translation of LacI\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction4\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006412\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfProducts>\n",
-      "          <speciesReference species=\"PX\"/>\n",
-      "        </listOfProducts>\n",
-      "        <listOfModifiers>\n",
-      "          <modifierSpeciesReference sboTerm=\"SBO:0000461\" species=\"X\"/>\n",
-      "        </listOfModifiers>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> k_tl </ci>\n",
-      "              <ci> X </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction5\" sboTerm=\"SBO:0000184\" id=\"Reaction5\" name=\"translation of TetR\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction5\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006412\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfProducts>\n",
-      "          <speciesReference species=\"PY\"/>\n",
-      "        </listOfProducts>\n",
-      "        <listOfModifiers>\n",
-      "          <modifierSpeciesReference sboTerm=\"SBO:0000461\" species=\"Y\"/>\n",
-      "        </listOfModifiers>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> k_tl </ci>\n",
-      "              <ci> Y </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction6\" sboTerm=\"SBO:0000184\" id=\"Reaction6\" name=\"translation of CI\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction6\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006412\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfProducts>\n",
-      "          <speciesReference species=\"PZ\"/>\n",
-      "        </listOfProducts>\n",
-      "        <listOfModifiers>\n",
-      "          <modifierSpeciesReference sboTerm=\"SBO:0000461\" species=\"Z\"/>\n",
-      "        </listOfModifiers>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> k_tl </ci>\n",
-      "              <ci> Z </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction7\" sboTerm=\"SBO:0000179\" id=\"Reaction7\" name=\"degradation of LacI\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction7\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0030163\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfReactants>\n",
-      "          <speciesReference species=\"PX\"/>\n",
-      "        </listOfReactants>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> kd_prot </ci>\n",
-      "              <ci> PX </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction8\" sboTerm=\"SBO:0000179\" id=\"Reaction8\" name=\"degradation of TetR\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction8\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0030163\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfReactants>\n",
-      "          <speciesReference species=\"PY\"/>\n",
-      "        </listOfReactants>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> kd_prot </ci>\n",
-      "              <ci> PY </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction9\" sboTerm=\"SBO:0000179\" id=\"Reaction9\" name=\"degradation of CI\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction9\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0030163\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfReactants>\n",
-      "          <speciesReference species=\"PZ\"/>\n",
-      "        </listOfReactants>\n",
-      "        <kineticLaw sboTerm=\"SBO:0000049\">\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <times/>\n",
-      "              <ci> kd_prot </ci>\n",
-      "              <ci> PZ </ci>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction10\" sboTerm=\"SBO:0000183\" id=\"Reaction10\" name=\"transcription of LacI\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction10\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006351\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfProducts>\n",
-      "          <speciesReference species=\"X\"/>\n",
-      "        </listOfProducts>\n",
-      "        <listOfModifiers>\n",
-      "          <modifierSpeciesReference sboTerm=\"SBO:0000536\" species=\"PZ\"/>\n",
-      "        </listOfModifiers>\n",
-      "        <kineticLaw>\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <plus/>\n",
-      "              <ci> a0_tr </ci>\n",
-      "              <apply>\n",
-      "                <divide/>\n",
-      "                <apply>\n",
-      "                  <times/>\n",
-      "                  <ci> a_tr </ci>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> KM </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                </apply>\n",
-      "                <apply>\n",
-      "                  <plus/>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> KM </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> PZ </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                </apply>\n",
-      "              </apply>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction11\" sboTerm=\"SBO:0000183\" id=\"Reaction11\" name=\"transcription of TetR\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction11\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006351\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfProducts>\n",
-      "          <speciesReference species=\"Y\"/>\n",
-      "        </listOfProducts>\n",
-      "        <listOfModifiers>\n",
-      "          <modifierSpeciesReference sboTerm=\"SBO:0000536\" species=\"PX\"/>\n",
-      "        </listOfModifiers>\n",
-      "        <kineticLaw>\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <plus/>\n",
-      "              <ci> a0_tr </ci>\n",
-      "              <apply>\n",
-      "                <divide/>\n",
-      "                <apply>\n",
-      "                  <times/>\n",
-      "                  <ci> a_tr </ci>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> KM </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                </apply>\n",
-      "                <apply>\n",
-      "                  <plus/>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> KM </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> PX </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                </apply>\n",
-      "              </apply>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "      <reaction metaid=\"meta_Reaction12\" sboTerm=\"SBO:0000183\" id=\"Reaction12\" name=\"transcription of CI\" reversible=\"false\">\n",
-      "        <annotation>\n",
-      "          <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:vCard=\"http://www.w3.org/2001/vcard-rdf/3.0#\" xmlns:vCard4=\"http://www.w3.org/2006/vcard/ns#\" xmlns:bqbiol=\"http://biomodels.net/biology-qualifiers/\" xmlns:bqmodel=\"http://biomodels.net/model-qualifiers/\">\n",
-      "            <rdf:Description rdf:about=\"#meta_Reaction12\">\n",
-      "              <bqbiol:isVersionOf>\n",
-      "                <rdf:Bag>\n",
-      "                  <rdf:li rdf:resource=\"http://identifiers.org/GO:0006351\"/>\n",
-      "                </rdf:Bag>\n",
-      "              </bqbiol:isVersionOf>\n",
-      "            </rdf:Description>\n",
-      "          </rdf:RDF>\n",
-      "        </annotation>\n",
-      "        <listOfProducts>\n",
-      "          <speciesReference species=\"Z\"/>\n",
-      "        </listOfProducts>\n",
-      "        <listOfModifiers>\n",
-      "          <modifierSpeciesReference sboTerm=\"SBO:0000536\" species=\"PY\"/>\n",
-      "        </listOfModifiers>\n",
-      "        <kineticLaw>\n",
-      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
-      "            <apply>\n",
-      "              <plus/>\n",
-      "              <ci> a0_tr </ci>\n",
-      "              <apply>\n",
-      "                <divide/>\n",
-      "                <apply>\n",
-      "                  <times/>\n",
-      "                  <ci> a_tr </ci>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> KM </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                </apply>\n",
-      "                <apply>\n",
-      "                  <plus/>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> KM </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                  <apply>\n",
-      "                    <power/>\n",
-      "                    <ci> PY </ci>\n",
-      "                    <ci> n </ci>\n",
-      "                  </apply>\n",
-      "                </apply>\n",
-      "              </apply>\n",
-      "            </apply>\n",
-      "          </math>\n",
-      "        </kineticLaw>\n",
-      "      </reaction>\n",
-      "    </listOfReactions>\n",
-      "  </model>\n",
-      "</sbml>\n",
-      "\n",
-      "--------------------------------------------------------------------------------\n",
-      "--------------------------------------------------------------------------------\n",
-      "validation error(s)      : 0\n",
-      "validation warning(s)    : 0\n",
-      "--------------------------------------------------------------------------------\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "if __name__ == \"__main__\":\n",
     "    from combine_notebooks import RESULTS_DIR\n",
@@ -1233,25 +247,7 @@
    ]
   }
  ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "combine_notebooks",
-   "language": "python",
-   "name": "combine_notebooks"
-  },
-  "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.6"
-  }
- },
+ "metadata": {},
  "nbformat": 4,
  "nbformat_minor": 5
 }
diff --git a/notebooks/neuroml.ipynb b/notebooks/neuroml.ipynb
new file mode 100644
index 0000000..68adaee
--- /dev/null
+++ b/notebooks/neuroml.ipynb
@@ -0,0 +1,780 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Interactive single Izhikevich neuron NeuroML example\n",
+    "\n",
+    "To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see {ref}`how to use this documentation <userdocs:usage:jupyterbooks>`.\n",
+    "Please uncomment the line below if you use the Google Colab (it does not include these packages by default)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#%pip install pyneuroml neuromllite NEURON"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from neuroml import NeuroMLDocument\n",
+    "import neuroml.writers as writers\n",
+    "from neuroml.utils import component_factory\n",
+    "from neuroml.utils import validate_neuroml2\n",
+    "from pyneuroml import pynml\n",
+    "from pyneuroml.lems import LEMSSimulation\n",
+    "import numpy as np"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Declaring the NeuroML model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Create a NeuroML document"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "nml_doc = component_factory(NeuroMLDocument, id=\"IzhSingleNeuron\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n",
+      "\n",
+      "Valid members for NeuroMLDocument are:\n",
+      "* ion_channel_kses (class: IonChannelKS, Optional)\n",
+      "* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n",
+      "* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n",
+      "* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n",
+      "* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n",
+      "* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n",
+      "* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n",
+      "* IF_curr_alpha (class: IF_curr_alpha, Optional)\n",
+      "* alpha_synapses (class: AlphaSynapse, Optional)\n",
+      "* IF_curr_exp (class: IF_curr_exp, Optional)\n",
+      "* exp_one_synapses (class: ExpOneSynapse, Optional)\n",
+      "* IF_cond_alpha (class: IF_cond_alpha, Optional)\n",
+      "* exp_two_synapses (class: ExpTwoSynapse, Optional)\n",
+      "* IF_cond_exp (class: IF_cond_exp, Optional)\n",
+      "* exp_three_synapses (class: ExpThreeSynapse, Optional)\n",
+      "* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n",
+      "* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n",
+      "* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n",
+      "* double_synapses (class: DoubleSynapse, Optional)\n",
+      "* HH_cond_exp (class: HH_cond_exp, Optional)\n",
+      "* gap_junctions (class: GapJunction, Optional)\n",
+      "* exp_cond_synapses (class: ExpCondSynapse, Optional)\n",
+      "* silent_synapses (class: SilentSynapse, Optional)\n",
+      "* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n",
+      "* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n",
+      "* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n",
+      "* graded_synapses (class: GradedSynapse, Optional)\n",
+      "* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n",
+      "* biophysical_properties (class: BiophysicalProperties, Optional)\n",
+      "* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n",
+      "* cells (class: Cell, Optional)\n",
+      "* networks (class: Network, Optional)\n",
+      "* cell2_ca_poolses (class: Cell2CaPools, Optional)\n",
+      "* ComponentType (class: ComponentType, Optional)\n",
+      "* id (class: NmlId, Required)\n",
+      "* base_cells (class: BaseCell, Optional)\n",
+      "* iaf_tau_cells (class: IafTauCell, Optional)\n",
+      "* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n",
+      "* iaf_cells (class: IafCell, Optional)\n",
+      "* iaf_ref_cells (class: IafRefCell, Optional)\n",
+      "* izhikevich_cells (class: IzhikevichCell, Optional)\n",
+      "* annotation (class: Annotation, Optional)\n",
+      "* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n",
+      "* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n",
+      "* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n",
+      "* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n",
+      "* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n",
+      "* properties (class: Property, Optional)\n",
+      "* pulse_generators (class: PulseGenerator, Optional)\n",
+      "* notes (class: xs:string, Optional)\n",
+      "* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n",
+      "* metaid (class: MetaId, Optional)\n",
+      "* sine_generators (class: SineGenerator, Optional)\n",
+      "* sine_generator_dls (class: SineGeneratorDL, Optional)\n",
+      "* ramp_generators (class: RampGenerator, Optional)\n",
+      "* ramp_generator_dls (class: RampGeneratorDL, Optional)\n",
+      "* compound_inputs (class: CompoundInput, Optional)\n",
+      "* compound_input_dls (class: CompoundInputDL, Optional)\n",
+      "* includes (class: IncludeType, Optional)\n",
+      "* voltage_clamps (class: VoltageClamp, Optional)\n",
+      "* extracellular_properties (class: ExtracellularProperties, Optional)\n",
+      "* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n",
+      "* intracellular_properties (class: IntracellularProperties, Optional)\n",
+      "* spike_arrays (class: SpikeArray, Optional)\n",
+      "* morphology (class: Morphology, Optional)\n",
+      "* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n",
+      "* ion_channel (class: IonChannel, Optional)\n",
+      "* spike_generators (class: SpikeGenerator, Optional)\n",
+      "* ion_channel_hhs (class: IonChannelHH, Optional)\n",
+      "* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n",
+      "* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n",
+      "* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for NeuroMLDocument are:\\n* ion_channel_kses (class: IonChannelKS, Optional)\\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\\n* alpha_synapses (class: AlphaSynapse, Optional)\\n* IF_curr_exp (class: IF_curr_exp, Optional)\\n* exp_one_synapses (class: ExpOneSynapse, Optional)\\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\\n* IF_cond_exp (class: IF_cond_exp, Optional)\\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\\n* double_synapses (class: DoubleSynapse, Optional)\\n* HH_cond_exp (class: HH_cond_exp, Optional)\\n* gap_junctions (class: GapJunction, Optional)\\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\\n* silent_synapses (class: SilentSynapse, Optional)\\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\\n* graded_synapses (class: GradedSynapse, Optional)\\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\\n* biophysical_properties (class: BiophysicalProperties, Optional)\\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\\n* cells (class: Cell, Optional)\\n* networks (class: Network, Optional)\\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\\n* ComponentType (class: ComponentType, Optional)\\n* id (class: NmlId, Required)\\n* base_cells (class: BaseCell, Optional)\\n* iaf_tau_cells (class: IafTauCell, Optional)\\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\\n* iaf_cells (class: IafCell, Optional)\\n* iaf_ref_cells (class: IafRefCell, Optional)\\n* izhikevich_cells (class: IzhikevichCell, Optional)\\n* annotation (class: Annotation, Optional)\\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\\n* properties (class: Property, Optional)\\n* pulse_generators (class: PulseGenerator, Optional)\\n* notes (class: xs:string, Optional)\\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\\n* metaid (class: MetaId, Optional)\\n* sine_generators (class: SineGenerator, Optional)\\n* sine_generator_dls (class: SineGeneratorDL, Optional)\\n* ramp_generators (class: RampGenerator, Optional)\\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\\n* compound_inputs (class: CompoundInput, Optional)\\n* compound_input_dls (class: CompoundInputDL, Optional)\\n* includes (class: IncludeType, Optional)\\n* voltage_clamps (class: VoltageClamp, Optional)\\n* extracellular_properties (class: ExtracellularProperties, Optional)\\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\\n* intracellular_properties (class: IntracellularProperties, Optional)\\n* spike_arrays (class: SpikeArray, Optional)\\n* morphology (class: Morphology, Optional)\\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\\n* ion_channel (class: IonChannel, Optional)\\n* spike_generators (class: SpikeGenerator, Optional)\\n* ion_channel_hhs (class: IonChannelHH, Optional)\\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\\n'"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "nml_doc.info()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n",
+      "\n",
+      "Valid members for NeuroMLDocument are:\n",
+      "* ion_channel_kses (class: IonChannelKS, Optional)\n",
+      "* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n",
+      "* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n",
+      "* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n",
+      "* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n",
+      "* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n",
+      "* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n",
+      "* IF_curr_alpha (class: IF_curr_alpha, Optional)\n",
+      "* alpha_synapses (class: AlphaSynapse, Optional)\n",
+      "* IF_curr_exp (class: IF_curr_exp, Optional)\n",
+      "* exp_one_synapses (class: ExpOneSynapse, Optional)\n",
+      "* IF_cond_alpha (class: IF_cond_alpha, Optional)\n",
+      "* exp_two_synapses (class: ExpTwoSynapse, Optional)\n",
+      "* IF_cond_exp (class: IF_cond_exp, Optional)\n",
+      "* exp_three_synapses (class: ExpThreeSynapse, Optional)\n",
+      "* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n",
+      "* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n",
+      "* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n",
+      "* double_synapses (class: DoubleSynapse, Optional)\n",
+      "* HH_cond_exp (class: HH_cond_exp, Optional)\n",
+      "* gap_junctions (class: GapJunction, Optional)\n",
+      "* exp_cond_synapses (class: ExpCondSynapse, Optional)\n",
+      "* silent_synapses (class: SilentSynapse, Optional)\n",
+      "* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n",
+      "* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n",
+      "* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n",
+      "* graded_synapses (class: GradedSynapse, Optional)\n",
+      "* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n",
+      "* biophysical_properties (class: BiophysicalProperties, Optional)\n",
+      "* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n",
+      "* cells (class: Cell, Optional)\n",
+      "* networks (class: Network, Optional)\n",
+      "* cell2_ca_poolses (class: Cell2CaPools, Optional)\n",
+      "* ComponentType (class: ComponentType, Optional)\n",
+      "* id (class: NmlId, Required)\n",
+      "\t* Contents ('ids'/<objects>): IzhSingleNeuron\n",
+      "\n",
+      "* base_cells (class: BaseCell, Optional)\n",
+      "* iaf_tau_cells (class: IafTauCell, Optional)\n",
+      "* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n",
+      "* iaf_cells (class: IafCell, Optional)\n",
+      "* iaf_ref_cells (class: IafRefCell, Optional)\n",
+      "* izhikevich_cells (class: IzhikevichCell, Optional)\n",
+      "* annotation (class: Annotation, Optional)\n",
+      "* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n",
+      "* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n",
+      "* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n",
+      "* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n",
+      "* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n",
+      "* properties (class: Property, Optional)\n",
+      "* pulse_generators (class: PulseGenerator, Optional)\n",
+      "* notes (class: xs:string, Optional)\n",
+      "* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n",
+      "* metaid (class: MetaId, Optional)\n",
+      "* sine_generators (class: SineGenerator, Optional)\n",
+      "* sine_generator_dls (class: SineGeneratorDL, Optional)\n",
+      "* ramp_generators (class: RampGenerator, Optional)\n",
+      "* ramp_generator_dls (class: RampGeneratorDL, Optional)\n",
+      "* compound_inputs (class: CompoundInput, Optional)\n",
+      "* compound_input_dls (class: CompoundInputDL, Optional)\n",
+      "* includes (class: IncludeType, Optional)\n",
+      "* voltage_clamps (class: VoltageClamp, Optional)\n",
+      "* extracellular_properties (class: ExtracellularProperties, Optional)\n",
+      "* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n",
+      "* intracellular_properties (class: IntracellularProperties, Optional)\n",
+      "* spike_arrays (class: SpikeArray, Optional)\n",
+      "* morphology (class: Morphology, Optional)\n",
+      "* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n",
+      "* ion_channel (class: IonChannel, Optional)\n",
+      "* spike_generators (class: SpikeGenerator, Optional)\n",
+      "* ion_channel_hhs (class: IonChannelHH, Optional)\n",
+      "* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n",
+      "* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n",
+      "* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "\"Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for NeuroMLDocument are:\\n* ion_channel_kses (class: IonChannelKS, Optional)\\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\\n* alpha_synapses (class: AlphaSynapse, Optional)\\n* IF_curr_exp (class: IF_curr_exp, Optional)\\n* exp_one_synapses (class: ExpOneSynapse, Optional)\\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\\n* IF_cond_exp (class: IF_cond_exp, Optional)\\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\\n* double_synapses (class: DoubleSynapse, Optional)\\n* HH_cond_exp (class: HH_cond_exp, Optional)\\n* gap_junctions (class: GapJunction, Optional)\\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\\n* silent_synapses (class: SilentSynapse, Optional)\\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\\n* graded_synapses (class: GradedSynapse, Optional)\\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\\n* biophysical_properties (class: BiophysicalProperties, Optional)\\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\\n* cells (class: Cell, Optional)\\n* networks (class: Network, Optional)\\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\\n* ComponentType (class: ComponentType, Optional)\\n* id (class: NmlId, Required)\\n\\t* Contents ('ids'/<objects>): IzhSingleNeuron\\n\\n* base_cells (class: BaseCell, Optional)\\n* iaf_tau_cells (class: IafTauCell, Optional)\\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\\n* iaf_cells (class: IafCell, Optional)\\n* iaf_ref_cells (class: IafRefCell, Optional)\\n* izhikevich_cells (class: IzhikevichCell, Optional)\\n* annotation (class: Annotation, Optional)\\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\\n* properties (class: Property, Optional)\\n* pulse_generators (class: PulseGenerator, Optional)\\n* notes (class: xs:string, Optional)\\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\\n* metaid (class: MetaId, Optional)\\n* sine_generators (class: SineGenerator, Optional)\\n* sine_generator_dls (class: SineGeneratorDL, Optional)\\n* ramp_generators (class: RampGenerator, Optional)\\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\\n* compound_inputs (class: CompoundInput, Optional)\\n* compound_input_dls (class: CompoundInputDL, Optional)\\n* includes (class: IncludeType, Optional)\\n* voltage_clamps (class: VoltageClamp, Optional)\\n* extracellular_properties (class: ExtracellularProperties, Optional)\\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\\n* intracellular_properties (class: IntracellularProperties, Optional)\\n* spike_arrays (class: SpikeArray, Optional)\\n* morphology (class: Morphology, Optional)\\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\\n* ion_channel (class: IonChannel, Optional)\\n* spike_generators (class: SpikeGenerator, Optional)\\n* ion_channel_hhs (class: IonChannelHH, Optional)\\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\\n\""
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "nml_doc.info(True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Define the Izhikevich cell and add it to the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Izhikevich2007Cell -- Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press\n",
+      "\n",
+      "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n",
+      "\n",
+      "Valid members for Izhikevich2007Cell are:\n",
+      "* vt (class: Nml2Quantity_voltage, Required)\n",
+      "\t* Contents ('ids'/<objects>): -40mV\n",
+      "\n",
+      "* annotation (class: Annotation, Optional)\n",
+      "* vpeak (class: Nml2Quantity_voltage, Required)\n",
+      "\t* Contents ('ids'/<objects>): 35mV\n",
+      "\n",
+      "* a (class: Nml2Quantity_pertime, Required)\n",
+      "\t* Contents ('ids'/<objects>): 0.03per_ms\n",
+      "\n",
+      "* C (class: Nml2Quantity_capacitance, Required)\n",
+      "\t* Contents ('ids'/<objects>): 100pF\n",
+      "\n",
+      "* b (class: Nml2Quantity_conductance, Required)\n",
+      "\t* Contents ('ids'/<objects>): -2nS\n",
+      "\n",
+      "* c (class: Nml2Quantity_voltage, Required)\n",
+      "\t* Contents ('ids'/<objects>): -50.0mV\n",
+      "\n",
+      "* d (class: Nml2Quantity_current, Required)\n",
+      "\t* Contents ('ids'/<objects>): 100pA\n",
+      "\n",
+      "* properties (class: Property, Optional)\n",
+      "* id (class: NmlId, Required)\n",
+      "\t* Contents ('ids'/<objects>): izh2007RS0\n",
+      "\n",
+      "* metaid (class: MetaId, Optional)\n",
+      "* notes (class: xs:string, Optional)\n",
+      "* neuro_lex_id (class: NeuroLexId, Optional)\n",
+      "* v0 (class: Nml2Quantity_voltage, Required)\n",
+      "\t* Contents ('ids'/<objects>): -60mV\n",
+      "\n",
+      "* k (class: Nml2Quantity_conductancePerVoltage, Required)\n",
+      "\t* Contents ('ids'/<objects>): 0.7nS_per_mV\n",
+      "\n",
+      "* vr (class: Nml2Quantity_voltage, Required)\n",
+      "\t* Contents ('ids'/<objects>): -60mV\n",
+      "\n",
+      "\n",
+      "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n",
+      "\n",
+      "Valid members for NeuroMLDocument are:\n",
+      "* ion_channel_kses (class: IonChannelKS, Optional)\n",
+      "* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\n",
+      "* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\n",
+      "* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\n",
+      "* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\n",
+      "* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\n",
+      "* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\n",
+      "* IF_curr_alpha (class: IF_curr_alpha, Optional)\n",
+      "* alpha_synapses (class: AlphaSynapse, Optional)\n",
+      "* IF_curr_exp (class: IF_curr_exp, Optional)\n",
+      "* exp_one_synapses (class: ExpOneSynapse, Optional)\n",
+      "* IF_cond_alpha (class: IF_cond_alpha, Optional)\n",
+      "* exp_two_synapses (class: ExpTwoSynapse, Optional)\n",
+      "* IF_cond_exp (class: IF_cond_exp, Optional)\n",
+      "* exp_three_synapses (class: ExpThreeSynapse, Optional)\n",
+      "* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\n",
+      "* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\n",
+      "* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\n",
+      "* double_synapses (class: DoubleSynapse, Optional)\n",
+      "* HH_cond_exp (class: HH_cond_exp, Optional)\n",
+      "* gap_junctions (class: GapJunction, Optional)\n",
+      "* exp_cond_synapses (class: ExpCondSynapse, Optional)\n",
+      "* silent_synapses (class: SilentSynapse, Optional)\n",
+      "* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\n",
+      "* linear_graded_synapses (class: LinearGradedSynapse, Optional)\n",
+      "* exp_curr_synapses (class: ExpCurrSynapse, Optional)\n",
+      "* graded_synapses (class: GradedSynapse, Optional)\n",
+      "* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\n",
+      "* biophysical_properties (class: BiophysicalProperties, Optional)\n",
+      "* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\n",
+      "* cells (class: Cell, Optional)\n",
+      "* networks (class: Network, Optional)\n",
+      "* cell2_ca_poolses (class: Cell2CaPools, Optional)\n",
+      "* ComponentType (class: ComponentType, Optional)\n",
+      "* id (class: NmlId, Required)\n",
+      "\t* Contents ('ids'/<objects>): IzhSingleNeuron\n",
+      "\n",
+      "* base_cells (class: BaseCell, Optional)\n",
+      "* iaf_tau_cells (class: IafTauCell, Optional)\n",
+      "* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\n",
+      "* iaf_cells (class: IafCell, Optional)\n",
+      "* iaf_ref_cells (class: IafRefCell, Optional)\n",
+      "* izhikevich_cells (class: IzhikevichCell, Optional)\n",
+      "* annotation (class: Annotation, Optional)\n",
+      "* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\n",
+      "\t* Contents ('ids'/<objects>): ['izh2007RS0']\n",
+      "\n",
+      "* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\n",
+      "* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\n",
+      "* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\n",
+      "* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\n",
+      "* properties (class: Property, Optional)\n",
+      "* pulse_generators (class: PulseGenerator, Optional)\n",
+      "* notes (class: xs:string, Optional)\n",
+      "* pulse_generator_dls (class: PulseGeneratorDL, Optional)\n",
+      "* metaid (class: MetaId, Optional)\n",
+      "* sine_generators (class: SineGenerator, Optional)\n",
+      "* sine_generator_dls (class: SineGeneratorDL, Optional)\n",
+      "* ramp_generators (class: RampGenerator, Optional)\n",
+      "* ramp_generator_dls (class: RampGeneratorDL, Optional)\n",
+      "* compound_inputs (class: CompoundInput, Optional)\n",
+      "* compound_input_dls (class: CompoundInputDL, Optional)\n",
+      "* includes (class: IncludeType, Optional)\n",
+      "* voltage_clamps (class: VoltageClamp, Optional)\n",
+      "* extracellular_properties (class: ExtracellularProperties, Optional)\n",
+      "* voltage_clamp_triples (class: VoltageClampTriple, Optional)\n",
+      "* intracellular_properties (class: IntracellularProperties, Optional)\n",
+      "* spike_arrays (class: SpikeArray, Optional)\n",
+      "* morphology (class: Morphology, Optional)\n",
+      "* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\n",
+      "* ion_channel (class: IonChannel, Optional)\n",
+      "* spike_generators (class: SpikeGenerator, Optional)\n",
+      "* ion_channel_hhs (class: IonChannelHH, Optional)\n",
+      "* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\n",
+      "* ion_channel_v_shifts (class: IonChannelVShift, Optional)\n",
+      "* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "\"Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for NeuroMLDocument are:\\n* ion_channel_kses (class: IonChannelKS, Optional)\\n* spike_generator_ref_poissons (class: SpikeGeneratorRefPoisson, Optional)\\n* decaying_pool_concentration_models (class: DecayingPoolConcentrationModel, Optional)\\n* poisson_firing_synapses (class: PoissonFiringSynapse, Optional)\\n* fixed_factor_concentration_models (class: FixedFactorConcentrationModel, Optional)\\n* transient_poisson_firing_synapses (class: TransientPoissonFiringSynapse, Optional)\\n* alpha_current_synapses (class: AlphaCurrentSynapse, Optional)\\n* IF_curr_alpha (class: IF_curr_alpha, Optional)\\n* alpha_synapses (class: AlphaSynapse, Optional)\\n* IF_curr_exp (class: IF_curr_exp, Optional)\\n* exp_one_synapses (class: ExpOneSynapse, Optional)\\n* IF_cond_alpha (class: IF_cond_alpha, Optional)\\n* exp_two_synapses (class: ExpTwoSynapse, Optional)\\n* IF_cond_exp (class: IF_cond_exp, Optional)\\n* exp_three_synapses (class: ExpThreeSynapse, Optional)\\n* EIF_cond_exp_isfa_ista (class: EIF_cond_exp_isfa_ista, Optional)\\n* blocking_plastic_synapses (class: BlockingPlasticSynapse, Optional)\\n* EIF_cond_alpha_isfa_ista (class: EIF_cond_alpha_isfa_ista, Optional)\\n* double_synapses (class: DoubleSynapse, Optional)\\n* HH_cond_exp (class: HH_cond_exp, Optional)\\n* gap_junctions (class: GapJunction, Optional)\\n* exp_cond_synapses (class: ExpCondSynapse, Optional)\\n* silent_synapses (class: SilentSynapse, Optional)\\n* alpha_cond_synapses (class: AlphaCondSynapse, Optional)\\n* linear_graded_synapses (class: LinearGradedSynapse, Optional)\\n* exp_curr_synapses (class: ExpCurrSynapse, Optional)\\n* graded_synapses (class: GradedSynapse, Optional)\\n* alpha_curr_synapses (class: AlphaCurrSynapse, Optional)\\n* biophysical_properties (class: BiophysicalProperties, Optional)\\n* SpikeSourcePoisson (class: SpikeSourcePoisson, Optional)\\n* cells (class: Cell, Optional)\\n* networks (class: Network, Optional)\\n* cell2_ca_poolses (class: Cell2CaPools, Optional)\\n* ComponentType (class: ComponentType, Optional)\\n* id (class: NmlId, Required)\\n\\t* Contents ('ids'/<objects>): IzhSingleNeuron\\n\\n* base_cells (class: BaseCell, Optional)\\n* iaf_tau_cells (class: IafTauCell, Optional)\\n* iaf_tau_ref_cells (class: IafTauRefCell, Optional)\\n* iaf_cells (class: IafCell, Optional)\\n* iaf_ref_cells (class: IafRefCell, Optional)\\n* izhikevich_cells (class: IzhikevichCell, Optional)\\n* annotation (class: Annotation, Optional)\\n* izhikevich2007_cells (class: Izhikevich2007Cell, Optional)\\n\\t* Contents ('ids'/<objects>): ['izh2007RS0']\\n\\n* ad_ex_ia_f_cells (class: AdExIaFCell, Optional)\\n* fitz_hugh_nagumo_cells (class: FitzHughNagumoCell, Optional)\\n* fitz_hugh_nagumo1969_cells (class: FitzHughNagumo1969Cell, Optional)\\n* pinsky_rinzel_ca3_cells (class: PinskyRinzelCA3Cell, Optional)\\n* properties (class: Property, Optional)\\n* pulse_generators (class: PulseGenerator, Optional)\\n* notes (class: xs:string, Optional)\\n* pulse_generator_dls (class: PulseGeneratorDL, Optional)\\n* metaid (class: MetaId, Optional)\\n* sine_generators (class: SineGenerator, Optional)\\n* sine_generator_dls (class: SineGeneratorDL, Optional)\\n* ramp_generators (class: RampGenerator, Optional)\\n* ramp_generator_dls (class: RampGeneratorDL, Optional)\\n* compound_inputs (class: CompoundInput, Optional)\\n* compound_input_dls (class: CompoundInputDL, Optional)\\n* includes (class: IncludeType, Optional)\\n* voltage_clamps (class: VoltageClamp, Optional)\\n* extracellular_properties (class: ExtracellularProperties, Optional)\\n* voltage_clamp_triples (class: VoltageClampTriple, Optional)\\n* intracellular_properties (class: IntracellularProperties, Optional)\\n* spike_arrays (class: SpikeArray, Optional)\\n* morphology (class: Morphology, Optional)\\n* timed_synaptic_inputs (class: TimedSynapticInput, Optional)\\n* ion_channel (class: IonChannel, Optional)\\n* spike_generators (class: SpikeGenerator, Optional)\\n* ion_channel_hhs (class: IonChannelHH, Optional)\\n* spike_generator_randoms (class: SpikeGeneratorRandom, Optional)\\n* ion_channel_v_shifts (class: IonChannelVShift, Optional)\\n* spike_generator_poissons (class: SpikeGeneratorPoisson, Optional)\\n\""
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "izh0 = nml_doc.add(\n",
+    "    \"Izhikevich2007Cell\",\n",
+    "    id=\"izh2007RS0\", v0=\"-60mV\", C=\"100pF\", k=\"0.7nS_per_mV\", vr=\"-60mV\",\n",
+    "    vt=\"-40mV\", vpeak=\"35mV\", a=\"0.03per_ms\", b=\"-2nS\", c=\"-50.0mV\", d=\"100pA\")\n",
+    "izh0.info(True)\n",
+    "nml_doc.info(show_contents=True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Create a network and add it to the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "net = nml_doc.add(\"Network\", id=\"IzNet\", validate=False)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Create a population of defined cells and add it to the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Network -- Network containing:  **population** s ( potentially of type  **populationList** , and so specifying a list of cell  **location** s );  **projection** s ( with lists of  **connection** s ) and/or  **explicitConnection** s; and  **inputList** s ( with lists of  **input** s ) and/or  **explicitInput** s. Note: often in NeuroML this will be of type  **networkWithTemperature**  if there are temperature dependent elements ( e. g. ion channels ).\n",
+      "\n",
+      "Please see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\n",
+      "\n",
+      "Valid members for Network are:\n",
+      "* id (class: NmlId, Required)\n",
+      "* type (class: networkTypes, Optional)\n",
+      "* annotation (class: Annotation, Optional)\n",
+      "* temperature (class: Nml2Quantity_temperature, Optional)\n",
+      "* neuro_lex_id (class: NeuroLexId, Optional)\n",
+      "* spaces (class: Space, Optional)\n",
+      "* regions (class: Region, Optional)\n",
+      "* extracellular_properties (class: ExtracellularPropertiesLocal, Optional)\n",
+      "* properties (class: Property, Optional)\n",
+      "* populations (class: Population, Required)\n",
+      "* notes (class: xs:string, Optional)\n",
+      "* cell_sets (class: CellSet, Optional)\n",
+      "* metaid (class: MetaId, Optional)\n",
+      "* synaptic_connections (class: SynapticConnection, Optional)\n",
+      "* projections (class: Projection, Optional)\n",
+      "* electrical_projections (class: ElectricalProjection, Optional)\n",
+      "* continuous_projections (class: ContinuousProjection, Optional)\n",
+      "* explicit_inputs (class: ExplicitInput, Optional)\n",
+      "* input_lists (class: InputList, Optional)\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'Network -- Network containing:  **population** s ( potentially of type  **populationList** , and so specifying a list of cell  **location** s );  **projection** s ( with lists of  **connection** s ) and/or  **explicitConnection** s; and  **inputList** s ( with lists of  **input** s ) and/or  **explicitInput** s. Note: often in NeuroML this will be of type  **networkWithTemperature**  if there are temperature dependent elements ( e. g. ion channels ).\\n\\nPlease see the NeuroML standard schema documentation at https://docs.neuroml.org/Userdocs/NeuroMLv2.html for more information.\\n\\nValid members for Network are:\\n* id (class: NmlId, Required)\\n* type (class: networkTypes, Optional)\\n* annotation (class: Annotation, Optional)\\n* temperature (class: Nml2Quantity_temperature, Optional)\\n* neuro_lex_id (class: NeuroLexId, Optional)\\n* spaces (class: Space, Optional)\\n* regions (class: Region, Optional)\\n* extracellular_properties (class: ExtracellularPropertiesLocal, Optional)\\n* properties (class: Property, Optional)\\n* populations (class: Population, Required)\\n* notes (class: xs:string, Optional)\\n* cell_sets (class: CellSet, Optional)\\n* metaid (class: MetaId, Optional)\\n* synaptic_connections (class: SynapticConnection, Optional)\\n* projections (class: Projection, Optional)\\n* electrical_projections (class: ElectricalProjection, Optional)\\n* continuous_projections (class: ContinuousProjection, Optional)\\n* explicit_inputs (class: ExplicitInput, Optional)\\n* input_lists (class: InputList, Optional)\\n'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "size0 = 1\n",
+    "pop0 = net.add(\"Population\", id=\"IzhPop0\", component=izh0.id, size=size0)\n",
+    "net.info()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Define an external stimulus and add it to the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pg = nml_doc.add(\n",
+    "    \"PulseGenerator\",\n",
+    "    id=\"pulseGen_%i\" % 0, delay=\"0ms\", duration=\"1000ms\",\n",
+    "    amplitude=\"0.07 nA\"\n",
+    ")\n",
+    "exp_input = net.add(\"ExplicitInput\", target=\"%s[%i]\" % (pop0.id, 0), input=pg.id)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Write the NeuroML model to a file"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Written network file to: /home/vboxuser/Documents/compbiolibs/combine-notebooks/results/hello_world_neuroml.nml\n"
+     ]
+    }
+   ],
+   "source": [
+    "from combine_notebooks import RESULTS_DIR\n",
+    "\n",
+    "nml_file = str(RESULTS_DIR) + '/hello_world_neuroml.nml'\n",
+    "writers.NeuroMLWriter.write(nml_doc, nml_file)\n",
+    "print(\"Written network file to: \" + nml_file)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Validate the NeuroML model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Validating izhikevich2007_single_cell_network.nml against /home/asinha/.local/share/virtualenvs/neuroml-dev/lib/python3.10/site-packages/neuroml/nml/NeuroML_v2.3.xsd\n",
+      "It's valid!\n"
+     ]
+    }
+   ],
+   "source": [
+    "validate_neuroml2(nml_file)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Simulating the model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Create a simulation instance of the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "pyNeuroML >>> INFO - Loading NeuroML2 file: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/izhikevich2007_single_cell_network.nml\n"
+     ]
+    }
+   ],
+   "source": [
+    "simulation_id = \"example-single-izhikevich2007cell-sim\"\n",
+    "simulation = LEMSSimulation(sim_id=simulation_id,\n",
+    "                            duration=1000, dt=0.1, simulation_seed=123)\n",
+    "simulation.assign_simulation_target(net.id)\n",
+    "simulation.include_neuroml2_file(nml_file)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Define the output file to store simulation outputs\n",
+    "\n",
+    "Here, we record the neuron's membrane potential to the specified data file."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "simulation.create_output_file(\n",
+    "    \"output0\", \"%s.v.dat\" % simulation_id\n",
+    ")\n",
+    "simulation.add_column_to_output_file(\"output0\", 'IzhPop0[0]', 'IzhPop0[0]/v')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Save the simulation to a file"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "lems_simulation_file = simulation.save_to_file()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Run the simulation using the jNeuroML simulator"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "pyNeuroML >>> INFO - Loading LEMS file: LEMS_example-single-izhikevich2007cell-sim.xml and running with jNeuroML\n",
+      "pyNeuroML >>> INFO - Executing: (java -Xmx2G  -Djava.awt.headless=true -jar  \"/home/asinha/.local/share/virtualenvs/neuroml-dev/lib/python3.10/site-packages/pyneuroml/lib/jNeuroML-0.12.0-jar-with-dependencies.jar\"  \"LEMS_example-single-izhikevich2007cell-sim.xml\"  -nogui -I '') in directory: .\n",
+      "pyNeuroML >>> INFO - Command completed. Output: \n",
+      "  jNeuroML >>   jNeuroML v0.12.0\n",
+      "  jNeuroML >>  Loading: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example-single-izhikevich2007cell-sim.xml with jLEMS, NO GUI mode...\n",
+      "  jNeuroML >>  INFO Sep 15,2022 15:24  (INFO) Loading LEMS file from: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example-single-izhikevich2007cell-sim.xml\n",
+      "  jNeuroML >>  INFO Sep 15,2022 15:24  (INFO) Reading from: /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/LEMS_example-single-izhikevich2007cell-sim.xml\n",
+      "  jNeuroML >>  INFO Sep 15,2022 15:24  (INFO) Finished 10000 steps in 0.081 seconds (sim duration: 1000.0ms; dt: 0.1ms)\n",
+      "  jNeuroML >>  INFO Sep 15,2022 15:24  (INFO) Written to the file /home/asinha/Documents/02_Code/00_mine/NeuroML/documentation/source/Userdocs/NML2_examples/./example-single-izhikevich2007cell-sim.v.dat 204829\n",
+      "  jNeuroML >>  INFO Sep 15,2022 15:24  (INFO) Finished reading, building, running and displaying LEMS model\n",
+      "  jNeuroML >>  \n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pynml.run_lems_with_jneuroml(\n",
+    "    lems_simulation_file, max_memory=\"2G\", nogui=True, plot=False\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Plot the recorded data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "pyNeuroML >>> INFO - Generating plot: Membrane potential\n",
+      "/home/asinha/.local/share/virtualenvs/neuroml-dev/lib/python3.10/site-packages/pyneuroml/plot/Plot.py:186: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string \"o\" (-> marker='o'). The keyword argument will take precedence.\n",
+      "  plt.plot(\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "<AxesSubplot:xlabel='time (s)', ylabel='membrane potential (V)'>"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Load the data from the file and plot the graph for the membrane potential\n",
+    "# using the pynml generate_plot utility function.\n",
+    "data_array = np.loadtxt(\"%s.v.dat\" % simulation_id)\n",
+    "pynml.generate_plot(\n",
+    "    [data_array[:, 0]], [data_array[:, 1]],\n",
+    "    \"Membrane potential\", show_plot_already=True,\n",
+    "    xaxis=\"time (s)\", yaxis=\"membrane potential (V)\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "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.10.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/omex.ipynb b/notebooks/omex.ipynb
new file mode 100644
index 0000000..638dc7e
--- /dev/null
+++ b/notebooks/omex.ipynb
@@ -0,0 +1,195 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "2e806b7a",
+   "metadata": {},
+   "source": [
+    "Example for creating a COMBINE archive."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "5e7c2a84",
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "from pathlib import Path\n",
+    "\n",
+    "from pymetadata.console import console\n",
+    "from pymetadata.omex import EntryFormat, ManifestEntry, Omex"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "565b2c61",
+   "metadata": {},
+   "source": [
+    "Creating an empty archive and adding entry for SBML."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "b8796964",
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>   <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'.'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'http://identifiers.org/combine.specifications:omex'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)</span>,\n",
+       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'./manifest.xml'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'http://identifiers.org/combine.specifications:omex-manifest'</span>, \n",
+       "<span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)</span>,\n",
+       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'./sbml/hello_world_sbml.xml'</span>, \n",
+       "<span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'http://identifiers.org/combine.specifications:sbml.level-3.version-2'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)</span>,\n",
+       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'./cellml/hello_world_cellml.cellml'</span>, \n",
+       "<span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'http://identifiers.org/combine.specifications:cellml'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)</span>,\n",
+       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'./sbgn/hello_world_sbgn.sbgn'</span>, \n",
+       "<span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'http://identifiers.org/combine.specifications:sbgn'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)</span>,\n",
+       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'./sbgn/hello_world_sbgn.png'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'https://purl.org/NET/mediatypes/image/png'</span>, \n",
+       "<span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)</span>,\n",
+       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ManifestEntry</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">location</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'./sedml/hello_world_sedml.sedml'</span>, \n",
+       "<span style=\"color: #808000; text-decoration-color: #808000\">format</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'http://identifiers.org/combine.specifications:sed-ml'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">master</span>=<span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span><span style=\"font-weight: bold\">)]</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m[\u001b[0m   \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'.'\u001b[0m, \u001b[33mformat\u001b[0m=\u001b[32m'http://identifiers.org/combine.specifications:omex'\u001b[0m, \u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "    \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'./manifest.xml'\u001b[0m, \u001b[33mformat\u001b[0m=\u001b[32m'http://identifiers.org/combine.specifications:omex-manifest'\u001b[0m, \n",
+       "\u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "    \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'./sbml/hello_world_sbml.xml'\u001b[0m, \n",
+       "\u001b[33mformat\u001b[0m=\u001b[32m'http://identifiers.org/combine.specifications:sbml.level-3.version-2'\u001b[0m, \u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "    \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'./cellml/hello_world_cellml.cellml'\u001b[0m, \n",
+       "\u001b[33mformat\u001b[0m=\u001b[32m'http://identifiers.org/combine.specifications:cellml'\u001b[0m, \u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "    \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'./sbgn/hello_world_sbgn.sbgn'\u001b[0m, \n",
+       "\u001b[33mformat\u001b[0m=\u001b[32m'http://identifiers.org/combine.specifications:sbgn'\u001b[0m, \u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "    \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'./sbgn/hello_world_sbgn.png'\u001b[0m, \u001b[33mformat\u001b[0m=\u001b[32m'https://purl.org/NET/mediatypes/image/png'\u001b[0m, \n",
+       "\u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "    \u001b[1;35mManifestEntry\u001b[0m\u001b[1m(\u001b[0m\u001b[33mlocation\u001b[0m=\u001b[32m'./sedml/hello_world_sedml.sedml'\u001b[0m, \n",
+       "\u001b[33mformat\u001b[0m=\u001b[32m'http://identifiers.org/combine.specifications:sed-ml'\u001b[0m, \u001b[33mmaster\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #800000; text-decoration-color: #800000\">WARNING </span> Existing omex is overwritten:                                                                  <a href=\"file:///home/vboxuser/.local/lib/python3.10/site-packages/pymetadata/omex.py\" target=\"_blank\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">omex.py</span></a><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">:</span><a href=\"file:///home/vboxuser/.local/lib/python3.10/site-packages/pymetadata/omex.py#680\" target=\"_blank\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">680</span></a>\n",
+       "         <span style=\"color: #008000; text-decoration-color: #008000\">'/home/vboxuser/Documents/compbiolibs/combine-notebooks/results/combine_hello_world.omex'</span>      <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">           </span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[31mWARNING \u001b[0m Existing omex is overwritten:                                                                  \u001b]8;id=296905;file:///home/vboxuser/.local/lib/python3.10/site-packages/pymetadata/omex.py\u001b\\\u001b[2momex.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=280012;file:///home/vboxuser/.local/lib/python3.10/site-packages/pymetadata/omex.py#680\u001b\\\u001b[2m680\u001b[0m\u001b]8;;\u001b\\\n",
+       "         \u001b[32m'/home/vboxuser/Documents/compbiolibs/combine-notebooks/results/combine_hello_world.omex'\u001b[0m      \u001b[2m           \u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "def create_omex(omex_path: Path, results_dir: Path) -> None:\n",
+    "    \"\"\"Create OMEX archive of resources.\"\"\"\n",
+    "    omex = Omex()\n",
+    "    omex.add_entry(\n",
+    "        entry=ManifestEntry(\n",
+    "            location=\"./sbml/hello_world_sbml.xml\",\n",
+    "            format=EntryFormat.SBML_L3V2,\n",
+    "            master=False,\n",
+    "        ),\n",
+    "        entry_path=results_dir / \"hello_world_sbml.xml\",\n",
+    "    )\n",
+    "\n",
+    "    omex.add_entry(\n",
+    "        entry=ManifestEntry(\n",
+    "            location=\"./cellml/hello_world_cellml.cellml\",\n",
+    "            format=EntryFormat.CELLML,\n",
+    "            master=False,\n",
+    "        ),\n",
+    "        entry_path=results_dir / \"hello_world_cellml.cellml\",\n",
+    "    )\n",
+    "\n",
+    "    \"\"\"omex.add_entry(\n",
+    "        entry=ManifestEntry(\n",
+    "            location=\"./biopax/repressilator_biopax.owl\",\n",
+    "            format=EntryFormat.BIOPAX,\n",
+    "            master=False,\n",
+    "        ),\n",
+    "        entry_path=results_dir / \"repressilator_biopax.owl\",\n",
+    "    )\"\"\"\n",
+    "\n",
+    "    omex.add_entry(\n",
+    "        entry=ManifestEntry(\n",
+    "            location=\"./sbgn/hello_world_sbgn.sbgn\",\n",
+    "            format=EntryFormat.SBGN,\n",
+    "            master=False,\n",
+    "        ),\n",
+    "        entry_path=results_dir / \"hello_world_sbgn.sbgn\",\n",
+    "    )\n",
+    "    omex.add_entry(\n",
+    "        entry=ManifestEntry(\n",
+    "            location=\"./sbgn/hello_world_sbgn.png\",\n",
+    "            format=EntryFormat.PNG,\n",
+    "            master=False,\n",
+    "        ),\n",
+    "        entry_path=results_dir / \"hello_world_sbgn.png\",\n",
+    "    )\n",
+    "\n",
+    "    omex.add_entry(\n",
+    "        entry=ManifestEntry(\n",
+    "            location=\"./sedml/hello_world_sedml.sedml\",\n",
+    "            format=EntryFormat.SEDML,\n",
+    "            master=False,\n",
+    "        ),\n",
+    "        entry_path=results_dir / \"hello_world_sedml.sedml\"\n",
+    "        # FIXME: add the model relative and test\n",
+    "    )\n",
+    "\n",
+    "    console.print(omex)\n",
+    "    omex.to_omex(omex_path)\n",
+    "\n",
+    "\n",
+    "if __name__ == \"__main__\":\n",
+    "    from combine_notebooks import RESULTS_DIR\n",
+    "\n",
+    "    create_omex(omex_path=RESULTS_DIR / \"combine_hello_world.omex\", results_dir=RESULTS_DIR)\n",
+    "\n",
+    "        # <markdowncell>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0cc8164b",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.10.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/sbgn.ipynb b/notebooks/sbgn.ipynb
new file mode 100644
index 0000000..5976b51
--- /dev/null
+++ b/notebooks/sbgn.ipynb
@@ -0,0 +1,174 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pathlib import Path\n",
+    "import IPython\n",
+    "import libsbgnpy.libsbgn as libsbgn\n",
+    "from IPython.core.display import HTML\n",
+    "from IPython.display import Image\n",
+    "from libsbgnpy.libsbgnTypes import ArcClass, GlyphClass, Language, Orientation\n",
+    "from pygments import highlight\n",
+    "from pygments.formatters import HtmlFormatter\n",
+    "from pygments.lexers import PythonLexer\n",
+    "from combine_notebooks import RESULTS_DIR"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def pprint_xml(xml_str: str) -> None:\n",
+    "    \"\"\"Create highlighted xml.\"\"\"\n",
+    "    IPython.display.display(\n",
+    "        HTML(\n",
+    "            '<style type=\"text/css\">{}</style>{}'.format(\n",
+    "                HtmlFormatter().get_style_defs(\".highlight\"),\n",
+    "                highlight(xml_str, PythonLexer(), HtmlFormatter()),\n",
+    "            )\n",
+    "        )\n",
+    "    )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "SBGN rendered: /home/vboxuser/Documents/compbiolibs/combine-notebooks/results/hello_world_sbgn.png\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmwAAAGGCAYAAADGot1cAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAADFUSURBVHhe7d15kFTVvcBxNBaQqqhUqZFoqaRiFE1pMDEJCYQZyqTUKhdUyoD+IQLDsLiMigi44EOQRc1Ek5JULMWXysuwqGhFg1ERFQaIIq644L7ividmrfP4dfftuff27Z4+Z3pmfuf091P1q/cCqND3Hs63b9/u7mOMadwxlzMMwzAMwzA6R4JN/h8AAAAoRbABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABAAAoR7ABntm4caNZsmSJmTNnDsM4TWtrq1m7dm3hjALgA4IN8IBsskOHDjV9+vRhmJrOkCFDzOTJk83HH39cONsAaESwAYo9++yzhBrTIzNw4ECzevXqwpkHQBuCDVBq6dKlpn///pmbK8N018jVNgD6EGyAQnJlrVysDRgwwDQ0NJjLLrvMXHrppWXnkksuyZyLL744c2bPnp05s2bNKjszZ87MnIsuuihzZsyYkTkXXnhh2Zk+fXrmXHDBBZlz/vnnZ855551XcVpaWirOueeemznnnHNO2Tn77LMz56yzzsqcadOmZc7UqVPLzpQpUzJHwitrmpubzU9+8hOzxx57ZJ5fMvJkAYAuBBugzJdffpm7ryi9iR599NHmpZdeMv/5z3+K8+9//7s4//rXv4rzz3/+szj/+Mc/iiP/7vj8/e9/L87f/va34nzxxRfF+fzzz4vz2WefFefTTz8tzieffFIcuRcqPh999FFxPvzww+J88MEHxXn//feL89577xXn3XffLc4777xTnO3btyfm7bffLs5bb71VnDfffLM4b7zxRmJef/31xLz22muJefXVVxPzyiuvFOfll18ujhyTaF588cXivPDCC8XZtm1bcZ5//vniPPfcc4mRUI/mmWeeKc7WrVuL8/TTTxfnqaeeKs6TTz5ZnCeeeKI4jz/+eGIee+yx4tx7773mtNNOKznX5EmBPK4A9CDYAGXkDQbpDVSupv33v/8tG2suwWYbay7BZhtrLsGmMdZcgs021lyCLR5rW7ZsKc6vf/1r07dv38Q5N2rUqMIZCUADgg1QZvDgwYmNU66sSaxVCjbbWHMJNttYcwk221jTGmy2seYSbLaxVinYHn300dxLtfHzTkbOEwA6EGyAIhI56U1T4oOra1xdi8eaS7BVirVo0ve1ya8FoAPBBigiH2Ya3zAHDRrE1bUysaY12GxjzSXYbGOt2mBrbGxMnH/yAc0AdCDYAEXkE+jjG+aJJ57I1bUywaYx1lyCzTbWXIKtmljbvHmzGTduXOL8k/spAehAsAGKpN9w0NmbDWxjzSXYbGPNJdhsY01rsNnGmkuw2caaTbBNmjQpcf4RbIAeBBugSFawlYs1l2CzjTWXYLONNZdg0xhrLsFmG2suwVZtrBFsgG4EG6CITbDZxppLsNnGmkuw2caa1mCzjTWXYLONNYINCAfBBihSKdjiseYSbLax5hJstrHmEmwaY80l2GxjzSXYbGKNYAN0I9gARaoNNttYcwk221hzCTbbWNMabLax5hJstrHmEmxNTU2J849gA/Qg2ABFygVbPNZcgs021lyCzTbWXIJNY6y5BJttrLkEm22sEWyAbgQboEg1wWYbay7BZhtrLsFmG2tag8021lyCzTbWXILtkUceIdgAxQg2QJGsYIvHmkuw2caaS7DZxppLsGmMNZdgs401l2CzjTWCDdCPYAMU6SzYbGPNJdhsY80l2GxjTWuw2caaS7DZxppLsEmsEWyAbgQboEg62C699NIuBZttrLkEm22suQSbxlhzCTbbWHMJNttYI9gAPxBsgCKVgs021lyCzTbWXILNNta0BpttrLkEm22suQRbFGsEG6AbwQYoUstgs401l2CzjTWXYNMYay7BZhtrLsFmG2sE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WuEjPNIz7iarl0Jdgs021gg2wC8EG6BIVrDZxppLsNnGWjLY9H1naPqjPEpiLTYlV9cKE923lry6VvgKquil0ESs+XvvmsQawQboRrABitQi2GxjzSXYbGOtZ4Otwkd5pILNNtZcgs021lyCzTbWCDbAPwQboEilYKsm1lyCzTbWXIKt52Kt4/616KM8ysWaS7DZxppLsNnGmkuwZcWazPjxHW+ekCHYAD0INkCRrgabbay5BJttrPVssK0vvEO0wpsNHGPNJdhsY80l2GxjjWAD/ESwAYqUC7ZqYs0l2GxjzSXYei7W8iORFk25WHMJNttYcwk221hzCbZysdbe3k6wAYoRbIAiXQk221hzCTbbWNMabLax5hJstrHmEmy2sUawAf4i2ABFsoKtmlhzCTbbWHMJNo2x5hJstrHmEmy2seYSbJVijWADdCPYAEVcg8021lyCzTbWtAabbay5BJttrLkEm22sEWyA3wg2QJF0sM2ePZurazWMNZdgs401l2CzjTWXYOss1gg2QDeCDVDEJdhsY80l2GxjTWuw2caaS7DZxppLsNnGGsEG+I9gAxQpF2zlYs0l2GxjzSXYNMaaS7DZxppLsNnGmkuwVRNr69evJ9gAxQg2QBHbYLONNZdgs401rcFmG2suwWYbay7BZhtrBBsQBoINUCQr2MrFmkuw2caaS7BpjDWXYLONNZdgs401l2CrNtYINkA3gg1QxCbYbGPNJdhsY01rsNnGmkuw2caaS7DZxhrBBoSDYAMUqRRs8VhzCTbbWHMJNo2x5hJstrHmEmy2seYSbDaxRrABuhFsgCLVBpttrLkEm22saQ0221hzCTbbWHMJNttYcwm2M888M3H+EWyAHgQboEi5YIvHmkuw2caaS7BpjDWXYLONNZdgs401l2CzjTWCDdCNYAMUqSbYbGPNJdhsY01rsNnGmkuw2caaS7DZxppLsK1bt45gAxQj2ABFsoItHmsuwWYbay7BpjHWXILNNtZcgs021lyCzTbWCDZAP4INUKSzYLONNZdgs401rcFmG2suwWYbay7BZhtrLsEmsUawAboRbIAi6WCbNWtWl4LNNtZcgk1jrLkEm22suQSbbay5BJttrBFsgB8INkCRSsFmG2suwWYba1qDzTbWXILNNtZcgs021lyCLYo1gg3QjWADFKllsNnGmkuwaYw1l2Cz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",
+      "text/plain": [
+       "<IPython.core.display.Image object>"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {
+      "image/png": {
+       "width": 300
+      }
+     },
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# create empty sbgn\n",
+    "sbgn: libsbgn.sbgn = libsbgn.sbgn()\n",
+    "\n",
+    "# create map, set language and set in sbgn\n",
+    "map = libsbgn.map()\n",
+    "map.set_language(Language.PD)\n",
+    "sbgn.set_map(map)\n",
+    "\n",
+    "# create some glyphs\n",
+    "# glyphs with labels\n",
+    "g = libsbgn.glyph(class_=GlyphClass.SIMPLE_CHEMICAL, id=\"glyph0\")\n",
+    "g.set_label(libsbgn.label(text=\"S1\"))\n",
+    "g.set_bbox(libsbgn.bbox(y=\"105.0\", x=\"25.0\", h=\"60.0\", w=\"60.0\"))\n",
+    "map.add_glyph(g)\n",
+    "\n",
+    "g = libsbgn.glyph(class_=GlyphClass.MACROMOLECULE, id=\"glyph2\")\n",
+    "g.set_label(libsbgn.label(text=\"enzyme\"))\n",
+    "g.set_bbox(libsbgn.bbox(y=\"30.0\", x=\"115.0\", h=\"40.0\", w=\"80.0\"))\n",
+    "map.add_glyph(g)\n",
+    "\n",
+    "g = libsbgn.glyph(class_=GlyphClass.PROCESS, id=\"glyph3\")\n",
+    "g.set_bbox(libsbgn.bbox(y=\"123.0\", x=\"143.0\", h=\"24.0\", w=\"24.0\"))\n",
+    "g.add_port(libsbgn.port(y=\"135.0\", x=\"131.0\", id=\"glyph3.1\"))\n",
+    "g.add_port(libsbgn.port(y=\"135.0\", x=\"179.0\", id=\"glyph3.2\"))\n",
+    "map.add_glyph(g)\n",
+    "\n",
+    "g = libsbgn.glyph(class_=GlyphClass.SIMPLE_CHEMICAL, id=\"glyph1\")\n",
+    "g.set_label(libsbgn.label(text=\"P1\"))\n",
+    "g.set_bbox(libsbgn.bbox(y=\"105.0\", x=\"225.0\", h=\"60.0\", w=\"60.0\"))\n",
+    "map.add_glyph(g)\n",
+    "\n",
+    "# Add arcs linking the glyphs together\n",
+    "a = libsbgn.arc(\n",
+    "    class_=ArcClass.CONSUMPTION,\n",
+    "    target=\"glyph3.1\",\n",
+    "    source=\"glyph0\",\n",
+    "    id=\"arc0\",\n",
+    ")\n",
+    "a.set_start(libsbgn.startType(y=\"135.0\", x=\"85.0\"))\n",
+    "a.set_end(libsbgn.endType(y=\"135.0\", x=\"131.0\"))\n",
+    "map.add_arc(a)\n",
+    "\n",
+    "a = libsbgn.arc(\n",
+    "    class_=ArcClass.CATALYSIS,\n",
+    "    target=\"glyph3\",\n",
+    "    source=\"glyph2\",\n",
+    "    id=\"arc1\",\n",
+    ")\n",
+    "a.set_start(libsbgn.startType(y=\"70.0\", x=\"155.0\"))\n",
+    "a.set_end(libsbgn.endType(y=\"123.0\", x=\"155.0\"))\n",
+    "map.add_arc(a)\n",
+    "\n",
+    "a = libsbgn.arc(\n",
+    "    class_=ArcClass.PRODUCTION,\n",
+    "    target=\"glyph1\",\n",
+    "    source=\"glyph3.2\",\n",
+    "    id=\"arc2\",\n",
+    ")\n",
+    "a.set_start(libsbgn.startType(y=\"135.0\", x=\"179.0\"))\n",
+    "a.set_end(libsbgn.endType(y=\"135.0\", x=\"225.0\"))\n",
+    "map.add_arc(a)\n",
+    "\n",
+    "from combine_notebooks import RESULTS_DIR\n",
+    "\n",
+    "sbgn_path = str(RESULTS_DIR) + \"/hello_world_sbgn.sbgn\"\n",
+    "f_out = sbgn_path\n",
+    "sbgn.write_file(f_out)\n",
+    "\n",
+    "# render SBGN\n",
+    "from libsbgnpy import render\n",
+    "\n",
+    "f_png: str = str(RESULTS_DIR) + '/hello_world_sbgn.png'\n",
+    "render.render_sbgn(sbgn, image_file=f_png, file_format=\"png\")\n",
+    "Image(f_png, width=300)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.10.6"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/sbml.ipynb b/notebooks/sbml.ipynb
new file mode 100644
index 0000000..e620cb1
--- /dev/null
+++ b/notebooks/sbml.ipynb
@@ -0,0 +1,196 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "103d5650",
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/vboxuser/.local/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
+      "  from .autonotebook import tqdm as notebook_tqdm\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
+      "<!-- Created by COPASI version 4.39.272 (Source) on 2023-05-03 10:07 with libSBML version 5.19.4. -->\n",
+      "<sbml xmlns=\"http://www.sbml.org/sbml/level2/version4\" level=\"2\" version=\"4\">\n",
+      "  <model metaid=\"COPASI0\" id=\"New_Model\" name=\"New Model\">\n",
+      "    <annotation>\n",
+      "      <copasi:COPASI xmlns:copasi=\"http://www.copasi.org/static/sbml\">\n",
+      "        <rdf:RDF xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n",
+      "          <rdf:Description rdf:about=\"#COPASI0\">\n",
+      "            <dcterms:created>\n",
+      "              <rdf:Description>\n",
+      "                <dcterms:W3CDTF>2023-05-03T09:07:41Z</dcterms:W3CDTF>\n",
+      "              </rdf:Description>\n",
+      "            </dcterms:created>\n",
+      "          </rdf:Description>\n",
+      "        </rdf:RDF>\n",
+      "      </copasi:COPASI>\n",
+      "    </annotation>\n",
+      "    <listOfUnitDefinitions>\n",
+      "      <unitDefinition id=\"length\" name=\"length\">\n",
+      "        <listOfUnits>\n",
+      "          <unit kind=\"metre\" exponent=\"1\" scale=\"0\" multiplier=\"1\"/>\n",
+      "        </listOfUnits>\n",
+      "      </unitDefinition>\n",
+      "      <unitDefinition id=\"area\" name=\"area\">\n",
+      "        <listOfUnits>\n",
+      "          <unit kind=\"metre\" exponent=\"2\" scale=\"0\" multiplier=\"1\"/>\n",
+      "        </listOfUnits>\n",
+      "      </unitDefinition>\n",
+      "      <unitDefinition id=\"volume\" name=\"volume\">\n",
+      "        <listOfUnits>\n",
+      "          <unit kind=\"litre\" exponent=\"1\" scale=\"0\" multiplier=\"1\"/>\n",
+      "        </listOfUnits>\n",
+      "      </unitDefinition>\n",
+      "      <unitDefinition id=\"time\" name=\"time\">\n",
+      "        <listOfUnits>\n",
+      "          <unit kind=\"second\" exponent=\"1\" scale=\"0\" multiplier=\"1\"/>\n",
+      "        </listOfUnits>\n",
+      "      </unitDefinition>\n",
+      "      <unitDefinition id=\"substance\" name=\"substance\">\n",
+      "        <listOfUnits>\n",
+      "          <unit kind=\"mole\" exponent=\"1\" scale=\"0\" multiplier=\"1\"/>\n",
+      "        </listOfUnits>\n",
+      "      </unitDefinition>\n",
+      "    </listOfUnitDefinitions>\n",
+      "    <listOfCompartments>\n",
+      "      <compartment id=\"compartment\" name=\"compartment\" spatialDimensions=\"3\" size=\"1\" constant=\"true\"/>\n",
+      "    </listOfCompartments>\n",
+      "    <listOfSpecies>\n",
+      "      <species id=\"A\" name=\"A\" compartment=\"compartment\" initialConcentration=\"1\" boundaryCondition=\"false\" constant=\"false\"/>\n",
+      "    </listOfSpecies>\n",
+      "    <listOfReactions>\n",
+      "      <reaction id=\"r1\" name=\"r1\" reversible=\"false\">\n",
+      "        <listOfReactants>\n",
+      "          <speciesReference species=\"A\" stoichiometry=\"1\"/>\n",
+      "        </listOfReactants>\n",
+      "        <kineticLaw>\n",
+      "          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n",
+      "            <apply>\n",
+      "              <times/>\n",
+      "              <ci> compartment </ci>\n",
+      "              <ci> k1 </ci>\n",
+      "              <ci> A </ci>\n",
+      "            </apply>\n",
+      "          </math>\n",
+      "          <listOfParameters>\n",
+      "            <parameter id=\"k1\" name=\"k1\" value=\"0.1\"/>\n",
+      "          </listOfParameters>\n",
+      "        </kineticLaw>\n",
+      "      </reaction>\n",
+      "    </listOfReactions>\n",
+      "  </model>\n",
+      "</sbml>\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "<Axes: xlabel='Time'>"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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brdeeeUV1dXVaezYsZxjP5gxY4bOP//8TudU4u+zL23btk25ubk66aSTNH36dO3du1dScJzjoHuwnK8dPHhQbrdbWVlZnbZnZWVpy5YtFqUKfyUlJZJ01PPe8R66zuPxaObMmRo/frwGDx4sqe1cO51OJScnd9qXc911GzZs0NixY9XY2KiEhATNmzdPgwYN0tq1aznHPvTKK69o9erVWrFixRHv8ffZN8aMGaNnn31W/fv314EDB3TnnXfqtNNO08aNG4PiHId9+QDCyYwZM7Rx48ZOY7fwnf79+2vt2rWqqqrSP//5T1111VVatGiR1bHCSlFRkW655RZ99NFHiomJsTpO2DrvvPO8Hw8dOlRjxoxRz5499dprryk2NtbCZG3CftglPT1ddrv9iFm8paWlys7OtihV+Os4t5x337nxxhv1zjvvaOHCherevbt3e3Z2tpqbm1VZWdlpf8511zmdTvXp00cjRozQ3LlzVVBQoIceeohz7EOrVq1SWVmZTjnlFEVFRSkqKkqLFi3Sww8/rKioKGVlZXGu/SA5OVn9+vXT9u3bg+Lvc9iXD6fTqREjRmj+/PnebR6PR/Pnz9fYsWMtTBbe8vPzlZ2d3em8V1dXa9myZZz3LjJNUzfeeKPmzZunBQsWKD8/v9P7I0aMkMPh6HSuCwsLtXfvXs71CfJ4PGpqauIc+9CECRO0YcMGrV271vsaOXKkpk+f7v2Yc+17tbW12rFjh3JycoLj73NAprVa7JVXXjGjo6PNZ5991vzyyy/Nn//852ZycrJZUlJidbSQVlNTY65Zs8Zcs2aNKcl84IEHzDVr1ph79uwxTdM077nnHjM5Odl86623zPXr15sXXXSRmZ+fbzY0NFicPLRcf/31psvlMj/55BPzwIED3ld9fb13n+uuu87s0aOHuWDBAnPlypXm2LFjzbFjx1qYOvTcdttt5qJFi8xdu3aZ69evN2+77TbTMAzzww8/NE2Tc+xPX7/bxTQ5175w6623mp988om5a9cu8/PPPzcnTpxopqenm2VlZaZpWn+OI6J8mKZpPvLII2aPHj1Mp9Npjh492ly6dKnVkULewoULTUlHvK666irTNNtut7399tvNrKwsMzo62pwwYYJZWFhobegQdLRzLMl85plnvPs0NDSYN9xwg5mSkmLGxcWZF198sXngwAHrQoega6+91uzZs6fpdDrNjIwMc8KECd7iYZqcY3/6ZvngXJ+4adOmmTk5OabT6TS7detmTps2zdy+fbv3favPsWGaphmYaywAAAARMOcDAAAEF8oHAAAIKMoHAAAIKMoHAAAIKMoHAAAIKMoHAAAIKMoHAAAIKMoHAAAIKMoHAJ+6+uqrNXXqVKtjAAhiUVYHABA6DMP4zvfvuOMOPfTQQ2LhZADfhfIB4JgdOHDA+/Grr76qOXPmqLCw0LstISFBCQkJVkQDEEIYdgFwzLKzs70vl8slwzA6bUtISDhi2OXMM8/UTTfdpJkzZyolJUVZWVl68sknVVdXp2uuuUaJiYnq06eP3nvvvU7H2rhxo8477zwlJCQoKytLV155pQ4ePBjgnxiAP1A+APjdc889p/T0dC1fvlw33XSTrr/+ev3kJz/RuHHjtHr1ak2aNElXXnml6uvrJUmVlZU6++yzNXz4cK1cuVLvv/++SktLdemll1r8kwDwBcoHAL8rKCjQb3/7W/Xt21ezZ89WTEyM0tPT9bOf/Ux9+/bVnDlzVFFRofXr10uSHn30UQ0fPly///3vNWDAAA0fPlx/+9vftHDhQm3dutXinwbAiWLOBwC/Gzp0qPdju92utLQ0DRkyxLstKytLklRWViZJWrdunRYuXHjU+SM7duxQv379/JwYgD9RPgD4ncPh6PS5YRidtnXcRePxeCRJtbW1mjJliu69994jvldOTo4fkwIIBMoHgKBzyimn6PXXX1evXr0UFcU/U0C4Yc4HgKAzY8YMHTp0SJdffrlWrFihHTt26IMPPtA111wjt9ttdTwAJ4jyASDo5Obm6vPPP5fb7dakSZM0ZMgQzZw5U8nJybLZ+GcLCHWGyVKEAAAggPhfCAAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFCUDwAAEFD/H/z7ygi1TgUbAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# %% [markdown]\n",
+    "# Here we show how to create a basic SBML model using basiCO, and simulating it. We start as usual by importing basiCO.\n",
+    "\n",
+    "# %%\n",
+    "from basico import *\n",
+    "\n",
+    "# %% [markdown]\n",
+    "# Lets create a new model, passing along the name that we want to give it.\n",
+    "\n",
+    "# %%\n",
+    "new_model(name=\"New Model\") \n",
+    "\n",
+    "# %% [markdown]\n",
+    "# Now we add a basic reaction of a metabolite A degrading.  \n",
+    "\n",
+    "# %%\n",
+    "add_reaction('r1', 'A -> ')\n",
+    "\n",
+    "# %% [markdown]\n",
+    "# We export the model to an sbml format and print it.\n",
+    "\n",
+    "# %%\n",
+    "from combine_notebooks import RESULTS_DIR\n",
+    "\n",
+    "sbml_file = str(RESULTS_DIR) + '/hello_world_sbml.xml'\n",
+    "save_model(sbml_file, type='sbml')\n",
+    "xml = open(sbml_file).read()\n",
+    "print(xml)\n",
+    "\n",
+    "# %% [markdown]\n",
+    "# To change the initial concentration, we use set_species, and specify which property we want to change.\n",
+    "\n",
+    "# %%\n",
+    "set_species('A', initial_concentration=10)\n",
+    "get_species().initial_concentration\n",
+    "\n",
+    "# %%\n",
+    "result = run_time_course(duration=50)\n",
+    "result.plot()\n",
+    "\n",
+    "# %%\n",
+    "\n",
+    "        # <markdowncell>\n",
+    "        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "07bfe041",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.10.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/sedml.ipynb b/notebooks/sedml.ipynb
new file mode 100644
index 0000000..8d4c0eb
--- /dev/null
+++ b/notebooks/sedml.ipynb
@@ -0,0 +1,304 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pathlib import Path\n",
+    "import libsedml"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Declaring the SED-ML model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    " # create the document\n",
+    "doc = libsedml.SedDocument(1, 4)\n",
+    "# create a first model referencing an sbml file\n",
+    "model = doc.createModel()\n",
+    "model.setId(\"model1\")\n",
+    "model.setSource(\"model1.xml\")\n",
+    "model.setLanguage(\"urn:sedml:language:sbml\") "
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Simulators"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# create simulation\n",
+    "tc = doc.createUniformTimeCourse()\n",
+    "tc.setId(\"sim1\")\n",
+    "tc.setInitialTime(0.0)\n",
+    "tc.setOutputStartTime(0.0)\n",
+    "tc.setOutputEndTime(10.0)\n",
+    "tc.setNumberOfSteps(100)\n",
+    "# need to set the correct KISAO Term\n",
+    "alg = tc.createAlgorithm()\n",
+    "alg.setName(\"Deterministic (LSODA)\")\n",
+    "alg.setKisaoID(\"KISAO:0000560\")\n",
+    "# add algorithm parameters\n",
+    "alg_par1 = alg.createAlgorithmParameter()\n",
+    "alg_par1.setName(\"Relative Tolerance\")\n",
+    "alg_par1.setKisaoID(\"KISAO:0000209\")\n",
+    "alg_par1.setValue(\"1e-06\")\n",
+    "alg_par2 = alg.createAlgorithmParameter()\n",
+    "alg_par2.setName(\"Absolute Tolerance\")\n",
+    "alg_par2.setKisaoID(\"KISAO:0000211\")\n",
+    "alg_par2.setValue(\"1e-12\")\n",
+    "alg_par3 = alg.createAlgorithmParameter()\n",
+    "alg_par3.setName(\"Integrate Reduced Model\")\n",
+    "alg_par3.setKisaoID(\"KISAO:0000216\")\n",
+    "alg_par3.setValue(\"0\")\n",
+    "alg_par4 = alg.createAlgorithmParameter()\n",
+    "alg_par4.setName(\"Max Internal Steps\")\n",
+    "alg_par4.setKisaoID(\"KISAO:0000415\")\n",
+    "alg_par4.setValue(\"100000\")\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Task"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# create a task that uses the simulation and the model above\n",
+    "task = doc.createTask()\n",
+    "task.setId(\"task1\")\n",
+    "task.setModelReference(\"model1\")\n",
+    "task.setSimulationReference(\"sim1\")\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Data generators"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# add a DataGenerator to hold the output for time\n",
+    "dg = doc.createDataGenerator()\n",
+    "dg.setId(\"_1_task1\")\n",
+    "dg.setName(\"Time\")\n",
+    "var = dg.createVariable()\n",
+    "var.setId(\"p1__1_task1\")\n",
+    "var.setName(\"Time\")\n",
+    "var.setTaskReference(\"task1\")\n",
+    "var.setSymbol(\"urn:sedml:symbol:time\")\n",
+    "var.setTerm(\"KISAO:0000832\")\n",
+    "dg.setMath(libsedml.parseFormula(\"p1__1_task1\"))\n",
+    "\n",
+    "dg = doc.createDataGenerator()\n",
+    "dg.setId(\"A_1_task1\")\n",
+    "dg.setName(\"[A]\")\n",
+    "var = dg.createVariable()\n",
+    "var.setId(\"p1_A_1_task1\")\n",
+    "var.setName(\"[A]\")\n",
+    "var.setTarget(\"/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id=&apos;A&apos;]\")\n",
+    "var.setTaskReference(\"task1\")\n",
+    "var.setTerm(\"KISAO:0000838\")\n",
+    "dg.setMath(libsedml.parseFormula(\"p1_A_1_task1\"))\n",
+    "\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Outputs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# add a 2d plot\n",
+    "plot = doc.createPlot2D()\n",
+    "plot.setId(\"plot_1_task1\")\n",
+    "plot.setName(\"Concentrations, Volumes, and Global Quantity Values\")\n",
+    "curve = plot.createCurve()\n",
+    "curve.setId(\"p1_curve_1_task1\")\n",
+    "curve.setName(\"[A]\")\n",
+    "curve.setLogX(False)\n",
+    "curve.setLogY(False)\n",
+    "curve.setStyle(\"style1\")\n",
+    "curve.setXDataReference(\"_1_task1\")\n",
+    "curve.setYDataReference(\"A_1_task1\")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Styles"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "style : libsedml.SedStyle = doc.createStyle()\n",
+    "style.setId(\"style1\")\n",
+    "line = style.createLineStyle()\n",
+    "line.setType(\"solid\")\n",
+    "line.setThickness(1.2)\n",
+    "marker = style.createMarkerStyle()\n",
+    "marker.setType(\"none\")\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from combine_notebooks import RESULTS_DIR\n",
+    "\n",
+    "sedml_file = str(RESULTS_DIR) + '/hello_world_sedml.sedml'\n",
+    "\n",
+    "libsedml.writeSedML(doc, sedml_file)\n"
+   ]
+  }
+ ],
+ "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.10.6"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/results/combine_hello_world.omex b/results/combine_hello_world.omex
new file mode 100644
index 0000000..04297ae
Binary files /dev/null and b/results/combine_hello_world.omex differ
diff --git a/results/hello_world_cellml.cellml b/results/hello_world_cellml.cellml
new file mode 100644
index 0000000..2aa14cb
--- /dev/null
+++ b/results/hello_world_cellml.cellml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<model xmlns="http://www.cellml.org/cellml/2.0#" name="GateModel">
+  <units name="ms">
+    <unit prefix="milli" units="second"/>
+  </units>
+  <units name="per_ms">
+    <unit exponent="-1" prefix="milli" units="second"/>
+  </units>
+  <units name="ms">
+    <unit prefix="milli" units="second"/>
+  </units>
+  <units name="per_ms">
+    <unit exponent="-1" prefix="milli" units="second"/>
+  </units>
+  <component name="gate">
+    <variable name="t" units="ms" interface="public_and_private"/>
+    <variable name="X" units="dimensionless" interface="public_and_private"/>
+  </component>
+  <component name="gateEquations">
+    <variable name="t" units="ms" interface="public_and_private"/>
+    <variable name="alpha_X" units="per_ms" interface="public"/>
+    <variable name="beta_X" units="per_ms" interface="public"/>
+    <variable name="X" units="dimensionless" interface="public_and_private"/>
+    <math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:cellml="http://www.cellml.org/cellml/2.0#">
+      <apply>
+        <eq/>
+        <apply>
+          <diff/>
+          <bvar>
+            <ci>t</ci>
+          </bvar>
+          <ci>X</ci>
+        </apply>
+        <apply>
+          <minus/>
+          <apply>
+            <times/>
+            <ci>alpha_X</ci>
+            <apply>
+              <minus/>
+              <cn cellml:units="dimensionless">1</cn>
+              <ci>X</ci>
+            </apply>
+          </apply>
+          <apply>
+            <times/>
+            <ci>beta_X</ci>
+            <ci>X</ci>
+          </apply>
+        </apply>
+      </apply>
+    </math>
+  </component>
+  <component name="gateParameters">
+    <variable name="X" units="dimensionless" initial_value="0" interface="public"/>
+    <variable name="alpha" units="per_ms" initial_value="0.1" interface="public"/>
+    <variable name="beta" units="per_ms" initial_value="0.5" interface="public"/>
+  </component>
+  <component name="gateParameters">
+    <variable name="X" units="dimensionless" initial_value="0" interface="public"/>
+    <variable name="alpha" units="per_ms" initial_value="0.1" interface="public"/>
+    <variable name="beta" units="per_ms" initial_value="0.5" interface="public"/>
+  </component>
+  <component name="gateParameters">
+    <variable name="X" units="dimensionless" initial_value="0" interface="public"/>
+    <variable name="alpha" units="per_ms" initial_value="0.1" interface="public"/>
+    <variable name="beta" units="per_ms" initial_value="0.5" interface="public"/>
+  </component>
+  <connection component_1="gate" component_2="gateEquations">
+    <map_variables variable_1="t" variable_2="t"/>
+    <map_variables variable_1="X" variable_2="X"/>
+  </connection>
+  <connection component_1="gateEquations" component_2="gateParameters">
+    <map_variables variable_1="alpha_X" variable_2="alpha"/>
+    <map_variables variable_1="beta_X" variable_2="beta"/>
+    <map_variables variable_1="X" variable_2="X"/>
+  </connection>
+  <connection component_1="gateEquations" component_2="gateParameters">
+    <map_variables variable_1="alpha_X" variable_2="alpha"/>
+    <map_variables variable_1="beta_X" variable_2="beta"/>
+    <map_variables variable_1="X" variable_2="X"/>
+  </connection>
+  <connection component_1="gateEquations" component_2="gateParameters">
+    <map_variables variable_1="alpha_X" variable_2="alpha"/>
+    <map_variables variable_1="beta_X" variable_2="beta"/>
+    <map_variables variable_1="X" variable_2="X"/>
+  </connection>
+  <encapsulation>
+    <component_ref component="gate">
+      <component_ref component="gateEquations"/>
+      <component_ref component="gateParameters"/>
+      <component_ref component="gateParameters"/>
+      <component_ref component="gateParameters"/>
+    </component_ref>
+  </encapsulation>
+</model>
diff --git a/results/hello_world_neuroml.nml b/results/hello_world_neuroml.nml
new file mode 100644
index 0000000..2af62e1
--- /dev/null
+++ b/results/hello_world_neuroml.nml
@@ -0,0 +1,8 @@
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="IzhSingleNeuron">
+    <izhikevich2007Cell id="izh2007RS0" C="100pF" v0="-60mV" k="0.7nS_per_mV" vr="-60mV" vt="-40mV" vpeak="35mV" a="0.03per_ms" b="-2nS" c="-50.0mV" d="100pA"/>
+    <pulseGenerator id="pulseGen_0" delay="0ms" duration="1000ms" amplitude="0.07 nA"/>
+    <network id="IzNet">
+        <population id="IzhPop0" component="izh2007RS0" size="1"/>
+        <explicitInput target="IzhPop0[0]" input="pulseGen_0"/>
+    </network>
+</neuroml>
diff --git a/results/hello_world_sbgn.png b/results/hello_world_sbgn.png
new file mode 100644
index 0000000..8d2185c
Binary files /dev/null and b/results/hello_world_sbgn.png differ
diff --git a/results/hello_world_sbgn.sbgn b/results/hello_world_sbgn.sbgn
new file mode 100644
index 0000000..8f1d644
--- /dev/null
+++ b/results/hello_world_sbgn.sbgn
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sbgn xmlns="http://sbgn.org/libsbgn/0.2">
+    <map language="process description">
+        <glyph class="simple chemical" id="glyph0">
+            <label text="S1"/>
+            <bbox w="60." h="60." x="25." y="105."/>
+        </glyph>
+        <glyph class="macromolecule" id="glyph2">
+            <label text="enzyme"/>
+            <bbox w="80." h="40." x="115." y="30."/>
+        </glyph>
+        <glyph class="process" id="glyph3">
+            <bbox w="24." h="24." x="143." y="123."/>
+            <port id="glyph3.1" x="131." y="135."/>
+            <port id="glyph3.2" x="179." y="135."/>
+        </glyph>
+        <glyph class="simple chemical" id="glyph1">
+            <label text="P1"/>
+            <bbox w="60." h="60." x="225." y="105."/>
+        </glyph>
+        <arc class="consumption" id="arc0" source="glyph0" target="glyph3.1">
+            <start x="85." y="135."/>
+            <end x="131." y="135."/>
+        </arc>
+        <arc class="catalysis" id="arc1" source="glyph2" target="glyph3">
+            <start x="155." y="70."/>
+            <end x="155." y="123."/>
+        </arc>
+        <arc class="production" id="arc2" source="glyph3.2" target="glyph1">
+            <start x="179." y="135."/>
+            <end x="225." y="135."/>
+        </arc>
+    </map>
+</sbgn>
diff --git a/results/hello_world_sbml.xml b/results/hello_world_sbml.xml
new file mode 100644
index 0000000..b49284f
--- /dev/null
+++ b/results/hello_world_sbml.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Created by COPASI version 4.39.272 (Source) on 2023-05-03 10:07 with libSBML version 5.19.4. -->
+<sbml xmlns="http://www.sbml.org/sbml/level2/version4" level="2" version="4">
+  <model metaid="COPASI0" id="New_Model" name="New Model">
+    <annotation>
+      <copasi:COPASI xmlns:copasi="http://www.copasi.org/static/sbml">
+        <rdf:RDF xmlns:dcterms="http://purl.org/dc/terms/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+          <rdf:Description rdf:about="#COPASI0">
+            <dcterms:created>
+              <rdf:Description>
+                <dcterms:W3CDTF>2023-05-03T09:07:41Z</dcterms:W3CDTF>
+              </rdf:Description>
+            </dcterms:created>
+          </rdf:Description>
+        </rdf:RDF>
+      </copasi:COPASI>
+    </annotation>
+    <listOfUnitDefinitions>
+      <unitDefinition id="length" name="length">
+        <listOfUnits>
+          <unit kind="metre" exponent="1" scale="0" multiplier="1"/>
+        </listOfUnits>
+      </unitDefinition>
+      <unitDefinition id="area" name="area">
+        <listOfUnits>
+          <unit kind="metre" exponent="2" scale="0" multiplier="1"/>
+        </listOfUnits>
+      </unitDefinition>
+      <unitDefinition id="volume" name="volume">
+        <listOfUnits>
+          <unit kind="litre" exponent="1" scale="0" multiplier="1"/>
+        </listOfUnits>
+      </unitDefinition>
+      <unitDefinition id="time" name="time">
+        <listOfUnits>
+          <unit kind="second" exponent="1" scale="0" multiplier="1"/>
+        </listOfUnits>
+      </unitDefinition>
+      <unitDefinition id="substance" name="substance">
+        <listOfUnits>
+          <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
+        </listOfUnits>
+      </unitDefinition>
+    </listOfUnitDefinitions>
+    <listOfCompartments>
+      <compartment id="compartment" name="compartment" spatialDimensions="3" size="1" constant="true"/>
+    </listOfCompartments>
+    <listOfSpecies>
+      <species id="A" name="A" compartment="compartment" initialConcentration="1" boundaryCondition="false" constant="false"/>
+    </listOfSpecies>
+    <listOfReactions>
+      <reaction id="r1" name="r1" reversible="false">
+        <listOfReactants>
+          <speciesReference species="A" stoichiometry="1"/>
+        </listOfReactants>
+        <kineticLaw>
+          <math xmlns="http://www.w3.org/1998/Math/MathML">
+            <apply>
+              <times/>
+              <ci> compartment </ci>
+              <ci> k1 </ci>
+              <ci> A </ci>
+            </apply>
+          </math>
+          <listOfParameters>
+            <parameter id="k1" name="k1" value="0.1"/>
+          </listOfParameters>
+        </kineticLaw>
+      </reaction>
+    </listOfReactions>
+  </model>
+</sbml>
diff --git a/results/hello_world_sedml.sedml b/results/hello_world_sedml.sedml
new file mode 100644
index 0000000..8cbbd70
--- /dev/null
+++ b/results/hello_world_sedml.sedml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sedML xmlns="http://sed-ml.org/sed-ml/level1/version4" level="1" version="4">
+  <listOfModels>
+    <model id="model1" language="urn:sedml:language:sbml" source="model1.xml"/>
+  </listOfModels>
+  <listOfSimulations>
+    <uniformTimeCourse id="sim1" initialTime="0" outputStartTime="0" outputEndTime="10" numberOfSteps="100">
+      <algorithm name="Deterministic (LSODA)" kisaoID="KISAO:0000560">
+        <listOfAlgorithmParameters>
+          <algorithmParameter name="Relative Tolerance" kisaoID="KISAO:0000209" value="1e-06"/>
+          <algorithmParameter name="Absolute Tolerance" kisaoID="KISAO:0000211" value="1e-12"/>
+          <algorithmParameter name="Integrate Reduced Model" kisaoID="KISAO:0000216" value="0"/>
+          <algorithmParameter name="Max Internal Steps" kisaoID="KISAO:0000415" value="100000"/>
+        </listOfAlgorithmParameters>
+      </algorithm>
+    </uniformTimeCourse>
+  </listOfSimulations>
+  <listOfTasks>
+    <task id="task1" modelReference="model1" simulationReference="sim1"/>
+  </listOfTasks>
+  <listOfDataGenerators>
+    <dataGenerator id="_1_task1" name="Time">
+      <math xmlns="http://www.w3.org/1998/Math/MathML">
+        <ci> p1__1_task1 </ci>
+      </math>
+      <listOfVariables>
+        <variable id="p1__1_task1" name="Time" symbol="urn:sedml:symbol:time" taskReference="task1" term="KISAO:0000832"/>
+      </listOfVariables>
+    </dataGenerator>
+    <dataGenerator id="A_1_task1" name="[A]">
+      <math xmlns="http://www.w3.org/1998/Math/MathML">
+        <ci> p1_A_1_task1 </ci>
+      </math>
+      <listOfVariables>
+        <variable id="p1_A_1_task1" name="[A]" target="/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id=&apos;A&apos;]" taskReference="task1" term="KISAO:0000838"/>
+      </listOfVariables>
+    </dataGenerator>
+  </listOfDataGenerators>
+  <listOfOutputs>
+    <plot2D id="plot_1_task1" name="Concentrations, Volumes, and Global Quantity Values">
+      <listOfCurves>
+        <curve id="p1_curve_1_task1" name="[A]" logX="false" style="style1" xDataReference="_1_task1" logY="false" yDataReference="A_1_task1"/>
+      </listOfCurves>
+    </plot2D>
+  </listOfOutputs>
+  <listOfStyles>
+    <style id="style1">
+      <line type="solid" thickness="1.2"/>
+      <marker type="none"/>
+    </style>
+  </listOfStyles>
+</sedML>
diff --git a/setup.cfg b/setup.cfg
index b4bd485..a12f617 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -61,6 +61,9 @@ install_requires =
 	pybiopax>=0.1.2
 	ipython>=8.4.0
 	nbformat>=5.4.0
+	tellurium>=2.2.5.2
+	copasi-basico>=0.44
+	numpy>=1.24.3
 tests_require = 
 	tox>=3.24.5
 	pytest>=7.0.1
diff --git a/src/combine_notebooks/__init__.py b/src/combine_notebooks/__init__.py
index ce76b32..36ef80d 100644
--- a/src/combine_notebooks/__init__.py
+++ b/src/combine_notebooks/__init__.py
@@ -6,4 +6,6 @@
 BASE_DIR: Path = Path(__file__).parent.parent.parent
 RESULTS_DIR: Path = BASE_DIR / "results"
 NOTEBOOK_DIR: Path = BASE_DIR / "notebooks"
-EXAMPLE_DIR: Path = Path(__file__).parent / "examples"
+HELLO_WORLD_DIR: Path = Path(__file__).parent / "examples/hello_world"
+REPRESSILATOR_DIR: Path = Path(__file__).parent / "examples/repressilator"
+
diff --git a/src/combine_notebooks/combine_files.py b/src/combine_notebooks/combine_files.py
index bf3f58f..1a9b751 100644
--- a/src/combine_notebooks/combine_files.py
+++ b/src/combine_notebooks/combine_files.py
@@ -1,20 +1,28 @@
 """Runs all the example scripts and generates all COMBINE files."""
 from pathlib import Path
 
-from combine_notebooks.examples.example_biopax import create_repressilator as biopax
-from combine_notebooks.examples.example_cellml import create_repressilator as cellml
-from combine_notebooks.examples.example_omex import create_omex
-from combine_notebooks.examples.example_sbgn import create_repressilator as sbgn
-from combine_notebooks.examples.example_sbml_antimony import (
+from combine_notebooks.examples.repressilator.example_biopax import (
+    create_repressilator as biopax,
+)
+from combine_notebooks.examples.repressilator.example_cellml import (
+    create_repressilator as cellml,
+)
+from combine_notebooks.examples.repressilator.example_omex import create_omex
+from combine_notebooks.examples.repressilator.example_sbgn import (
+    create_repressilator as sbgn,
+)
+from combine_notebooks.examples.repressilator.example_sbml_antimony import (
     create_repressilator as sbml_antimony,
 )
-from combine_notebooks.examples.example_sbml_libsbml import (
+from combine_notebooks.examples.repressilator.example_sbml_libsbml import (
     create_repressilator as sbml_libsbml,
 )
-from combine_notebooks.examples.example_sbml_sbmlutils import (
+from combine_notebooks.examples.repressilator.example_sbml_sbmlutils import (
     create_repressilator as sbml_sbmlutils,
 )
-from combine_notebooks.examples.example_sedml import create_repressilator as sedml
+from combine_notebooks.examples.repressilator.example_sedml import (
+    create_repressilator as sedml,
+)
 
 
 def create_combine_files(output_dir: Path) -> None:
diff --git a/src/combine_notebooks/convert_notebooks.py b/src/combine_notebooks/convert_notebooks.py
index 3d317fe..ea4b5e4 100644
--- a/src/combine_notebooks/convert_notebooks.py
+++ b/src/combine_notebooks/convert_notebooks.py
@@ -2,16 +2,22 @@
 
 from pathlib import Path
 from typing import List
+from os.path import exists
 
 from nbformat import v3, v4
+import json
 
+def read_ipynb(notebook_path):
+    with open(notebook_path, 'r', encoding='utf-8') as f:
+        return json.load(f)
 
-def create_notebooks(input_dir: Path, output_dir: Path) -> List[Path]:
+
+def create_notebooks(hello_world_dir: Path, repressilator_dir: Path, output_dir: Path) -> List[Path]:
     """Create notebooks for all COMBINE examples.
 
     Returns list of notebook paths.
     """
-    module_paths = input_dir.glob("**/*.py")
+    module_paths = repressilator_dir.glob("**/*.py")
     notebook_paths: List[Path] = []
     for module_path in module_paths:
         if "__init__" in str(module_path):
@@ -21,8 +27,14 @@ def create_notebooks(input_dir: Path, output_dir: Path) -> List[Path]:
         if "example_sbol" in str(module_path):
             continue
 
+        hello_world_path = str(hello_world_dir) + "/" + module_path.name
+        text = ""
+        if exists(hello_world_path):  
+            with open(hello_world_path) as f_module:
+                text += f_module.read()
+
         with open(module_path) as f_module:
-            text = f_module.read()
+            text += f_module.read()
 
         # add empty markdowncell to ensure last cell is written
         text += """
@@ -43,7 +55,7 @@ def create_notebooks(input_dir: Path, output_dir: Path) -> List[Path]:
 
 
 if __name__ == "__main__":
-    from combine_notebooks import EXAMPLE_DIR, NOTEBOOK_DIR
+    from combine_notebooks import HELLO_WORLD_DIR, REPRESSILATOR_DIR, NOTEBOOK_DIR
 
-    notebook_paths = create_notebooks(input_dir=EXAMPLE_DIR, output_dir=NOTEBOOK_DIR)
+    notebook_paths = create_notebooks(hello_world_dir=HELLO_WORLD_DIR, repressilator_dir=REPRESSILATOR_DIR, output_dir=NOTEBOOK_DIR)
     print(notebook_paths)
diff --git a/src/combine_notebooks/examples/__init__.py b/src/combine_notebooks/examples/__init__.py
index fdd5d14..2759e7c 100644
--- a/src/combine_notebooks/examples/__init__.py
+++ b/src/combine_notebooks/examples/__init__.py
@@ -1,1 +1,1 @@
-"""COMBINE example notebooks."""
+"""COMBINE examples."""
diff --git a/src/combine_notebooks/examples/hello_world/__init__.py b/src/combine_notebooks/examples/hello_world/__init__.py
new file mode 100644
index 0000000..96648fe
--- /dev/null
+++ b/src/combine_notebooks/examples/hello_world/__init__.py
@@ -0,0 +1,1 @@
+"""COMBINE basic helloww world examples for each standard."""
diff --git a/src/combine_notebooks/examples/hello_world/cellml.py b/src/combine_notebooks/examples/hello_world/cellml.py
new file mode 100644
index 0000000..decdd8a
--- /dev/null
+++ b/src/combine_notebooks/examples/hello_world/cellml.py
@@ -0,0 +1,280 @@
+# ---
+# jupyter:
+#   jupytext:
+#     text_representation:
+#       extension: .py
+#       format_name: percent
+#       format_version: '1.3'
+#       jupytext_version: 1.14.5
+#   kernelspec:
+#     display_name: Python 3
+#     language: python
+#     name: python3
+# ---
+
+# %% [markdown]
+# https://libcellml.org/documentation/v0.4.0/user/tutorials/hh_tutorial1/index
+
+# %%
+from libcellml import Analyser, Component, Model, Printer, Units, Validator, Variable, cellmlElementTypeAsString
+from utilities import print_issues, print_model, get_issue_level_from_enum
+
+# %% [markdown]
+# Setup the model
+
+# %%
+#  Setup useful things.
+math_header = '<math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:cellml="http://www.cellml.org/cellml/2.0#">\n'
+math_footer = '</math>'
+
+# The first step is to create a Model item which will later contain the component and 
+# the units it needs.  
+model = Model()
+
+# Each CellML element must have a name, which is set using the setName() function.
+model.setName('GateModel')
+
+# We'll create a wrapper component whose only job is to encapsulate the other components.
+# This makes is a lot easier for this model to be reused, as the connections between
+# components internal to this one won't need to be re-established.
+# Note that the constructor for all named CellML entities is overloaded, so 
+# you can pass it the name string at the time of creation.
+# Create a component named 'gate'.
+gate = Component('gate')
+
+# Finally we need to add the component to the model.  This sets it at the top-level of 
+# the components' encapsulation hierarchy.  All other components need to be added 
+# to this component, rather than the model.
+# Add the component to the model using the Model::addComponent() function.
+model.addComponent(gate)
+
+# Print the model to the terminal using the print_model helper function and 
+# check it is what you'd expect.
+print_model(model)
+
+
+# %% [markdown]
+# Create the gateEquations component
+
+# %%
+
+# Create a gateEquations component and name it 'gateEquations'.
+gateEquations = Component('gateEquations')
+
+# Add the new gateEquations component to the gate component.
+gate.addComponent(gateEquations)
+
+# Add the mathematics to the gateEquations component.
+equation = \
+    '  <apply><eq/>\n'\
+    '    <apply><diff/>\n'\
+    '      <bvar><ci>t</ci></bvar>\n'\
+    '      <ci>X</ci>\n'\
+    '    </apply>\n'\
+    '    <apply><minus/>\n'\
+    '      <apply><times/>\n'\
+    '        <ci>alpha_X</ci>\n'\
+    '        <apply><minus/>\n'\
+    '          <cn cellml:units="dimensionless">1</cn>\n'\
+    '          <ci>X</ci>\n'\
+    '        </apply>\n'\
+    '      </apply>\n'\
+    '      <apply><times/>\n'\
+    '        <ci>beta_X</ci>\n'\
+    '        <ci>X</ci>\n'\
+    '      </apply>\n'\
+    '    </apply>\n'\
+    '  </apply>\n'
+
+gateEquations.setMath(math_header)
+gateEquations.appendMath(equation)
+gateEquations.appendMath(math_footer)
+
+#      Print the model to the terminal using the print_model helper function and 
+#      check it is what you'd expect.  Include the second argument as True so that 
+#      the maths is included.
+print_model(model, True)
+
+#  Once the mathematics has been added to the component, and the component to the 
+#  model, we can make use of the diagnostic messages within the Validator class
+#  to tell us what else needs to be done.  
+
+# %% [markdown]
+# Validate the model
+
+# %%
+# Create a Validator instance, and pass it your model for processing using the 
+# validateModel function.  
+validator = Validator()
+validator.validateModel(model)
+print_issues(validator)
+
+
+# %% [markdown]
+# Add the variables
+
+# %%
+# Create items for the missing variables and add them to the gateEquations component.
+# You will need to be sure to give them names which match exactly those reported by the
+# validator, or are present in the MathML string.  
+gateEquations.addVariable(Variable('t'))
+gateEquations.addVariable(Variable('alpha_X'))
+gateEquations.addVariable(Variable('beta_X'))
+gateEquations.addVariable(Variable('X'))
+
+# Validate again, and expect errors relating to missing units.
+# Note that you can use the helper function print_issues(validator) to print your
+# issues to the screen instead of repeating the code from 3.b.
+validator.validateModel(model)
+print_issues(validator)
+
+# %% [markdown]
+# Add the units
+
+# %%
+#  The validator has reported that the four variables are missing units attributes.  
+#  In this example none of the units exist yet, so we need to create all of them. 
+#  The variables' units should be:
+#      - t, time has units of *milliseconds*
+#      - X, gate status has units of *dimensionless*
+#      - alpha_X and beta_X, rates, have units of *per millisecond*.
+
+# Create the units which will be needed by your variables and add them to the model.
+ms = Units('ms')
+per_ms = Units('per_ms')
+
+# Add Unit items to the units you created to define them.
+ms.addUnit('second', 'milli')
+per_ms.addUnit('second', 'milli', -1)
+
+# Add the Units to the model (not the component) so that other components can make 
+# use of them too.
+model.addUnits(ms)
+model.addUnits(per_ms)
+
+# Use the setUnits function to associate them with the appropriate variables.  
+gateEquations.variable('t').setUnits(ms)
+gateEquations.variable('alpha_X').setUnits(per_ms)
+gateEquations.variable('beta_X').setUnits(per_ms)
+gateEquations.variable('X').setUnits('dimensionless')
+
+# Validate again, and expect no errors.
+validator.validateModel(model)
+print_issues(validator)
+
+# Print the model to the terminal and include the optional second argument of true
+# to include the MathML.
+print_model(model, True)
+
+# %% [markdown]
+# Analyse the model
+
+# %%
+# Create an Analyser item and submit the model for processing. 
+analyser = Analyser()
+analyser.analyseModel(model)
+
+# Just like the Validator class, the Analyser class keeps track of issues. 
+# Retrieve these and print to the terminal. Expect errors related to 
+# un-computed variables and missing initial values.
+print_issues(analyser)
+
+# In order to avoid hard-coding values here, we will need to connect to external 
+# values to initialise the X variable and provide the value for alpha_X and beta_X.
+# This means that:
+#      - we need to create an external component to hold variable values
+#      - we need to create external variables in that component 
+#      - we need to specify the connections between variables and
+#      - we need to permit external connections on the variables.
+
+# Create a component which will store the hard-coded values for initialisation.
+# Name it 'gateParameters', and add it to the top-level gate component as a sibling
+# of the gateEquations component.
+gateParameters = Component('gateParameters')
+gate.addComponent(gateParameters)
+
+#      Create appropriate variables in this component, and set their units.
+#      Use the setInitialValue function to initialise them.
+X = Variable('X')
+X.setUnits('dimensionless')
+X.setInitialValue(0)
+gateParameters.addVariable(X)
+
+alpha = Variable('alpha')
+alpha.setUnits(per_ms)
+alpha.setInitialValue(0.1)
+gateParameters.addVariable(alpha)
+
+beta = Variable('beta')
+beta.setUnits(per_ms)
+beta.setInitialValue(0.5)
+gateParameters.addVariable(beta)
+
+# Specify a variable equivalence between the gateEquations variables and the parameter variables.
+# Validate the model again, expecting errors related to the variable interface types.
+Variable.addEquivalence(gateEquations.variable('X'), gateParameters.variable('X'))
+Variable.addEquivalence(gateEquations.variable('alpha_X'), gateParameters.variable('alpha'))
+Variable.addEquivalence(gateEquations.variable('beta_X'), gateParameters.variable('beta'))
+
+validator.validateModel(model)
+print_issues(validator)
+
+# Set the variable interface type according to the recommendation from the validator.
+# This can either be done individually using the Variable::setInterfaceType() function, or 
+# en masse for all the model's interfaces using the Model::fixVariableInterfaces() function.
+# Validate and analyse again, expecting no errors. 
+model.fixVariableInterfaces()
+
+validator.validateModel(model)
+print_issues(validator)
+
+analyser.analyseModel(model)
+print_issues(analyser)
+
+# %% [markdown]
+# Sanity check
+
+# %%
+# Print the model to the terminal using the helper function print_model.
+print_model(model)
+
+# Looking at the printout we see that the top-level component has no variables.  
+# Even though this is clearly a valid situation (as proved by 4.f), it's not
+# going to make this model easy to reuse.  We need to make sure that any input and
+# output variables are also connected into the top level gate component.  
+
+# Create intermediate variables for time t and gate status X in the gate component,
+# and ensure they have a public and private interface to enable two-way connection.
+# You may also need to set a public and private connection onto t and X in the
+# equations component too.
+gate.addVariable(gateEquations.variable('t').clone())
+gate.addVariable(gateEquations.variable('X').clone())
+
+gate.variable('t').setInterfaceType('public_and_private')
+gate.variable('X').setInterfaceType('public_and_private')
+gateEquations.variable('t').setInterfaceType('public_and_private')
+gateEquations.variable('X').setInterfaceType('public_and_private')
+
+# Connect the intermediate variables to their respective partners in the equations
+# component, and recheck the model.
+Variable.addEquivalence(gate.variable('t'), gateEquations.variable('t'))
+Variable.addEquivalence(gate.variable('X'), gateEquations.variable('X'))
+
+validator.validateModel(model)
+print_issues(validator)
+analyser.analyseModel(model)
+print_issues(analyser)
+
+# %% [markdown]
+# Serialise and output the model
+
+# %%
+# Create a Printer instance and use it to serialise the model.  This creates a string
+# containing the CellML-formatted version of the model.  Write this to a file called
+# 'cellml.cellml'.
+printer = Printer()
+write_file = open('cellml.cellml', 'w')
+write_file.write(printer.printModel(model))
+write_file.close()
+
+print('The created model has been written to GateModel.cellml')
diff --git a/src/combine_notebooks/examples/hello_world/neuroml.py b/src/combine_notebooks/examples/hello_world/neuroml.py
new file mode 100644
index 0000000..6236d22
--- /dev/null
+++ b/src/combine_notebooks/examples/hello_world/neuroml.py
@@ -0,0 +1,149 @@
+# ---
+# jupyter:
+#   jupytext:
+#     text_representation:
+#       extension: .py
+#       format_name: percent
+#       format_version: '1.3'
+#       jupytext_version: 1.14.5
+#   kernelspec:
+#     display_name: Python 3 (ipykernel)
+#     language: python
+#     name: python3
+# ---
+
+# %% [markdown]
+# # Interactive single Izhikevich neuron NeuroML example
+#
+# To run this interactive Jupyter Notebook, please click on the rocket icon 🚀 in the top panel. For more information, please see {ref}`how to use this documentation <userdocs:usage:jupyterbooks>`.
+# Please uncomment the line below if you use the Google Colab (it does not include these packages by default).
+
+# %%
+# #%pip install pyneuroml neuromllite NEURON
+
+# %%
+from neuroml import NeuroMLDocument
+import neuroml.writers as writers
+from neuroml.utils import component_factory
+from neuroml.utils import validate_neuroml2
+from pyneuroml import pynml
+from pyneuroml.lems import LEMSSimulation
+import numpy as np
+
+# %% [markdown]
+# ## Declaring the NeuroML model
+
+# %% [markdown]
+# ### Create a NeuroML document
+
+# %%
+nml_doc = component_factory(NeuroMLDocument, id="IzhSingleNeuron")
+
+# %%
+nml_doc.info()
+
+# %%
+nml_doc.info(True)
+
+# %% [markdown]
+# ### Define the Izhikevich cell and add it to the model
+
+# %%
+izh0 = nml_doc.add(
+    "Izhikevich2007Cell",
+    id="izh2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
+    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
+izh0.info(True)
+nml_doc.info(show_contents=True)
+
+# %% [markdown]
+# ### Create a network and add it to the model
+
+# %%
+net = nml_doc.add("Network", id="IzNet", validate=False)
+
+# %% [markdown]
+# ### Create a population of defined cells and add it to the model
+
+# %%
+size0 = 1
+pop0 = net.add("Population", id="IzhPop0", component=izh0.id, size=size0)
+net.info()
+
+# %% [markdown]
+# ### Define an external stimulus and add it to the model
+
+# %%
+pg = nml_doc.add(
+    "PulseGenerator",
+    id="pulseGen_%i" % 0, delay="0ms", duration="1000ms",
+    amplitude="0.07 nA"
+)
+exp_input = net.add("ExplicitInput", target="%s[%i]" % (pop0.id, 0), input=pg.id)
+
+# %% [markdown]
+# ### Write the NeuroML model to a file
+
+# %%
+nml_file = 'izhikevich2007_single_cell_network.nml'
+writers.NeuroMLWriter.write(nml_doc, nml_file)
+print("Written network file to: " + nml_file)
+
+# %% [markdown]
+# ### Validate the NeuroML model
+
+# %%
+validate_neuroml2(nml_file)
+
+# %% [markdown]
+# ## Simulating the model
+
+# %% [markdown]
+# ### Create a simulation instance of the model
+
+# %%
+simulation_id = "example-single-izhikevich2007cell-sim"
+simulation = LEMSSimulation(sim_id=simulation_id,
+                            duration=1000, dt=0.1, simulation_seed=123)
+simulation.assign_simulation_target(net.id)
+simulation.include_neuroml2_file(nml_file)
+
+# %% [markdown]
+# ### Define the output file to store simulation outputs
+#
+# Here, we record the neuron's membrane potential to the specified data file.
+
+# %%
+simulation.create_output_file(
+    "output0", "%s.v.dat" % simulation_id
+)
+simulation.add_column_to_output_file("output0", 'IzhPop0[0]', 'IzhPop0[0]/v')
+
+# %% [markdown]
+# ### Save the simulation to a file
+
+# %%
+lems_simulation_file = simulation.save_to_file()
+
+# %% [markdown]
+# ## Run the simulation using the jNeuroML simulator
+
+# %%
+pynml.run_lems_with_jneuroml(
+    lems_simulation_file, max_memory="2G", nogui=True, plot=False
+)
+
+# %% [markdown]
+# ## Plot the recorded data
+
+# %%
+# Load the data from the file and plot the graph for the membrane potential
+# using the pynml generate_plot utility function.
+data_array = np.loadtxt("%s.v.dat" % simulation_id)
+pynml.generate_plot(
+    [data_array[:, 0]], [data_array[:, 1]],
+    "Membrane potential", show_plot_already=True,
+    xaxis="time (s)", yaxis="membrane potential (V)"
+)
+
+# %%
diff --git a/src/combine_notebooks/examples/hello_world/sbml.py b/src/combine_notebooks/examples/hello_world/sbml.py
new file mode 100644
index 0000000..d3ef6e7
--- /dev/null
+++ b/src/combine_notebooks/examples/hello_world/sbml.py
@@ -0,0 +1,52 @@
+# ---
+# jupyter:
+#   jupytext:
+#     text_representation:
+#       extension: .py
+#       format_name: percent
+#       format_version: '1.3'
+#       jupytext_version: 1.14.5
+#   kernelspec:
+#     display_name: Python 3
+#     language: python
+#     name: python3
+# ---
+
+# %% [markdown]
+# Here we show how to create a basic SBML model using basiCO, and simulating it. We start as usual by importing basiCO.
+
+# %%
+from basico import *
+
+# %% [markdown]
+# Lets create a new model, passing along the name that we want to give it.
+
+# %%
+new_model(name="New Model") 
+
+# %% [markdown]
+# Now we add a basic reaction of a metabolite A degrading.  
+
+# %%
+add_reaction('r1', 'A -> ')
+
+# %% [markdown]
+# We export the model to an sbml format and print it.
+
+# %%
+save_model('sbml.xml', type='sbml')
+xml = open('sbml.xml').read()
+print(xml)
+
+# %% [markdown]
+# To change the initial concentration, we use set_species, and specify which property we want to change.
+
+# %%
+set_species('A', initial_concentration=10)
+get_species().initial_concentration
+
+# %%
+result = run_time_course(duration=50)
+result.plot()
+
+# %%
diff --git a/src/combine_notebooks/examples/hello_world/sedml.py b/src/combine_notebooks/examples/hello_world/sedml.py
new file mode 100644
index 0000000..219e873
--- /dev/null
+++ b/src/combine_notebooks/examples/hello_world/sedml.py
@@ -0,0 +1,137 @@
+# ---
+# jupyter:
+#   jupytext:
+#     text_representation:
+#       extension: .py
+#       format_name: percent
+#       format_version: '1.3'
+#       jupytext_version: 1.14.5
+#   kernelspec:
+#     display_name: Python 3
+#     language: python
+#     name: python3
+# ---
+
+# %%
+from pathlib import Path
+import libsedml
+
+# %% [markdown]
+# ## Declaring the SED-ML model
+
+ # %%
+ # create the document
+doc = libsedml.SedDocument(1, 4)
+# create a first model referencing an sbml file
+model = doc.createModel()
+model.setId("model1")
+model.setSource("model1.xml")
+model.setLanguage("urn:sedml:language:sbml") 
+
+# %% [markdown]
+# Simulators
+
+# %%
+# create simulation
+tc = doc.createUniformTimeCourse()
+tc.setId("sim1")
+tc.setInitialTime(0.0)
+tc.setOutputStartTime(0.0)
+tc.setOutputEndTime(10.0)
+tc.setNumberOfSteps(100)
+# need to set the correct KISAO Term
+alg = tc.createAlgorithm()
+alg.setName("Deterministic (LSODA)")
+alg.setKisaoID("KISAO:0000560")
+# add algorithm parameters
+alg_par1 = alg.createAlgorithmParameter()
+alg_par1.setName("Relative Tolerance")
+alg_par1.setKisaoID("KISAO:0000209")
+alg_par1.setValue("1e-06")
+alg_par2 = alg.createAlgorithmParameter()
+alg_par2.setName("Absolute Tolerance")
+alg_par2.setKisaoID("KISAO:0000211")
+alg_par2.setValue("1e-12")
+alg_par3 = alg.createAlgorithmParameter()
+alg_par3.setName("Integrate Reduced Model")
+alg_par3.setKisaoID("KISAO:0000216")
+alg_par3.setValue("0")
+alg_par4 = alg.createAlgorithmParameter()
+alg_par4.setName("Max Internal Steps")
+alg_par4.setKisaoID("KISAO:0000415")
+alg_par4.setValue("100000")
+
+
+# %% [markdown]
+# Task
+
+# %%
+# create a task that uses the simulation and the model above
+task = doc.createTask()
+task.setId("task1")
+task.setModelReference("model1")
+task.setSimulationReference("sim1")
+
+
+# %% [markdown]
+# Data generators
+
+# %%
+# add a DataGenerator to hold the output for time
+dg = doc.createDataGenerator()
+dg.setId("_1_task1")
+dg.setName("Time")
+var = dg.createVariable()
+var.setId("p1__1_task1")
+var.setName("Time")
+var.setTaskReference("task1")
+var.setSymbol("urn:sedml:symbol:time")
+var.setTerm("KISAO:0000832")
+dg.setMath(libsedml.parseFormula("p1__1_task1"))
+
+dg = doc.createDataGenerator()
+dg.setId("A_1_task1")
+dg.setName("[A]")
+var = dg.createVariable()
+var.setId("p1_A_1_task1")
+var.setName("[A]")
+var.setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id=&apos;A&apos;]")
+var.setTaskReference("task1")
+var.setTerm("KISAO:0000838")
+dg.setMath(libsedml.parseFormula("p1_A_1_task1"))
+
+
+
+# %% [markdown]
+# Outputs
+
+# %%
+# add a 2d plot
+plot = doc.createPlot2D()
+plot.setId("plot_1_task1")
+plot.setName("Concentrations, Volumes, and Global Quantity Values")
+curve = plot.createCurve()
+curve.setId("p1_curve_1_task1")
+curve.setName("[A]")
+curve.setLogX(False)
+curve.setLogY(False)
+curve.setStyle("style1")
+curve.setXDataReference("_1_task1")
+curve.setYDataReference("A_1_task1")
+
+# %% [markdown]
+# Styles
+
+# %%
+style : libsedml.SedStyle = doc.createStyle()
+style.setId("style1")
+line = style.createLineStyle()
+line.setType("solid")
+line.setThickness(1.2)
+marker = style.createMarkerStyle()
+marker.setType("none")
+
+
+# %%
+libsedml.writeSedML(doc, str('sedml_path.sedml'))
+
diff --git a/src/combine_notebooks/examples/repressilator/__init__.py b/src/combine_notebooks/examples/repressilator/__init__.py
new file mode 100644
index 0000000..4ecfa54
--- /dev/null
+++ b/src/combine_notebooks/examples/repressilator/__init__.py
@@ -0,0 +1,1 @@
+"""COMBINE repressilator example for each standard."""
diff --git a/src/combine_notebooks/examples/example_biopax.py b/src/combine_notebooks/examples/repressilator/example_biopax.py
similarity index 100%
rename from src/combine_notebooks/examples/example_biopax.py
rename to src/combine_notebooks/examples/repressilator/example_biopax.py
diff --git a/src/combine_notebooks/examples/example_cellml.py b/src/combine_notebooks/examples/repressilator/example_cellml.py
similarity index 100%
rename from src/combine_notebooks/examples/example_cellml.py
rename to src/combine_notebooks/examples/repressilator/example_cellml.py
diff --git a/src/combine_notebooks/examples/example_neuroml.py b/src/combine_notebooks/examples/repressilator/example_neuroml.py
similarity index 100%
rename from src/combine_notebooks/examples/example_neuroml.py
rename to src/combine_notebooks/examples/repressilator/example_neuroml.py
diff --git a/src/combine_notebooks/examples/example_omex.py b/src/combine_notebooks/examples/repressilator/example_omex.py
similarity index 100%
rename from src/combine_notebooks/examples/example_omex.py
rename to src/combine_notebooks/examples/repressilator/example_omex.py
diff --git a/src/combine_notebooks/examples/example_sbgn.py b/src/combine_notebooks/examples/repressilator/example_sbgn.py
similarity index 100%
rename from src/combine_notebooks/examples/example_sbgn.py
rename to src/combine_notebooks/examples/repressilator/example_sbgn.py
diff --git a/src/combine_notebooks/examples/example_sbml_antimony.py b/src/combine_notebooks/examples/repressilator/example_sbml_antimony.py
similarity index 100%
rename from src/combine_notebooks/examples/example_sbml_antimony.py
rename to src/combine_notebooks/examples/repressilator/example_sbml_antimony.py
diff --git a/src/combine_notebooks/examples/example_sbml_libsbml.py b/src/combine_notebooks/examples/repressilator/example_sbml_libsbml.py
similarity index 100%
rename from src/combine_notebooks/examples/example_sbml_libsbml.py
rename to src/combine_notebooks/examples/repressilator/example_sbml_libsbml.py
diff --git a/src/combine_notebooks/examples/example_sbml_sbmlutils.py b/src/combine_notebooks/examples/repressilator/example_sbml_sbmlutils.py
similarity index 100%
rename from src/combine_notebooks/examples/example_sbml_sbmlutils.py
rename to src/combine_notebooks/examples/repressilator/example_sbml_sbmlutils.py
diff --git a/src/combine_notebooks/examples/example_sbol.py b/src/combine_notebooks/examples/repressilator/example_sbol.py
similarity index 100%
rename from src/combine_notebooks/examples/example_sbol.py
rename to src/combine_notebooks/examples/repressilator/example_sbol.py
diff --git a/src/combine_notebooks/examples/example_sedml.py b/src/combine_notebooks/examples/repressilator/example_sedml.py
similarity index 100%
rename from src/combine_notebooks/examples/example_sedml.py
rename to src/combine_notebooks/examples/repressilator/example_sedml.py
diff --git a/tox.ini b/tox.ini
index 953cc11..0f0e436 100644
--- a/tox.ini
+++ b/tox.ini
@@ -37,7 +37,7 @@ deps=
     flake8-docstrings
     flake8-bugbear
 commands=
-    flake8 {toxinidir}/src/combine_notebooks {toxinidir}/setup.py {toxinidir}/tests --extend-ignore=F401,F403,F405,E501,D100 --exclude={toxinidir}/src/combine_notebooks/examples/example_sbol.py
+    flake8 {toxinidir}/src/combine_notebooks {toxinidir}/setup.py {toxinidir}/tests --extend-ignore=F401,F403,F405,E501,D100 --exclude={toxinidir}/src/combine_notebooks/examples/repressilator/example_sbol.py
 # F401 : module imported but unused
 # F403 : 'from .x import *' used; unable to detect undefined names
 # F405 : name may be undefined, or defined from star imports: module
@@ -147,6 +147,9 @@ ignore_missing_imports = True
 [mypy-antimony.*]
 ignore_missing_imports = True
 
+[mypy-numpy.*]
+ignore_missing_imports = True
+
 [mypy-jinja2.*]
 ignore_missing_imports = True
 
@@ -207,4 +210,4 @@ ignore_missing_imports = True
 ignore_missing_imports = True
 
 [mypy-pybiopax.*]
-ignore_missing_imports = True
\ No newline at end of file
+ignore_missing_imports = True


Test patch:
diff --git a/tests/examples/test_biopax.py b/tests/examples/test_biopax.py
index cea1dc2..5d9eecf 100644
--- a/tests/examples/test_biopax.py
+++ b/tests/examples/test_biopax.py
@@ -4,7 +4,7 @@
 import pytest
 from pybiopax.biopax.model import BioPaxModel
 
-from combine_notebooks.examples import example_biopax
+from combine_notebooks.examples.repressilator import example_biopax
 
 
 def test_create_repressilator_biopax(tmp_path: Path) -> None:
diff --git a/tests/examples/test_cellml.py b/tests/examples/test_cellml.py
index 08db20e..9e5b3b0 100644
--- a/tests/examples/test_cellml.py
+++ b/tests/examples/test_cellml.py
@@ -1,7 +1,7 @@
 """Test CellML functionality."""
 from pathlib import Path
 
-from combine_notebooks.examples import example_cellml
+from combine_notebooks.examples.repressilator import example_cellml
 
 
 def test_create_repressilator_cellml(tmp_path: Path) -> None:
diff --git a/tests/examples/test_omex.py b/tests/examples/test_omex.py
index 9019bb4..88d2429 100644
--- a/tests/examples/test_omex.py
+++ b/tests/examples/test_omex.py
@@ -2,7 +2,7 @@
 from pathlib import Path
 
 from combine_notebooks.combine_files import create_combine_files
-from combine_notebooks.examples.example_omex import create_omex
+from combine_notebooks.examples.repressilator.example_omex import create_omex
 
 
 def test_create_repressilator_omex(tmp_path: Path) -> None:
diff --git a/tests/examples/test_sbgn.py b/tests/examples/test_sbgn.py
index 5cec0c3..0095fe2 100644
--- a/tests/examples/test_sbgn.py
+++ b/tests/examples/test_sbgn.py
@@ -1,7 +1,7 @@
 """Test SBGN functionality."""
 from pathlib import Path
 
-from combine_notebooks.examples import example_sbgn
+from combine_notebooks.examples.repressilator import example_sbgn
 
 
 def test_create_repressilator_libsbgn(tmp_path: Path) -> None:
diff --git a/tests/examples/test_sbml.py b/tests/examples/test_sbml.py
index 2835b47..dfe6553 100644
--- a/tests/examples/test_sbml.py
+++ b/tests/examples/test_sbml.py
@@ -3,7 +3,7 @@
 
 from sbmlutils.factory import FactoryResult
 
-from combine_notebooks.examples import (
+from combine_notebooks.examples.repressilator import (
     example_sbml_antimony,
     example_sbml_libsbml,
     example_sbml_sbmlutils,
diff --git a/tests/examples/test_sedml.py b/tests/examples/test_sedml.py
index 196693e..8de6a1c 100644
--- a/tests/examples/test_sedml.py
+++ b/tests/examples/test_sedml.py
@@ -1,7 +1,7 @@
 """Test SED-ML functionality."""
 from pathlib import Path
 
-from combine_notebooks.examples import example_sedml
+from combine_notebooks.examples.repressilator import example_sedml
 
 
 def test_create_repressilator_cellml(tmp_path: Path) -> None: