In [7]:
%matplotlib inline
from __future__ import print_function, division
import os.path
import antimony
def _checkAntimonyReturnCode(code):
""" Helper for checking the antimony response code.
Raises Exception if error in antimony.
:param code: antimony response
:type code: int
"""
if code < 0:
raise Exception('Antimony: {}'.format(antimony.getLastError()))
def a2sbml(ant):
""" Convert Antimony to SBML string.
:param ant: Antimony string or file
:type ant: str | file
:return: SBML
:rtype: str
"""
if os.path.isfile(ant):
code = antimony.loadAntimonyFile(ant)
else:
code = antimony.loadAntimonyString(ant)
_checkAntimonyReturnCode(code)
mid = antimony.getMainModuleName()
return antimony.getSBMLString(mid)
In [28]:
# reversible reaction '->'
a2sbml("""
model reaction_rev
J0: S1 + E -> ES; k1*k2*S1*E - k2*ES;
k1 = 3; k2 = 1.4;
S1 = 30.4; E = 1.2; ES = 2.1;
end
""");
# irreversible reaction '=>'
a2sbml("""
model reaction_rev
J0: S1 + E => ES; k1*k2*S1*E;
k1 = 3; k2 = 1.4;
S1 = 30.4; E = 1.2; ES = 2.1;
end
""");
In [30]:
s = a2sbml("""
model example
S + E -> ES;
end
""");
# reuse model
a2sbml("""
model example
S + E -> ES;
end
model example2
example();
end
""");
In [31]:
# set values in the included model
a2sbml("""
model example
S + E -> ES;
end
model example2
A: example();
A.S = 3;
end
""");
In [32]:
# more complex model composition
a2sbml("""
model example
S + E -> ES;
end
model example2
A: example();
A.S = 3;
end
model example3
A: example();
B: example();
C: example2();
end
""");
In [33]:
# use species defined in submodules in new reactions
s = a2sbml("""
model example
S + E -> ES;
end
model example4
A: example();
A.S -> ; kdeg*A.S;
end
""");
When combining multiple submodules, you can also 'attach' them to each other by declaring that a species in one submodule is the same species as is found in a different submodule by using the is
keyword.
In [34]:
s = a2sbml("""
model side_reaction
J0: S + E -> SE; k1*k2*S*E - k2*ES;
S = 5; E = 3;
SE = E+S;
k1 = 1.2; k2 = 0.4;
end
model full_reaction
A: side_reaction();
B: side_reaction();
A.S is B.S;
end
""");
If you wanted, you could give the identical species a new name to more easily use it in the full_reaction
module:
In [35]:
a2sbml("""
model side_reaction
J0: S + E -> SE; k1*k2*S*E - k2*ES;
S = 5; E = 3;
SE = E+S;
k1 = 1.2; k2 = 0.4;
end
model full_reaction
var species S;
A: side_reaction();
B: side_reaction()
A.S is S;
B.S is S;
end
""");
In this system, S
is involved in two reversible reactions with exactly the same reaction kinetics and initial concentrations. Let's now say the reaction rate of the second side-reaction takes the same form, but that the kinetics are twice as fast, and the starting conditions are different:
In [36]:
a2sbml("""
model side_reaction
J0: S + E -> SE; k1*k2*S*E - k2*ES;
S = 5; E = 3;
SE = E+S;
k1 = 1.2; k2 = 0.4;
end
model full_reaction
var species S;
A: side_reaction();
A.S is S;
B: side_reaction();
B.S is S;
B.k1 = 2.4;
B.k2 = 0.8;
B.E = 10;
end
""");
Finally, we add a third side reaction, one in which S binds irreversibly, and where the complex it forms degrades. We'll need a new reaction rate, and a whole new reaction as well:
In [37]:
a2sbml("""
model side_reaction
J0: S + E -> SE; k1*k2*S*E - k2*ES;
S = 5; E = 3;
SE = E+S;
k1 = 1.2; k2 = 0.4;
end
model full_reaction
var species S;
A: side_reaction();
A.S is S;
B: side_reaction();
B.S is S;
B.k1 = 2.4;
B.k2 = 0.8;
B.E = 10;
C: side_reaction();
C.S is S;
C.J0 = C.k1*C.k2*S*C.E
J3: C.SE -> ; C.SE*k3;
k3 = 0.02;
end
""");
For convenience and style, modules may define an interface where some symbols in the module are more easily renamed. To do this, first enclose a list of the symbols to export in parentheses after the name of the model when defining it:
In [38]:
a2sbml("""
model side_reaction(S, k1)
J0: S + E -> SE; k1*k2*S*E - k2*ES;
S = 5;
E = 3;
SE = E+S;
k1 = 1.2;
k2 = 0.4;
end
""");
Then when you use that module as a submodule, you can provide a list of new symbols in parentheses:
A: side_reaction(spec2, k2);
In [ ]: