ctl.ControlSBML¶
controlSBML provides ways to use an SBML model to construct an
object representing a system
model that can be used by the control package.
Two kinds of control objects can be constructed.
The first,
control.NonlinearIOSystem,
wraps an entire nonlinear SBML model.
This allows the control package to do the same kind of detailed
simulations that are provided by SBML simulators as as libroadrunner
and Copasi.
The second object,
control.StateSpace, provides a linear approximation to the SBML model.
control.NonlinearIOSystem and
control.StateSpace objects are constructed from an
ctl.ControlSBML object.
In the sequel, we use the following Antiimony representation of an SBML model.
1SIMPLE_MODEL = """
2 species E1;
3 J1: S1 -> S2; S1 + E1
4 S1 = 10; S2 = 0; E1 = 1;
5"""
Constructors¶
We begin with constructing a ctl.ControlSBML object.
This requires having a representation of an SBML model.
This can be an XML file, an XML URL, an antimony file,
or a libroadrunner object.
We refer to any of these representations of the SBML model as
a model reference.
The following constructs ctl.ControlSBML object for this model.
ctlsb = ctl.ControlSBML(SIMPLE_MODEL)
This object has a number of useful properties.
ctlsb.antimonyis the Antimony string that corresponds to the model reference in the constructor.ctlsb.roadrunneris thelibroadrunnerobject for the model reference in the constructor.ctlsb.state_seris apandasSeriesthat provides the values of the concentrations of floating species (the state variables).ctlsb.setTime(time)runs the simulation from time 0 to a desired time. This updatesctlsb.state_ser.
To create an object that is more useful for control analysis, you should specify at least one input and at least one output. An input is a chemical species that can be manipulated by increasing or decreasing its value. An output is a chemical species or reaction flux that can be read. An example of this constructor is:
ctlsb = ctl.ControlSBML(SIMPLE_MODEL,
input_names=["E1"], output_names=["S2"])
Note that both input_names and output_names
are lists of strings.
Inputs and outputs must be specified to make use of
subsequent capabilities of ctl.ControlSBML.
control.NonlinearIOSystem¶
The method ctl.ControlSBML.makeNonlinearIOSystem constructs
a control.NonlinearIOSystem object for an SBML model.
The control.NonlinearIOSystem object provides a way to use
many of the capabilities of the control system library.
For example,
ctlsb = ctl.ControlSBML(SIMPLE_MODEL,
input_names=["E1"], output_names=["S1", "S2"])
sys = ctlsb.makeNonlinearIOSystem("simple")
sys is a control.NonlinearIOSystem object,
and the following simulates this system for 5 s.
times = [0.1*n for n in range(51)]
time_response = control.input_output_response(sys,
times, X0=ctl.makeStateVector(sys))
ctlsb is constructed to have the input E1 and the outputs S1 and S2.
sys is a control.NonlinearIOSystem object
that wraps the SBML model.
time_response is a control.TimeResponseData object.
The simulation requires knowlege of initial values for all state variables,
which is provided by the method ctl.makeStateVector.
Going a bit further, we introduce a plotting function for
the control.TimeResponseData object.
1def plotTimeResponse(time_response, output_names,
2 is_legend=True, stmts=None):
3 # Plots the results of running a simulation
4 outputs = time_response.outputs
5 times = time_response.time
6 colors = ["orange", "green"]
7 for idx in range(len(output_names)):
8 if np.ndim(outputs) > 1:
9 plt.plot(times, outputs[idx,:], c=colors[idx])
10 else:
11 plt.plot(times, outputs, c=colors[idx])
12 if is_legend:
13 _ = plt.legend(output_names)
14 if stmts is None:
15 stmts = []
16 for stmt in stmts:
17 exec(stmt)
18 plt.xlabel("time")
19 plt.ylabel("concentration")
We execute the statement below to plot the simulation results.
plotTimeResponse(time_response, ["S1", "S2"])
control.StateSpace¶
A state space model is a linear system of differential equations in which there are \(n\) states, \(p\) inputs, and \(q\) outputs.
where:
\({\bf x}\) is the state variable, \({\bf u}\) is the input vector, and \({\bf y}\) is the output.
controlSBML constructs a control.StateSpace
object for an SBML model as follows.
The state variables are
floating species.
The \({\bf u}\) are names of floating
species that are manipulated inputs (input_names).
The \({\bf y}\) are the names
of measured outputs (output_names), either
floating species or names of reactions whose fluxes are output.
A
linear approximation for an SBML model is constructed
using the Jacobian of the state variables at a specified operating point.
The operating point is a simulation time at which state variables are assigned their values
to calculate the Jacobian.
Once a ctl.ControlSBML object has been constructed,
the method makeStateSpace is used to create
a control.StateSpace object.
This is illustrated below to construct a control.StateSpace object using
time 0 as the operating point.
ctlsb = ctl.ControlSBML(SIMPLE_MODEL,
input_names=["S1"], output_names=["S2"])
state_space = ctlsb.makeStateSpace(time=0)
The resulting state space model is represented below.
\({\bf x}\) is a 3 dimensional vector
that correspond to the state variables (floating species)
E1, S1, and S2.
\(u\) and \(y\) are scalars (and so
are not in bold).
\({\bf A}\) is in the upper left;
\({\bf B}\) is in the upper right;
and \({\bf C}\) is in the lower left.
\({\bf A}\) is A
\(3 \times 3\) matrix;
\({\bf B}\) is a \(3 \times 1\) matrix;
and \({\bf C}\) is \(1 \times 3\).
We can construct a transfer function from a control.StateSpace
object.
The transfer function for the above system is obtained by
transfer_function = control.tf(state_space)
and is displayed as
The DC gain for this transfer function is \(\infty\).
This makes sense since by having
a unti input for times \(\geq 0\) and
a single reaction that consumes S1 to produce S2,
the output increases without bound.
Now consider a slightly different reaction network.
1model = """
2 J1: S1 -> S2; S1
3 J2: S2 -> S1; S2
4 J3: S2 -> ; k*S2
5 S1 = 10; S2 = 0;
6 k = 0.8
7"""
8
9ctlsb = ctl.ControlSBML(model,
10 input_names=["S1"], output_names=["S2"])
11state_space = ctlsb.makeStateSpace()
The state space matrices are:
We simulate and plot the response of the state space model
to a unit step in the input in S1.
1times = [0.1*n for n in range(301)]
2ss_time_response = control.forced_response(state_space,
3 times, X0=[10, 0], U=1)
4plotTimeResponse(ss_time_response, ["S2"], is_legend=False)
5plt.plot([0, 30], [1.25, 1.25], linestyle="--")
The transfer function is
and so the DC gain is \(1/0.8=1.25\), which is consistent with the plot.