librelist archives

« back to archive

allowing "refinement" on ComplexPatterns

allowing "refinement" on ComplexPatterns

Jeremy Muhlich
2013-06-05 @ 16:13
In my recent work building a model involving protein cleavage 
(Caspase-8), I found it useful to represent the two cleavage products as 
Monomers, and the whole protein as a complex. However there is another 
protein in the system (FLIP/CFLAR) that binds to the upstream adaptor 
(FADD) in the same way and can participate in some of the same 
reactions. Thus I wanted to create some kind of entity that represented 
the whole Caspase-8 protein complex yet could be refined with site 
conditions for use in patterns just like the FLIP Monomer.

The solution I came up with was to implement the __call__ operator for 
ComplexPatterns. It will throw an exception if the ComplexPattern you 
apply it to has more than one MonomerPattern of the same Monomer, or if 
any of the sites you list in the refinement are not unique across all 
its MonomerPatterns. For example here is how I defined Caspase-8 and 
FLIP (and Bid):

Monomer('C8_ded', ['dr', 'peptide_c'])
Monomer('C8_cat', ['d', 'bid', 'peptide_n'])
Monomer('Flip', ['dr', 'd', 'bid'])
Monomer('Bid', ['enzyme'])

C8_ded represents the "death effector domain" subunit of Caspase-8, and 
C8_cat the catalytic subunit (p18-p10). The peptide_c and peptide_n 
sites are where the two subunits are bound to form the complete protein. 
The dr site on C8_ded and Flip binds the death receptor "above", and the 
bid site binds Bid "below". The d site is where dimerization can occur, 
for all three possible pairings of C8 and Flip. The enzyme site on Bid 
is where its enzyme (either C8_cat or Flip) binds (the "truncated" state 
of Bid is omitted here for brevity).

With the new feature, I can create a C8 alias and then use it just like 

C8 = C8_ded(peptide_c=99) % C8_cat(peptide_n=99)
Rule('bind_C8_Bid', C8(bid=None) + Bid(enzyme=None) <> C8(bid=1) + 
Bid(enzyme=1), ...)
Rule('bind_Flip_Bid', Flip(bid=None) + Bid(enzyme=None) <> Flip(bid=1) + 
Bid(enzyme=1), ...)

In fact the actual model also had FlipS (which lacks the d and Bid 
sites) and we generate the rules they have in common with a loop over 

Note that the alias uses a "weird" bond number, 99. This is so that bond 
will "stay out of the way" of any bonds introduced in refinements. This 
is one part of the implementation I'm not happy about. Refinement could 
potentially renumber any "new" bonds to start above existing ones so the 
alias could just use bond 1 to start with, but that would effectively 
disallow aliases with half bonds that get completed in a later pattern 
construction. For example:

C8_half = C8_cat(peptide_n=None, d=1)
Rule(... C8_half % C8_half ...)
Rule(... C8_half % SomethingElse(d=1) ...)

Also if you declare an initial condition with this C8 alias, you'll run 
into an old PySB bug during network generation -- PySB doesn't normalize 
bond numbers in patterns, leading to failure to recognize some patterns 
read back in from BNG (Issue #13 on github). This bug can potentially be 
triggered by any initial condition with a complex, but it will 
definitely trigger here because BNG renormalizes bonds in a pattern to 
start with 1 and only go as high as necessary, so the 99 will definitely 
be changed to some other number.

This feature is currently available in the master branch on github. I 
welcome any feedback or ideas on how to improve it.

  -- Jeremy