"""
Overview
========
PySB implementations of Bcl2-models from the group of Pingping Shen, along with
other derived, closely related models.
In a series of papers from 2007-2010, the research group of Pingping Shen
implemented and investigated models of Bcl-2 family interactions. In this file
we have re-implemented these models using PySB. We have also included a model
from [Howells2011]_ which is a fairly straightforward extension of a
Shen group model from [Chen2007biophysj]_.
MOMP model implementations
--------------------------
The implementations of the various models are contained within the
following functions:
- :py:func:`chen_biophys_j`
- :py:func:`chen_febs_indirect`
- :py:func:`chen_febs_direct`
- :py:func:`cui_direct`
- :py:func:`cui_direct1`
- :py:func:`cui_direct2`
- :py:func:`howells`
Model descriptions (with references) are available in the documentation for
each function.
The models are closely related, and many of the later models are derived from
earlier ones. The models have been implemented in such a way as to make this
hierarchy transparent.
Shared functions
----------------
In addition to the implementations of the models themselves, this file also
contains two macros that are re-used by the various models:
- :py:func:`momp_monomers`, which declares the Bcl-2 molecule types used in the
models, and
- :py:func:`shen_pore_transport`, which declares the set of transport reactions
required for the release of Cytochrome c and Smac.
Parameter values
----------------
In the original papers, species quantities and forward rate constants were
either given in units of micromolar ([Chen2007biophysj]_, [Howells2011]_) or
nanomolar ([Chen2007febs]_, [Cui2008]_). For consistency, these values have
been written in terms of their molar equivalents (for example, 0.1uM = 0.1e-6 M;
3 uM^-1 s^1 = 3e6 M^-1 s^-1). Concentrations have been converted into units of
numbers of molecules according to:
No. of molecules = Conc * N_A * vol
where N_A is Avogadro's number and vol is the cell volume, which is given a
default value in the global variable `V` defined in :doc:`shared`.
Similarly, forward rate constants are converted into stochastic rate constants
according to:
Stoch. rate constant = Det. rate constant / (N_A * vol)
"""
# Preliminaries
# =============
# We'll need everything from the pysb core and some macros:
from pysb import *
from shared import *
from pysb.macros import catalyze_one_step_reversible, catalyze_one_step, \
synthesize_degrade_table, degrade, equilibrate
from pysb.util import alias_model_components
# Shared functions
# ================
# The Shen model functions share some logic that is contained in the following
# two functions.
[docs]def momp_monomers():
"""Declares the signatures of the Bcl-2 family monomers used in all of the
Shen models.
In principle, each Shen MOMP model implementation could declare its own
set of Bcl-2 monomers, each with its own site and state signature. In the
interest of consistency, a unified set of monomer signatures that supports
all of the models is defined here.
"""
# **Activators.** We use Bid as a representative for the generic
# "activator" "Act" or "BH3" used in the Shen models. Bid has three states:
# Untruncated, Truncated, and truncated and Mitochondrial.
Monomer('Bid', ['bf', 'state'], {'state':['U', 'T', 'M']})
# **Effector***. Bax, states: Cytoplasmic, Mitochondrial, Active.
# Sites 's1' and 's2' are used for pore formation.
Monomer('Bax', ['bf', 's1', 's2', 'state'], {'state':['C', 'M', 'A']})
# **Anti-apoptotic**. Bcl-2 is considered to be constitutively
# mitochondrial so it doesn't have a 'state' site, only the single binding
# site.
Monomer('Bcl2', ['bf'])
# **Sensitizer**. We use Bad as a representative for the generic "Ena"
# ("Enabler," another term for sensitizer) used in the Shen models. Bad can
# be both Cytosolic and Mitochondrial. To support the Bad phosphorylation
# model of [Howells2011]_ we also add a site "serine", with three
# states (Unphosphorylated, Phosphorylated, and Bound (i.e., to 14-3-3
# domains). These are only used in the Howells model--for all other
# models, the serine is set as unphosphorylated (i.e., serine='U').
Monomer('Bad',
['bf', 'state', 'serine'],
{'state':['C', 'M'], 'serine':['U', 'P', 'B']})
# **Cytochrome C and Smac**. We include these species here so that the
# the Shen models can optionally implement CytoC/Smac release. This allows
# them to interface with the downstream apoptotic machinery when composed
# into a larger model. Both Cytochrome C and Smac have three states:
# Mitochondrial (the initial state), Cytosolic (for after release) and
# Active.
Monomer('CytoC', ['bf', 'state'], {'state':['M', 'C', 'A']})
Monomer('Smac', ['bf', 'state'], {'state':['M', 'C', 'A']})
[docs]def shen_pore_transport(pore_size=4):
"""Implements release of Cytochrome C and Smac.
Uses the same model as the original EARM 1.0 ([Albeck2008]_), in
which pore transport is modeled as binding of the cargo
(cytochrome C or Smac) to the active pore, and then release, in a
catalysis-like mechanism.
The initial conditions for cytochrome C and Smac, and the rate constants
for transport, are also taken from EARM 1.0.
"""
Initial(Smac(state='M', bf=None), Parameter('Smac_0', 1e5))
Initial(CytoC(state='M', bf=None), Parameter('CytoC_0', 5e5))
pore_transport(Bax(state='A'), pore_size, Smac(state='M'),
Smac(state='C'),
[[rate_scaling_factor*2e-6, 1e-3, 10]])
pore_transport(Bax(state='A'), pore_size, CytoC(state='M'),
CytoC(state='C'),
[[rate_scaling_factor*2e-6, 1e-3, 10]])
# MOMP model implementations
# ==========================
[docs]def chen_biophys_j(do_pore_assembly=True, do_pore_transport=False):
"""Model drawn from [Chen2007biophysj]_.
Model features (see the source code):
* Activation of Bax by an activator (tBid) in a one-step, hit-and-run
manner; Bax activation is reversible.
* Bcl2 binds both tBid and Bax Bax can displace tBid from Bcl-2 (but not
the reverse).
* If Bax oligomerization is incorporated into the model (see
`do_pore_assembly` argument, below), then this occurs as a spontaneous,
order 4 reaction.
This model combines both "direct" type and "indirect" type elements in
that Bcl-2 is capable of binding both Bid and Bax (see `bind_table` call
in the source code).
Parameters
----------
do_pore_assembly : True (default) or False
If True, adds the formation of Bax oligomers to the model. If False,
the model's most downstream element is Bax activation. This is included
for two reasons: first, the original publication included two variant
models, one with and one without Bax oligomerization, so this allows
this aspect of the original models to be explored. Second, it allows
a model that extends this model to implement a different model of Bax
pore assembly (for example, as is the case with cui_direct).
do_pore_transport : True or False (default)
If True, adds the release of Cytochrome C and Smac to the model by
calling the function :py:func:`shen_pore_transport`. If CytoC/Smac
release are not incorporated into the model, the model matches the
originally published model but can't be composed into the full
extrinsic apoptosis pathway.
"""
Parameter('Bcl2_0', 0.1e-6 * N_A * V) # Mitochondrial Bcl2
Parameter('Bax_0', 0.2e-6 * N_A * V) # Bax
alias_model_components()
# Bax is in the Cytosolic, inactive state by default.
Initial(Bax(bf=None, s1=None, s2=None, state='C'), Bax_0)
Initial(Bcl2(bf=None), Bcl2_0)
# One-step "kiss-and-run" activation of Bax by tBid:
catalyze_one_step_reversible(
Bid(state='T', bf=None), Bax(bf=None, **inactive_monomer),
Bax(bf=None, **active_monomer), [0.5e6/(N_A*V), 1e-1])
# Bcl2 binds tBid and Bax:
bind_table([[ Bcl2],
[Bid(state='T'), (3e6/(N_A*V), 4e-2)],
[Bax(active_monomer), (2e6/(N_A*V), 1e-3)]])
# Bax can displace Bid from Bcl2:
displace(Bax(active_monomer), Bid(state='T'), Bcl2, 2e6/(N_A*V))
if do_pore_assembly:
# Four Bax monomers cooperatively bind to form a tetramer
assemble_pore_spontaneous(Bax(state='A', bf=None),
[2e6*4/(N_A*V), 0])
if do_pore_transport:
# Release Cytochrome C and Smac:
shen_pore_transport(pore_size=4)
[docs]def chen_febs_indirect(do_pore_assembly=True, do_pore_transport=False):
"""The "indirect" model drawn from [Chen2007febs]_.
Model features (see the source code):
* There is no activation of Bax by tBid. Bax starts out constitutively
"active" in that in its initial state, it is able to form oligomers.
* Bcl-2 can bind tBid and Bax.
Parameters
----------
do_pore_assembly : True (default) or False
As for :py:func:`chen_biophys_j`.
do_pore_transport : True or False (default)
As for :py:func:`chen_biophys_j`.
"""
Parameter('Bcl2_0' , 30e-9 * N_A * V) # Mitochondrial Bcl2
Parameter('Bax_0' , 60e-9 * N_A * V) # Bax
alias_model_components()
Initial(Bax(bf=None, s1=None, s2=None, state='A'), Bax_0)
Initial(Bcl2(bf=None), Bcl2_0)
# (Note: No activation of Bax by tBid, so Bax is in the active state
# by default)
# Bcl2 binds tBid and Bax:
bind_table([[ Bcl2],
[Bid(state='T'), (1e5/(N_A*V), 1e-3)],
[Bax(active_monomer), (1e5/(N_A*V), 1e-3)]])
if do_pore_assembly:
# Four "inactive" Bax monomers cooperatively bind to form a tetramer:
assemble_pore_spontaneous(Bax(state='A', bf=None),
[4*1e6/(N_A*V), 1e-3])
if do_pore_transport:
# Release Cytochrome C and Smac:
shen_pore_transport(pore_size=4)
[docs]def chen_febs_direct(do_pore_assembly=True, do_pore_transport=False):
"""The "direct" model drawn from [Chen2007febs]_.
Model features (see the source code):
* Activation of Bax by an activator (tBid) in a one-step, hit-and-run
manner; Bax activation is reversible.
* Bcl-2 can bind tBid, but not Bax.
Parameters
----------
do_pore_assembly : True (default) or False
As for :py:func:`chen_biophys_j`.
do_pore_transport : True or False (default)
As for :py:func:`chen_biophys_j`.
"""
# Initial conditions
Parameter('Bcl2_0' , 30e-9 * N_A * V) # Bcl2
Parameter('Bax_0' , 60e-9 * N_A * V) # InBax
alias_model_components()
Initial(Bax(bf=None, s1=None, s2=None, state='C'), Bax_0)
Initial(Bcl2(bf=None), Bcl2_0)
# One-step "kiss-and-run" activation of Bax by tBid
catalyze_one_step_reversible(
Bid(state='T', bf=None), Bax(bf=None, **inactive_monomer),
Bax(bf=None, **active_monomer), [1e6/(N_A*V), 1e-3])
# Bcl2 binds tBid and Bad (a sensitizer) but not Bax
bind_table([[ Bcl2],
[Bid(state='T'), (1e5/(N_A*V), 1e-3)],
[Bad(state='M'), (1e5/(N_A*V), 1e-3)]])
if do_pore_assembly:
# Four Bax monomers cooperatively bind to form a tetramer
assemble_pore_spontaneous(Bax(state='A', bf=None),
[4*1e6/(N_A*V), 1e-3])
if do_pore_transport:
# Release Cytochrome C and Smac:
shen_pore_transport(pore_size=4)
[docs]def cui_direct(do_pore_transport=False):
"""The "direct" model drawn from [Cui2008]_.
Builds on the direct model from [Chen2007febs]_, implemented
in :py:func:`chen_febs_direct` (see source code).
Parameters
----------
do_pore_transport : True or False (default)
As for :py:func:`chen_biophys_j`.
"""
# Build on the direct model from [Chen2007febs]_ by...
# (NOTE that we set the keyword argument `do_pore_assembly` to False here:
# this is because we don't want to use a tetrameric pore as was implemented
# in the Chen model, we want to implement a dimeric pore. See comment #3,
# below.)
chen_febs_direct(do_pore_assembly=False, do_pore_transport=False)
alias_model_components()
# 1. Overriding some parameter values:
# Cut the activation rate of Bax by tBid by half (was originally 1e6):
one_step_BidT_BaxC_to_BidT_BaxA_kf.value = 5e5/(N_A*V)
# Make Bid/Bcl2 binding 10-fold tighter (was originally 1e5)
bind_BidT_Bcl2_kf.value = 1e6/(N_A*V)
# 2. Adding a Bad-for-Bid displacement reaction,
displace_reversibly(Bad(state='M'), Bid(state='T'), Bcl2,
[1e5/(N_A*V), 0.001])
# 3. Adding simplified MAC formation (Bax dimerization)
# NOTE: Even though this binding reaction is homomeric (which would
# imply that the forward rate should be divided by two) the fact that the
# binding reaction can occur in two different ways (s1 on one Bax binding
# to the s2 on another, vs. s2 on the first Bax binding to s1 on the second)
# requires that the rate be scaled back by a factor of two. These two
# scaling factors cancel out, so the forward rate constant is not scaled,
# and is used in the ODE with its nominal value.
active_unbound = {'state': 'A', 'bf': None}
assemble_pore_sequential(Bax(**active_unbound), 2,
[[2e5/(N_A*V), 0.02]])
# 4. Adding synthesis and degradation reactions
Bax2 = Bax(s1=1, s2=None) % Bax(s1=None, s2=1)
synthesize_degrade_table(
[[Bax(bf=None, **inactive_monomer), 0.06, 0.001],
[Bax(bf=None, **active_monomer), None, 0.001],
[Bid(state='T', bf=None), 0.001, 0.001],
[Bcl2(bf=None), 0.03, 0.001],
[Bid(state='T', bf=1) % Bcl2(bf=1), None, 0.005],
[Bad(state='M', bf=None, serine='U'), 0.001, 0.001],
[Bad(bf=1) % Bcl2(bf=1), None, 0.005],
[Bax2, None, 0.0005]])
if do_pore_transport:
# Release Cytochrome C and Smac:
shen_pore_transport(pore_size=2)
[docs]def cui_direct1(do_pore_transport=False):
"""The "direct 1" model drawn from [Cui2008]_.
Builds on the (base) direct model from [Cui2008]_,
implemented in :py:func:`cui_direct` (see source code).
Parameters
----------
do_pore_transport : True or False (default)
As for :py:func:`chen_biophys_j`.
"""
alias_model_components()
# Build on the base "direct" model...
cui_direct(do_pore_transport=do_pore_transport)
# ...by adding inhibition of Bax by Bcl2,
bind(Bax(state='A', s1=None, s2=None), Bcl2, [5e6/(N_A*V), 0.001])
# ...associated displacement reactions
displace_reversibly(Bax(active_monomer), Bid(state='T'), Bcl2,
[5e6/(N_A*V), 0.001])
displace_reversibly(Bad(state='M'), Bax(active_monomer), Bcl2,
[1e5/(N_A*V), 0.005])
# ...and degradation of the active Bax:Bcl2 complex
degrade(Bax(bf=1) % Bcl2(bf=1), 0.005)
[docs]def cui_direct2(do_pore_transport=False):
"""The "direct 2" model drawn from [Cui2008]_.
Builds on the "direct 1" model from [Cui2008]_, implemented
in :py:func:`cui_direct1` (see source code).
Parameters
----------
do_pore_transport : True or False (default)
As for :py:func:`chen_biophys_j`.
"""
alias_model_components()
# Build on the "direct 1" model...
cui_direct1(do_pore_transport=do_pore_transport)
# By adding simultaneous auto-activation and dimerization of Bax
Rule('Bax_autoactivation_dimerization',
Bax(state='A', bf=None, s1=None, s2=None) +
Bax(state='C', bf=None, s1=None, s2=None) >>
Bax(state='A', bf=None, s1=1, s2=None) %
Bax(state='A', bf=None, s1=None, s2=1),
Parameter('Bax_autoactivation_dimerization_k', 2e5/(N_A*V)))
[docs]def howells(do_pore_assembly=True, do_pore_transport=False):
"""The model drawn from [Howells2011]_.
This model builds on the model from [Chen2007biophysj]_,
implemented in :py:func:`chen_biophys_j`. The core reactions from the Chen
et al. model are the same, but Howells et al. modify some parameter values
and add a number of Bad-related reactions, including (see source code):
* Unphosphorylated Bad spontaneously translocates between cytosol and
mitochondria
* Bad binds Bcl-2
* Bad displaces tBid from Bcl-2
* Cytosolic, mitochondrial, and Bad in a mitochondrial Bad:Bcl2 complex
can be phosphorylated at various rates (this is modeled as a first-order
reaction with no explicit representation of kinases)
* Bad can be sequestered by, and released from, 14-3-3 domains in the
cytosol (modeled as a first-order reaction with no explicit
representation of 14-3-3-domain-containing proteins)
Parameters
----------
do_pore_assembly : True (default) or False
As for :py:func:`chen_biophys_j`.
do_pore_transport : True or False (default)
As for :py:func:`chen_biophys_j`.
"""
# Build on the model from [Chen2007biophysj]_:
chen_biophys_j(do_pore_assembly=do_pore_assembly,
do_pore_transport=do_pore_transport)
alias_model_components()
# Override a few parameter values from the pre-existing model
bind_BidT_Bcl2_kr.value = 2e-3 # was 4e-2 in Chen 2007 Biophys J
bind_BaxA_Bcl2_kr.value = 2e-3 # was 1e-3 in Chen 2007 Biophys J
spontaneous_pore_BaxA_to_Bax4_kf.value = 2000e6*4/(N_A*V)
# was 2e6 in Chen 2007 B.J.
spontaneous_pore_BaxA_to_Bax4_kr.value = 5e-5 # was 0 in Chen 2007 B.J.
# Translocation equilibrium between unphosphorylated cytosolic and
# mitochondrial Bad
equilibrate(Bad(state='C', serine='U', bf=None),
Bad(state='M', serine='U', bf=None), [1e-2, 2e-3])
# Bad binds Bcl2
bind(Bad(state='M'), Bcl2, [15e6/(N_A*V), 2e-3])
# Bad displaces tBid from Bcl2 (parameter `k_tBid_rel1` in paper)
displace(Bad(state='M'), Bid(state='T'), Bcl2, 5e6/(N_A*V))
# Phosphorylation of Bad
phosphorylate_Bad_k1 = Parameter('phosphorylate_Bad_k1', 1e-3)
phosphorylate_Bad_k2 = Parameter('phosphorylate_Bad_k2', 1e-4)
Rule('phosphorylate_BadCU_to_BadCP', # Cytosolic Bad
Bad(state='C', serine='U') >> Bad(state='C', serine='P'),
phosphorylate_Bad_k1)
Rule('phosphorylate_BadMU_to_BadCP', # Mitochondrial Bad
Bad(state='M', serine='U', bf=None) >>
Bad(state='C', serine='P', bf=None),
phosphorylate_Bad_k1)
Rule('phosphorylate_BadMUBcl2_to_BadCP', # Mitochondrial Bad:Bcl2
Bad(state='M', serine='U', bf=1) % Bcl2(bf=1) >>
Bad(state='C', serine='P', bf=None) + Bcl2(bf=None),
phosphorylate_Bad_k2)
# Sequester phospho-Bad by "binding" 14-3-3 domains (parameter `k_BAD_seq`)
Rule('sequester_BadCP_to_BadC1433',
Bad(state='C', serine='P') >> Bad(state='C', serine='B'),
Parameter('sequester_BadCP_to_BadC1433_k', 1e-3))
# Release of Bad from 14-3-3 domains (parameter `k_BAD_rel`)
Rule('release_BadC1433_to_BadCU',
Bad(state='C', serine='B') >> Bad(state='C', serine='U'),
Parameter('release_BadC1433_to_BadCU_k', 8.7e-4))