{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Guard Cell Abscinic Acid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "In this tutorial, we will use a Boolean model representing the signaling events taking place upon **ABA-induced stomatal closure** in plant guard cells. Stomata are microscopic pores on the leaf surface thatregulate gas exchange, and their aperture is tightly controlled by a pair of guard cells. In response to drought, the hormone abscisic acid (ABA) promotes stomatal closure to minimize water loss. This complex physiological response involves a broad aarray of molecular components, including ion channels, secondary messengers, and cytoskeletal regulators. The model integrates more than 40 experimetally characterized components into a unified **signal transduction network** that captures the main regulatory interactions driving guard cell shrinkage and stomatal closure. It successfully reproduces known physiological and pathway-level respones to ABA.\n", "\n", "
\n", "\n", "Li S, Assmann SM, Albert R (2006). \n", "Predicting Essential Components of Signal Transduction Networks: A Dynamic Model of Guard Cell Abscisic Acid Signaling. \n", "PLOS Biology 4(10): e312. \n", "https://doi.org/10.1371/journal.pbio.0040312\n", "
\n" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [], "source": [ "import biolqm\n", "import tempfile\n", "import re\n", "import boolevard as blv\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import xml.etree.ElementTree as ET\n", "from PyComplexHeatmap import * \n", "from libsbml import *\n", "from matplotlib.colors import ListedColormap, LinearSegmentedColormap\n", "from scipy.cluster.hierarchy import linkage, leaves_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **Guard Cell Abscisic Acid Signaling** Boolean Model is stored in [Cell Collective](https://research.cellcollective.org/dashboard#module/2161:1/guard-cell-abscisic-acid-signaling/1). Boolean models can be downloaded in SBML format from Cell Collective, but BooLEVARD uses Boolean models in BoolNet format as input. Accordingly, we must define a small function to convert SBML to BoolNet models:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Convert SBML-qual model to bnet format\n", "def sbml2bnet(sbml_file, bnet_file):\n", " reader = SBMLReader()\n", " document = reader.readSBMLFromFile(sbml_file)\n", " model = document.getModel()\n", " qual = model.getPlugin(\"qual\")\n", " id2name = {}\n", " for i in range(qual.getNumQualitativeSpecies()):\n", " qs = qual.getQualitativeSpecies(i)\n", " id2name[qs.getId()] = qs.getName() if qs.isSetName() else qs.getId()\n", " equations = {}\n", " new_lines = []\n", " for transition in qual.getListOfTransitions():\n", " outputs = transition.getListOfOutputs()\n", " target_id = outputs[0].getQualitativeSpecies()\n", " target_name = id2name.get(target_id, target_id)\n", " function_terms = transition.getListOfFunctionTerms()\n", " formula = formulaToL3String(function_terms[0].getMath())\n", " normal_formula = re.sub(r'\\|\\|', '|', formula) # convert || to |\n", " normal_formula = re.sub(r'&&', '&', normal_formula) # convert && to &\n", " normal_formula = re.sub(r'\\b(\\w+)\\s*==\\s*1\\b', r'\\1', normal_formula) # convert == 1 to \n", " normal_formula = re.sub(r'\\b(\\w+)\\s*==\\s*0\\b', r'~\\1', normal_formula)\n", " normal_formula = normal_formula.replace('!', '~')\n", " for node_id, node_name in id2name.items():\n", " normal_formula = re.sub(rf'\\b{re.escape(node_id)}\\b', node_name, normal_formula)\n", " equations[target_name] = normal_formula\n", " for var, formula in equations.items():\n", " new_lines.append(f\"{var}, {formula}\\n\")\n", " inputs = [node for node in list(id2name.values()) if node not in list(equations.keys())]\n", " for input in inputs:\n", " new_lines.append(f\"{input}, {input}\\n\") \n", " with open(bnet_file, \"w\") as out:\n", " out.writelines(new_lines)\n", " print(f\"✅ SBML-qual model successfully converted to bnet: {bnet_file}\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we can generate the BoolNet version of the model:" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ SBML-qual model successfully converted to bnet: resources/Guard Cell Abscisic Acid Signaling.bnet\n" ] } ], "source": [ "# The SBML model is stored in:\n", "model_sbml_path = \"resources/Guard Cell Abscisic Acid Signaling (SBML).sbml\"\n", "# We will save the BoolNet model in:\n", "model_bnet_path = \"resources/Guard Cell Abscisic Acid Signaling.bnet\"\n", "\n", "# Convert SBML to BoolNet format\n", "sbml2bnet(model_sbml_path, model_bnet_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's now load it with BooLEVARD, and retrieve some basic information:" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of nodes: 44\n", "Number of inputs: 4, (ABA, ABH1, GCR1, ERA1)\n", "Number of stable states: 16\n" ] } ], "source": [ "# Load te BoolNet model with BooLEVARD\n", "model = blv.Load(model_bnet_path)\n", "print(f\"Number of nodes: {len(model.Nodes)}\")\n", "print(f\"Number of inputs: {len(model.Info.index[model.Info.index == model.Info['DNF'].apply(str)])}, ({', '.join(list((model.Info.index[model.Info.index == model.Info['DNF'].apply(str)])))})\")\n", "print(f\"Number of stable states: {len(model.Info.columns)-2}\")" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " | 11 | \n", "9 | \n", "10 | \n", "8 | \n", "7 | \n", "6 | \n", "5 | \n", "4 | \n", "1 | \n", "0 | \n", "2 | \n", "3 | \n", "13 | \n", "15 | \n", "12 | \n", "14 | \n", "DNF | \n", "NDNF | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
cGMP | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "GC | \n", "~GC | \n", "
RCN1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ABA | \n", "~ABA | \n", "
AGB1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "GPA1 | \n", "~GPA1 | \n", "
Actin | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(Ca2_c, And(~Ca2_c, ~RAC1)) | \n", "And(~Ca2_c, RAC1) | \n", "
cADPR | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "ADPRc | \n", "~ADPRc | \n", "
Depolar | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(AnionEM, Ca2_c, KEV, And(~AnionEM, ~Ca2_c, ... | \n", "And(~AnionEM, ~Ca2_c, HTPase, ~KEV, KOUT) | \n", "
KEV | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "Ca2_c | \n", "~Ca2_c | \n", "
KAP | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(And(~Ca2_c, Depolar), And(Depolar, ~pH)) | \n", "Or(~Depolar, And(Ca2_c, pH)) | \n", "
Closure | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(And(Actin, AnionEM, KAP, ~Malate), And(Acti... | \n", "Or(~Actin, ~AnionEM, Malate, And(~KAP, ~KOUT)) | \n", "
NIA12 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "RCN1 | \n", "~RCN1 | \n", "
CaIM | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "Or(And(~ABH1, ~Depolar, ERA1), And(ABH1, ~Depo... | \n", "Or(Depolar, And(ABH1, ERA1, ~ROS)) | \n", "
PLD | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "GPA1 | \n", "~GPA1 | \n", "
AnionEM | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(And(~ABI1, Ca2_c), And(~ABI1, pH), And(Ca2_... | \n", "Or(And(ABI1, ~Ca2_c), And(ABI1, ~pH), And(~Ca2... | \n", "
ROP10 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ERA1 | \n", "~ERA1 | \n", "
NO | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "And(NIA12, NOS) | \n", "Or(~NIA12, ~NOS) | \n", "
S1P | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "SphK | \n", "~SphK | \n", "
GPA1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(And(AGB1, ~GCR1), And(AGB1, S1P)) | \n", "Or(~AGB1, And(GCR1, ~S1P)) | \n", "
ROP2 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "PA | \n", "~PA | \n", "
InsP3 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "PLC | \n", "~PLC | \n", "
SphK | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ABA | \n", "~ABA | \n", "
NOS | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "Ca2_c | \n", "~Ca2_c | \n", "
Atrboh | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "And(~ABI1, OST1, ROP2, pH) | \n", "Or(ABI1, ~OST1, ~ROP2, ~pH) | \n", "
Ca2_ATPase | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "Ca2_c | \n", "~Ca2_c | \n", "
OST1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ABA | \n", "~ABA | \n", "
Malate | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "And(~ABA, ~AnionEM, PEPC) | \n", "Or(ABA, AnionEM, ~PEPC) | \n", "
RAC1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "And(~ABA, ~ABI1) | \n", "Or(ABA, ABI1) | \n", "
InsP6 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "InsPK | \n", "~InsPK | \n", "
ADPRc | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "NO | \n", "~NO | \n", "
ABI1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "And(~PA, ~ROS, pH) | \n", "Or(PA, ROS, ~pH) | \n", "
ROS | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Atrboh | \n", "~Atrboh | \n", "
Ca2_c | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "Or(And(CIS, ~Ca2_ATPase), And(~Ca2_ATPase, CaIM)) | \n", "Or(Ca2_ATPase, And(~CIS, ~CaIM)) | \n", "
InsPK | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ABA | \n", "~ABA | \n", "
PA | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "PLD | \n", "~PLD | \n", "
GC | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "NO | \n", "~NO | \n", "
KOUT | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "Or(And(Depolar, ~NO), And(Depolar, ~ROS), And(... | \n", "Or(~Depolar, And(NO, ROS, ~pH)) | \n", "
PEPC | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "~ABA | \n", "ABA | \n", "
HTPase | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "And(~Ca2_c, ~ROS, ~pH) | \n", "Or(Ca2_c, ROS, pH) | \n", "
PLC | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "And(ABA, Ca2_c) | \n", "Or(~ABA, ~Ca2_c) | \n", "
pH | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ABA | \n", "~ABA | \n", "
CIS | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "Or(And(InsP3, InsP6), And(cADPR, cGMP)) | \n", "Or(And(~InsP3, ~cADPR), And(~InsP3, ~cGMP), An... | \n", "
ABA | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ABA | \n", "~ABA | \n", "
ABH1 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "ABH1 | \n", "~ABH1 | \n", "
GCR1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "0 | \n", "1 | \n", "GCR1 | \n", "~GCR1 | \n", "
ERA1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "0 | \n", "0 | \n", "0 | \n", "0 | \n", "1 | \n", "1 | \n", "1 | \n", "1 | \n", "ERA1 | \n", "~ERA1 | \n", "