librelist archives

« back to archive

Using aliases in rule patterns

Using aliases in rule patterns

John Bachman
2013-03-14 @ 16:42

I thought I would post to touch on a functionality of PySB that we
didn't have a chance to describe in the manuscript and that we have
not yet described in the online documentation. It's usefulness should
be apparent to modelers currently using BNG/Kappa. We call this
functionality "aliases". Technically speaking, it's just the practice
of storing parts of rule expressions in variables to eliminate
redundancy. One can break this functionality down into three types:
keyword aliases, monomer pattern aliases, and complex pattern aliases.

1. Keyword Aliases

In rule definitions it is very often the case that a rule pattern will
contain a number of sites/states that are repeated over and over but
can nevertheless not be omitted. Suppose you want to describe the
process of oligomerization of the protein Bax to form a ring-shaped
pore in the mitochondrial membrane. The monomer signature of Bax
includes four sites: 's1' and 's2' for binding (to neighboring Bax
molecules), a 'loc' site (to specify location, e.g. 'c' for cytosol or
'm' for mitochondrial) and a site 'active' which is either 'y' (yes)
or 'n' (no).

Since only mitochondrially-localized, activated Bax can oligomerize, a
dimerization rule pattern might look like this (PySB syntax):

Bax(s1=None, loc='m', active='y') + Bax(s2=None, loc='m', active='y')
<> Bax(s1=1, loc='m', active='y') % Bax(s2=1, loc='m', active='y')

This is where aliases come in. Every rule pattern contains the
"loc='m', active='y'" site/state combination. Since site/state
specifications are Python keyword arguments, we can store this set of
args in a dict and reuse them in the rule pattern, as follows:

active_at_mito = {'loc': 'm', 'active': 'y'}
Bax(s1=None, **active_at_mito) + Bax(s2=None, **active_at_mito) <>
Bax(s1=1, **active_at_mito) % Bax(s2=1, **active_at_mito)

This particular example doesn't reduce the overall character count
very much, but the re-use of the site/states dict makes it clear at a
glance that all Bax monomers in the rule share this site/state
combination, and also allows us to apply the semantic name
"active_at_mito" for that combination.

2. Using MonomerPattern Aliases

There's another way to rewrite the rule we wrote above, in which we
instead use aliases for a monomer pattern rather than for site/state
args. In this case we write the monomer pattern for a particular
combination of sites/states and store it in a variable:

Bax_act_mito = Bax(loc='m', active='y')

Bax_act_mito now has as its value an instance of a MonomerPattern
object. Since MonomerPatterns can also be called with site/state
keywords to return new MonomerPatterns, we can re-write the
dimerization rule as:

Bax_act_mito(s1=None) + Bax_act_mito(s2=None) <> Bax_act_mito(s1=1) %

If you are building many rules that operate on activated,
mitochondrial Bax, the use of these types of aliases can make models
more concise and improve clarity substantially.

3. Using ComplexPattern Aliases

Aliases can also be used to store references to patterns for large
complexes, i.e., instances of ComplexPattern objects. Suppose you have
rules that result in the formation of a Bax tetramer:

Bax(s1=1, s2=4, loc='m', active='y') % Bax(s1=2, s2=1, loc='m',
active='y') % Bax(s1=3, s2=2, loc='m', active='y') % Bax(s1=4, s2=3,
loc='m', active='y').

This is for a complex with four elements; certainly there may be cases
where one wishes to operate on larger and more verbose complexes. Now
suppose you want to write rules that operate on this tetramer, e.g.,
synthesis and degradation rules. Instead of rewriting the whole
complex specification twice (once for the synthesis rule and once for
the degradation rule) you can instead assign the complex pattern to a

Bax_tetramer = Bax(s1=1, s2=4, loc='m', active='y') % Bax(s1=2, s2=1,
loc='m', active='y') % Bax(s1=3, s2=2, loc='m', active='y') %
Bax(s1=4, s2=3, loc='m', active='y').

Then write the synthesis and degradation rules, or better yet, use macros:

synthesize(Bax_tetramer, k_syn)
degrade(Bax_tetramer, k_deg)

I hope some of you will find this useful. We'll also work a version of
this into the tutorial.