[ top :: introduction :: installation :: tutorial ]

SunlightCBM
SourceForge.net Logo


SunlightCBM is intended to be used inside a modern unix environment, such as the GNU/Linux operating system.  Here we present examples using two simple networks, simple_network.xml and simple_network_with_ext.xml, and some examples of working with genome-scale models.

Inspecting model contents

The SBML model in simple_network.xml describes the following network :

name
reaction
explanation
EX_A
A ↔ exchange reaction for A
R1
2 A → B first internal reaction
R2
2 B → C second internal reaction
biomass
(0.2) B + (0.3) C → biomass demand reaction

Everything is happening in a single compartment, the cytosol (see later for a generalisation).  This is a very schematic model for anabolism.  Although you can view (and edit) simple_network.xml in a text editor, the SunlightCBM perl scripts inspect.pl and export.pl allow the contents of the model to be easily extracted :

% perl inspect.pl simple_network.xml
Simple network (simple_network), compartments = 1, metabolites = 3, reactions = 4

In here '% ' represents the command line prompt.

More details can be retrieved using various options :

% perl inspect.pl simple_network.xml --compartments
[c]     Cytosol


% perl inspect.pl simple_network.xml --metabolites
A_c     A       Cytosol species-A_C123H938O11N7P2SR
B_c     B       Cytosol species-B_C12H45OP2Zn
C_c     C       Cytosol species-C_FeZn3Co


% perl inspect.pl simple_network.xml --reactions
EX_A    exchange reaction for A [c] : A <==>
R1      first internal reaction [c] : (2) A --> B
R2      second internal reaction        [c] : (2) B --> C
biomass biomass demand reaction [c] : (0.2) B + (0.3) C -->


This first is a tab-delimited list of the compartment abbreviations and full names.  The second is a tab-delimited list comprising: the compartmentalised metabolite abbreviation (this is where the compartment abbreviations come in); the metabolite abbreviation without compartmentalisation; the name of the compartment; and a descriptive name of the metabolite.  The third is a tab-delimited list comprising: the reaction abbreviation (this is used to identify fluxes), a descriptive name for the reaction, and a schematic of the actual reaction following the format promoted by Palsson group.

You might notice the full metabolite names end with atomic formulae.  This is a convention adopted in some of the SBML models from the Palsson group (in the present case the formulae are hypothetical).  The extra option --with-formulae can be used to extract this information :

% perl inspect.pl simple_network.xml --metabolites --with-formulae
A_c     A       Cytosol species-A       C123H938O11N7P2SR       2688    1079
B_c     B       Cytosol species-B       C12H45OP2Zn     205     58
C_c     C       Cytosol species-C       FeZn3Co 0       0


Here the additional columns are the atomic formula, the atomic weight (currently ignoring metal ions), and the number of atoms (also ignoring metal ions).

The difference between inspect.pl and export.pl is that the former can handle more than one SBML file at a time (try it!), and the latter can export a model to cytoscape files taking account of flux bounds (an example is shown below).  Use the --help option for more details. 

Model optimisation

Now let's run a single optimisation (in fact the same one as used to test the installation) :

% perl singleopt.pl simple_network.xml "EX_A=(-10,--)"
6.25


This specifies that the SBML model is contained within simple_network.xml and that the flux bounds for the exchange reaction EX_A should have a minimum value -10, and an unchanged maximum value (of ∞).  By default, the script seeks out the reaction name which matches the name 'biomass' and maximises the flux through that reaction.  It then returns this value of the maximum flux, in this case 6.25. 

Here it is again, using --verbose to get more information :

% perl singleopt.pl simple_network.xml "EX_A=(-10,--)" --verbose
SunlightCBM (ParseSBML): Extracted model Simple network (simple_network) successfully
SunlightCBM (ReadSBMLAndBounds): from command line, EX_A = (-10, Infinity)
SunlightCBM (FindTarget): Maximising flux through 'biomass demand reaction' reaction (biomass)
SunlightCBM (Initialise): LP initialised for 3 x 4 problem
glp_simplex: original LP has 3 rows, 4 columns, 7 non-zeros
glp_simplex: presolved LP has 2 rows, 2 columns, 4 non-zeros
lpx_adv_basis: size of triangular part = 2
*     0:   objval =   0.000000000e+00   infeas =   0.000000000e+00 (0)
*     1:   objval =   6.250000000e+00   infeas =   0.000000000e+00 (0)
OPTIMAL SOLUTION FOUND
SunlightCBM (SolveProblem): maximise biomass, solution was optimal, result was 6.250000
6.25


Here it is again, this time with the actual fluxes :

% perl singleopt.pl simple_network.xml "EX_A=(-10,--)" --fluxes
EX_A    -10     -0.625  non-basic, at lower bound       exchange reaction for A
R1      5       0       basic   first internal reaction
R2      1.875   0       basic   second internal reaction
biomass 6.25    0       basic   biomass demand reaction


The various columns are: flux (col 2), reduced cost (col 3), status in LP terminology (col 4), and name (col 5).  The reduced cost for a reaction gives the rate at which the target function (in this case the flux through the biomass demand reaction) increases per unit flux increase through that reaction.   Reduced costs are discussed briefly in Palsson's book.

The tab-delimited output can be captured and read into your favourite spreadsheet program, or filtered for further analysis.  For example, the output below is piped into a gawk command, which splits each line into fields by tabs (the -F "\t" option), then prints out the first two fields ($1 and $2) as a string (%s), followed by a tab (\t), followed by a numeric value (%f) and carriage return (\n) :

% perl singleopt.pl simple_network.xml "EX_A=(-10,--)" --fluxes | gawk -F "\t" '{ printf "%s\t%f\n", $1, $2 }'
EX_A    -10.000000
R1      5.000000
R2      1.875000
biomass 6.250000


Finally, here are the shadow prices (one could use the option --with-formulae here too) :

% perl singleopt.pl simple_network.xml "EX_A=(-10,--)" --shadows
A_c     A       Cytosol 0.625   species-A-C123H938O11N7P2SR
B_c     B       Cytosol 1.25    species-B-C12H45OP2Zn
C_c     C       Cytosol 2.5     species-C-FeZn3Co


Note that the shadow prices double from A to B to C, and the reduced cost for the A exchange reaction (EX_A) is exactly minus the shadow price for A.  This is generally true, since reducing the flux through the exchange reaction is the same as making the associated metabolite more available.  The shadow prices can be determined also by direct solution of the dual problem :

% perl dualopt.pl simple_network.xml "EX_A=(-10,--)" -shadows
A_c     A       Cytosol 0.625   basic   species-A-C123H938O11N7P2SR
B_c     B       Cytosol 1.25    basic   species-B-C12H45OP2Zn
C_c     C       Cytosol 2.5     basic   species-C-FeZn3Co


The result is the same as solving the primal (ie original) problem.  The new column gives the status of the dual variables in LP terminology.  Here is the dual solution again again, with some more information about what is happening :

% perl dualopt.pl simple_network.xml "EX_A=(-10,--)" --verbose
SunlightCBM (ParseSBML): Extracted model Simple network (simple_network) successfully
SunlightCBM (ReadSBMLAndBounds): from command line, EX_A = (-10, Infinity)
SunlightCBM (FindTarget): Maximising flux through 'biomass demand reaction' reaction (biomass)
SunlightCBM (InitialiseDual): LP initialised for 4 x 3 problem
SunlightCBM (SetDualBounds): identified exchange reaction = EX_A
SunlightCBM (SetDualBounds): corresponding scale factor = 10
SunlightCBM (SetDualBounds): target = shadow price for A [Cytosol]
glp_simplex: original LP has 4 rows, 3 columns, 7 non-zeros
glp_simplex: presolved LP has 3 rows, 3 columns, 6 non-zeros
lpx_adv_basis: size of triangular part = 3
      0:   objval =   0.000000000e+00   infeas =   1.000000000e+00 (0)
      2:   objval =   6.250000000e-01   infeas =   0.000000000e+00 (0)
OPTIMAL SOLUTION FOUND
SunlightCBM (SolveProblem): minimise A_c, solution was optimal, result was 0.625000
dualopt.pl: corresponding maximised biomass flux was 6.25
0.625


Note that the direct solution of the dual problem is currently set up to work only when there is a single limiting exchange reaction, since that can be used to identify a unique metabolite shadow price as the target.  Also, the final output of the script is the shadow price for the target metabolite.

Now let's look at some examples where the LP problem does not have a finite solution.  Here's what happens if the growth rate is unbounded, both without and with the --verbose option :

% perl singleopt.pl simple_network.xml "EX_A=(-Infinity,--)"
perl singleopt.pl: flux unbounded, when maximising biomass
Infinity

% perl singleopt.pl simple_network.xml "EX_A=(-Infinity,--)" --verbose
SunlightCBM (ParseSBML): Extracted model Simple network (simple_network) successfully
SunlightCBM (ReadSBMLAndBounds): from command line, EX_A = (-Infinity, Infinity)
SunlightCBM (FindTarget): Maximising flux through 'biomass demand reaction' reaction (biomass)
SunlightCBM (Initialise): LP initialised for 3 x 4 problem
glp_simplex: original LP has 3 rows, 4 columns, 7 non-zeros
PROBLEM HAS NO DUAL FEASIBLE SOLUTION
SunlightCBM (SolveProblem): turning presolver off temporarily
*     0:   objval =   0.000000000e+00   infeas =   0.000000000e+00 (3)
*     3:   objval =   0.000000000e+00   infeas =   0.000000000e+00 (0)
PROBLEM HAS UNBOUNDED SOLUTION
SunlightCBM (SolveProblem): maximise biomass
SunlightCBM (SolveProblem): solution was unbounded (GLP_UNBND), result was Infinity
singleopt.pl: flux unbounded, when maximising biomass
Infinity


Here's what happens if the problem is infeasible, again without and with the --verbose option :

% perl singleopt.pl simple_network.xml "EX_A=(10,--)"
perl singleopt.pl: failed when maximising biomass
Undefined

% perl singleopt.pl simple_network.xml "EX_A=(10,--)" --verbose
SunlightCBM (ParseSBML): Extracted model Simple network (simple_network) successfully
SunlightCBM (ReadSBMLAndBounds): from command line, EX_A = (10, Infinity)
SunlightCBM (FindTarget): Maximising flux through 'biomass demand reaction' reaction (biomass)
SunlightCBM (Initialise): LP initialised for 3 x 4 problem
glp_simplex: original LP has 3 rows, 4 columns, 7 non-zeros
PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION
SunlightCBM (SolveProblem): turning presolver off temporarily
      0:   objval =   0.000000000e+00   infeas =   1.000000000e+00 (2)
PROBLEM HAS NO FEASIBLE SOLUTION
SunlightCBM (SolveProblem): maximise biomass
SunlightCBM (SolveProblem): no feasible solution existed (GLP_NOFEAS)
SunlightCBM (SolveProblem): no primal feasible solution existed (GLP_NOFEAS)
SunlightCBM (SolveProblem): problem was dual infeasible (GLP_INFEAS)
singleopt.pl: failed when maximising biomass
Undefined

Multicompartment models

The model in simple_network_with_ext.xml is similar to that in simple_network.xml, shown above, except an extracellular compartment has been added, a transporter reaction has been added to allow A to move between the cytosol and the extracellular space, and the exchange reaction now acts on extracellular A :

name
reaction
explanation
EX_A
[e] : A ↔ exchange reaction for A
At
A [e] ↔ A [c]
transport reaction for A
R1
[c] : 2 A → B first internal reaction
R2
[c] : 2 B → C second internal reaction
biomass
[c] : (0.2) B + (0.3) C → biomass demand reaction

The optimal growth solution is basically the same as the previous model :

% perl singleopt.pl simple_network_with_ext.xml "EX_A=(-10,--)" --fluxes
At      10      0       basic   transport reaction for A
EX_A    -10     -0.625  non-basic, at lower bound       exchange reaction for A
R1      5       0       basic   first internal reaction
R2      1.875   0       basic   second internal reaction
biomass 6.25    0       basic   biomass demand reaction


This model allows us to demonstrate some of the features of the SunlightCBM scripts.

Adding and removing metabolites and reactions

The script mogrify.pl allows SBML models to be modified by adding and removing metabolites and reactions.  We will see more extensive use of this in the section discussing genome-scale models.  For the present time, let's add a metabolite (D) and a couple of reactions (A[e] ↔ D[c] and [c] : (2) D → B) to the two-compartment model above.  Tab-delimited text files are used for listing the metabolites or reactions to be added or removed.  The format is the same as the output from inspect.pl, although obviously not all the fields are used.  Note: be careful if using emacs for editing these files, as the tab characters are sometimes replaced by spaces, which is not what you want!  Here is a way of using the 'printf' command for making a short files with strings (%s) separated by tabs (%t) ending in a newline (%n) :

% printf "%s\t%s\t%s\t%s\n" D_c D Cytosol "my new metabolite" > metabs.dat
% printf "%s\t%s\t%s\n" At2 "alternate transport for A" "A[e] <==> D[c]" > rxns.dat
% printf "%s\t%s\t%s\n" R3 "my new internal reaction" "[c] : (2) D --> B" >> rxns.dat

% cat metabs.dat
D_c     D       Cytosol my new metabolite

% cat rxns.dat
At2     alternate transport for A       A[e] <==> D[c]
R3      my new internal reaction        [c] : (2) D --> B


Let's use mogrify.pl to add these to simple_network_with_ext.xml and save the model for future use :

% perl mogrify.pl simple_network_with_ext.xml --add-metabolites=metabs.dat --add-reactions=rxns.dat > new_model.xml

Here is a single optimisation using the new model :

% perl singleopt.pl new_model.xml "EX_A=(-10,--)" --fluxes
At      10      0       basic   transport reaction for A
At2     0       0       non-basic, free (unbounded)     alternate transport for A
EX_A    -10     -0.625  non-basic, at lower bound       exchange reaction for A
R1      5       0       basic   first internal reaction
R2      1.875   0       basic   second internal reaction
R3      0       0       basic   my new internal reaction
biomass 6.25    0       basic   biomass demand reaction


Obviously the added metabolite and reactions merely provide an alternative pathway for the generation of B.  This shows up for instance if we stop the flux through the original transport reaction, re-optimise, and compare the new flux distribution with the one above :

% perl singleopt.pl new_model.xml "EX_A=(-10,--)" At --fluxes
At      10      0       basic   transport reaction for A
At2     0       0       non-basic, free (unbounded)     alternate transport for A
EX_A    -10     -0.625  non-basic, at lower bound       exchange reaction for A
R1      5       0       basic   first internal reaction
R2      1.875   0       basic   second internal reaction
R3      0       0       basic   my new internal reaction
biomass 6.25    0       basic   biomass demand reaction


We exploit the shorthand notation where the name of a reaction by itself as a parameter closes the reaction by setting the flux bounds to (0, 0).

In fact At and At2 are a so-called 'synthetic lethal pair', as the following sequence of single optimisations shows :

% perl singleopt.pl new_model.xml "EX_A=(-10,--)" At
6.25

% perl singleopt.pl new_model.xml "EX_A=(-10,--)" At2
6.25

% perl singleopt.pl new_model.xml "EX_A=(-10,--)" At At2
0


We can also see that there are alternate pathways (strictly speaking alternate optima) in the new model by running a flux variability study.  Here the --prefac=1 option is used to force the flux through the target biomass reaction to be the maximum possible (ie 6.25) :

% perl variability.pl new_model.xml "EX_A=(-10,--)" --prefac=1
At      0       10      bounded transport reaction for A
At2     0       10      bounded alternate transport for A
EX_A    -10     -10     fixed   exchange reaction for A
R1      0       5       bounded first internal reaction
R2      1.875   1.875   fixed   second internal reaction
R3      0       5       bounded my new internal reaction
biomass 6.25    6.25    fixed   biomass demand reaction


The second and third columns give the lower and upper possible values for the flux, the third column gives the status, and the last column the descriptive name of the reaction.  Here, the two transporter reactions and the two alternative routes to synthesis 'B' show up as fluxes with bounded variation reflecting the alternate pathways (the other fluxes are fixed). 

Deleting metabolites and reactions using mogrify.pl follows a similar pattern to adding metabolites and reactions.  Some examples of this are given when genome-scale models are discussed.

One can regenerate an SBML model from the list of metabolites and reactions generated by inspect.pl or export.pl as the following sequence shows :

% perl inspect.pl simple_network.xml --metabolites > metabs.dat

% perl inspect.pl simple_network.xml --reactions > rxns.dat

% perl mogrify.pl --new-model --add-metabolites=metabs.dat --add-reactions=rxns.dat | perl inspect.pl - --all
New Model (new_model), compartments = 1, metabolites = 3, reactions = 4
[c]     Cytosol
A_c     A       Cytosol species-A-C123H938O11N7P2SR
B_c     B       Cytosol species-B-C12H45OP2Zn
C_c     C       Cytosol species-C-FeZn3Co
EX_A    exchange reaction for A [c] : A <==>
R1      first internal reaction [c] : (2) A --> B
R2      second internal reaction        [c] : (2) B --> C
biomass biomass demand reaction [c] : (0.2) B + (0.3) C -->


Note the use of a unix pipe to send the output of mogrify.pl straight into inspect.pl.  The  '-' option makes inspect.pl take its input from stdin.

Renaming compartments

It is possible to rename compartments using mogrify.pl, both in terms of the full compartment name and the abbreviation.  In the convention promoted by the Palsson group, single characters are used for compartment abbreviations (for example 'c' for cytosol, and so on), and these are appended to the metabolite abbreviations with a single underscore ("A_c" for example).  If a model uses this convention, we will say that it is in the standard format.  SunlightCBM extends this, by allowing multicharacter compartment abbreviations.  These are joined to the metabolite abbreviation by a double underscore ("A__cyt" for example).  If a model uses multicharacter compartment abbreviations, we will say that it is in the extended format.

Let's use mogrify.pl to change the abbreviation of the cytosol compartment in simple_network.xml to "cyt", converting the model from standard to extended format in the process :

% perl mogrify.pl simple_network.xml --compartment="Cytosol->cyt" | perl inspect.pl - --all
Simple network (simple_network__), compartments = 1, metabolites = 3, reactions = 4
[cyt]   Cytosol
A__cyt  A       Cytosol species-A-C123H938O11N7P2SR
B__cyt  B       Cytosol species-B-C12H45OP2Zn
C__cyt  C       Cytosol species-C-FeZn3Co
EX_A    exchange reaction for A [cyt] : A <==>
R1      first internal reaction [cyt] : (2) A --> B
R2      second internal reaction        [cyt] : (2) B --> C
biomass biomass demand reaction [cyt] : (0.2) B + (0.3) C -->


Note that a double underscore is also added to the model id (ie "simple_network__").  This is very important, because SunlightCBM uses the presence of a double underscore in the model abbreviation to indicate that a model is in the extended format.

We can also rename the compartment keeping it in standard format, as the following example shows :

% perl mogrify.pl simple_network.xml --compartment="Cytosol->(intracellular,i)" | perl inspect.pl - --all
Simple network (simple_network), compartments = 1, metabolites = 3, reactions = 4
[i]     intracellular
A_i     A       intracellular   species-A-C123H938O11N7P2SR
B_i     B       intracellular   species-B-C12H45OP2Zn
C_i     C       intracellular   species-C-FeZn3Co
EX_A    exchange reaction for A [i] : A <==>
R1      first internal reaction [i] : (2) A --> B
R2      second internal reaction        [i] : (2) B --> C
biomass biomass demand reaction [i] : (0.2) B + (0.3) C -->


These models all perform exactly the same as the original one.  By the way, if you just want to convert a model into the extended format, then use mogrify.pl with the --make-extended option.  Also, when making a new model the extended format can be selected by using the --new-extended-model option.

Labelling

The extended format opens up the possibility of adding labels to models, which can subsequently be joined together in various ways.  More examples are given later for genome-scale models.  Labelling is done with the --label option of mogrify.pl, for example :

% perl mogrify.pl simple_network.xml --label=gut | perl inspect.pl - --all
Simple network (simple_network__gut), compartments = 1, metabolites = 3, reactions = 4
[gut_c]       Cytosol__gut
A__gut_c      A       Cytosol__gut  species-A-C123H938O11N7P2SR
B__gut_c      B       Cytosol__gut  species-B-C12H45OP2Zn
C__gut_c      C       Cytosol__gut  species-C-FeZn3Co
EX_A__gut     exchange reaction for A [gut_c] : A <==>
R1__gut       first internal reaction [gut_c] : (2) A --> B
R2__gut       second internal reaction        [gut_c] : (2) B --> C
biomass__gut  biomass demand reaction [gut_c] : (0.2) B + (0.3) C -->


Obviously many things have been changed in here : the compartment names and abbreviations, the reaction abbreviations, and the model id; uncompartmentalised metabolite abbreviations are not changed, rather the change is made in the compartmentalised metabolite abbreviation.  Although a lot has changed, the model behaves exactly the same as before, as this single optimisation shows (we also illustrate an occasionally useful idiom whereby the --fluxes option is set and the output is piped through grep -i biomass) :

% perl mogrify.pl simple_network.xml --label=gut | perl singleopt.pl - "EX_A__gut=(-10,--)" --fluxes | grep -i biomass
biomass__gut  6.25    0       basic   biomass demand reaction


Note that we have to specify "EX_A__gut" rather than "EX_A".  The labelling of exhange fluxes in this way can be avoided by using the --exclude-exchanges option. 

Further labels can be added, for example here we pipe the output of one call to mogrify .pl into a second call, then inspect the output :

% perl mogrify.pl simple_network.xml --label=gut | perl mogrify.pl - --label=human | perl inspect.pl - --all
Simple network (simple_network__human_gut), compartments = 1, metabolites = 3, reactions = 4
[human_gut_c]   Cytosol__human_gut
A__human_gut_c  A       Cytosol__human_gut      species-A-C123H938O11N7P2SR
B__human_gut_c  B       Cytosol__human_gut      species-B-C12H45OP2Zn
C__human_gut_c  C       Cytosol__human_gut      species-C-FeZn3Co
EX_A__human_gut exchange reaction for A [human_gut_c] : A <==>
R1__human_gut   first internal reaction [human_gut_c] : (2) A --> B
R2__human_gut   second internal reaction        [human_gut_c] : (2) B --> C
biomass__human_gut      biomass demand reaction [human_gut_c] : (0.2) B + (0.3) C -->


The place where the label ends up can be changed with the --postfix option.  It is possible to combine the addition and removal of metabolites and reactions with these compartment renaming and labelling commands although care is advised since all combinations have not been thoroughly tested.  However, using compartment renaming together with labelling is known to work sensibly, as the examples using genome-scale networks show.

Genome-scale models

It has been a deliberate choice not to include genome-scale models with SunlightCBM, since these models more properly belong to the groups who have generated them.  Here we illustrate the use of SunlightCBM with the genome-scale models Ec_iJR904_GlcMM.xml for E. coli, and Sc_iND750_GlcMM.xml for S. cerevisiae.  These are available as Supplementary Data 1 and Supplementary Data 2 from the Nature Protocols article about the COBRA toolbox.  If you use these models in serious work, you should certainly consider citing the following articles :

"An expanded genome-scale model of Escherichia coli K-12 (iJR904 GSM/GPR)", J. L. Reed, T. D. Vo, C. H. Schilling and B. Ø. Palsson, Genome Biology 4, R54.1 (2003).

"Reconstruction and validation of Saccharomyces cerevisiae iND750, a fully compartmentalized genome-scale metabolic model", N. C. Duarte, M. J. Herrgard and B. Ø. Palsson, Genome Research 14, 1298 (2004).

Other versions of these models, and models for other organisms, are available from UCSD's BiGG database.  These do not (typically?) have biomass reactions in them.  There is also a minor but somewhat annoying name differences, for example 'mal-L' in the model exported from BiGG is 'mal_L' in the above SBML models, and so on.  In fact the whole problem of ontology is one which remains to be resolved for these kind of models.

We suppose that you have got the E. coli and S. cerevisiae models somehow, and they are called Ec_iJR904_GlcMM.xml and Sc_iND750_GlcMM.xml.   Let's check these :

% perl inspect.pl Ec_iJR904_GlcMM.xml Sc_iND750_GlcMM.xml
Ec_iJR904_GlcMM.xml: iJR904 (iJR904), compartments = 2, metabolites = 904, reactions = 1075
Sc_iND750_GlcMM.xml: Sc_iND750 (Sc_iND750), compartments = 8, metabolites = 1177, reactions = 1266

(this incidentally shows inspect.pl examining more than one model at once).  If you get something like this then you are probably in good shape for the rest of this section.

These models cannot immediately be used by SunlightCBM.  Firstly the exchange reactions are of the form A[e] ↔ A[b], where the "b" is used to denote a boundary metabolite.  Imposing the flux balance condition on the boundary metabolites would force all the exchange fluxes to zero.  SunlightCBM does not make a special exception for boundary metabolites, therefore they must be removed from the models.  Let's illustrate how this can be done for iJR904 :

% perl inspect.pl Ec_iJR904_GlcMM.xml --metabolites | gawk '$1 ~ /_b$/' > metabs.dat

% perl mogrify.pl Ec_iJR904_GlcMM.xml --remove-metabolites=metabs.dat > new_model.xml


The first command identifies a list of all metabolites in Ec_iJR904_GlcMM.xml whose compartmentalised abbreviations end with "_b"; this is done by filtering the output of inspect.pl with a gawk command.  The second command removes these metabolites from Ec_iJR904_GlcMM.xml to make new_model.xml.  Comparing the old and new models shows that 143 boundary metabolites have gone :

% perl inspect.pl Ec_iJR904_GlcMM.xml new_model.xml
Ec_iJR904_GlcMM.xml: iJR904 (iJR904), compartments = 2, metabolites = 904, reactions = 1075
new_model.xml: iJR904 (iJR904), compartments = 2, metabolites = 761, reactions = 1075


The boundary metabolites are silently dropped from the exchange reactions, but will show up if you run the above mogrify command with the --verbose option.

The second reason why the models cannot be immediately used is that the information they may contain about flux bounds is not used by SunlightCBM.  Rather the flux bounds in SunlightCBM default to (−∞, ∞) for reversible reactions and (0, ∞) for irreversible reactions (exchange reactions default to (0, ∞), unless the --open-exchanges flag is used).  To change these defaults, flux bounds have to be specified separately either in the command line as we have already seen or by reading in tab-delimited text files.  For example, by looking into Ec_iJR904_GlcMM.xml (or otherwise) we find that a number of exchange reactions should be fully open in order for growth to occur.  For convenience we have gathered these into the following tab-delimited text file (some comment lines omitted) :

% cat open_exchanges.dat
 . . .
EX_co2(e)       -Infinity       Infinity
EX_fe2(e)       -Infinity       Infinity
EX_h(e) -Infinity       Infinity
EX_h2o(e)       -Infinity       Infinity
EX_k(e) -Infinity       Infinity
EX_na1(e)       -Infinity       Infinity
EX_nh4(e)       -Infinity       Infinity
EX_pi(e)        -Infinity       Infinity
EX_so4(e)       -Infinity       Infinity
EX_o2(e)        -Infinity       Infinity
 . . .


With these exchanges open, in only remains to specify a carbon/energy source such as glucose which can be done on the command line.  For example, here is iJR904 optimised for growth with the above open exchanges and with glucose uptake limited to 10 mmol / (gDW-hr) :

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)"
0.956973417061644


The result here means that the growth rate is 0.957 / hr, or a doubling time of 60 × ln 2 / 0.957 = 43 minutes.  Here it is again with more output :

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --verbose
SunlightCBM (ParseSBML): Extracted model iJR904 (iJR904) successfully
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_co2(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_fe2(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_h(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_h2o(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_k(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_na1(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_nh4(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_pi(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_so4(e) = (-Infinity, Infinity)
SunlightCBM (ReadBounds): from open_exchanges.dat, EX_o2(e) = (-Infinity, Infinity)
SunlightCBM (ReadSBMLAndBounds): from command line, EX_glc(e) = (-10, Infinity)
SunlightCBM (FindTarget): Maximising flux through 'BiomassEcoli' reaction (BiomassEcoli)
SunlightCBM (Initialise): LP initialised for 761 x 1075 problem
glp_simplex: original LP has 761 rows, 1075 columns, 4503 non-zeros
glp_simplex: presolved LP has 487 rows, 706 columns, 2861 non-zeros
lpx_adv_basis: size of triangular part = 462
*     0:   objval =   0.000000000e+00   infeas =   0.000000000e+00 (25)
*   159:   objval =   9.569734171e-01   infeas =   6.369887142e-10 (8)
OPTIMAL SOLUTION FOUND
SunlightCBM (SolveProblem): maximise BiomassEcoli, solution was optimal, result was 0.956973
0.956973417061644


Two recent publications suggest simple updates to the original iJR904 model :

"Systematic assignment of thermodynamic constraints in metabolic network models", A. Kümmel, S. Panke and M. Heinemann, BMC Bioinformatics 7, 512 (2006).  The authors suggest the reaction 'GALU' is irreversible.

"Genome-scale in silico models of E. coli have multiple equivalent phenotypic states: assessment of correlated reaction subsets that comprise network states", J. L. Reed and B. Ø. Palsson, Genome Research 14, 1797 (2004).  The authors suggest a number of reactions that can be removed to eliminate so-called type III cycles.

We have provided some tab-delimited text files to make it easier to update the iJR904 model along these lines (some comment lines omitted) :

% cat iJR904_rxn_add.dat
 . . .
GALU    UTP-glucose-1-phosphate uridylyltransferase     [c] : g1p + h + utp --> ppi + udpg
 . . .

% cat iJR904_rxn_remove.dat
 . . .
ABUTt2  4-aminobutyrate transport in via proton symport
ACCOAL  acetate-CoA ligase (ADP-forming)
ADK1    adenylate kinase
ADNt2   adenosine transport in via proton symport
ALARi   alanine racemase (irreversible)
CYTDt2  cytidine transport in via proton symport
GALUi   UTP-glucose-1-phosphate uridylyltransferase (irreversible)
GLUt4   Na+/glutamate symport
INSt2   inosine transport in via proton symport
LCADi   lactaldehyde dehydrogenase
PROt4   Na+/Proline-L symporter
SERt4   L-serine via sodium symport
THMDt2  thymidine transport in via proton symport
THRt4   L-threonine via sodium symport
URAt2   uracil transport in via proton symport
URIt2   uridine transport in via proton symport
VPAMT   Valine-pyruvate aminotransferase
 . . .


(In iJR904_scale_factors.dat we also provide a list of the metabolites in iJR904 that represent multiple copies of the actual molecules.) 

These files can be used to make an up-to-date iJR904 model as follows :

% perl mogrify.pl new_model.xml --add-reactions=iJR904_rxn_add.dat --remove-reactions=iJR904_rxn_remove.dat > iJR904.xml

If you use the updated iJR904 model in serious work, you should obviously cite the above two publications in addition to the original one.  For convenience the steps to go from  Ec_iJR904_GlcMM.xml to an updated iJR904 model which works with SunlightCBM have been built into the Makefile.  Thus 'make ec' will make the above file iJR904.xml from Ec_iJR904_GlcMM.xml (using a temporary xml file instead of new_model.xml).  The following shows this in action (assuming iJR904.xml has not yet been generated):

% make ec
perl inspect.pl Ec_iJR904_GlcMM.xml --metabolites | gawk '$1 ~ /_b$/' > metabs.dat
perl mogrify.pl Ec_iJR904_GlcMM.xml --remove-metabolites=metabs.dat > temp.xml
perl mogrify.pl temp.xml --add-reactions=iJR904_rxn_add.dat --remove-reactions=iJR904_rxn_remove.dat > iJR904.xml
rm -f metabs.dat temp.xml

% perl singleopt.pl iJR904.xml open_exchanges.dat "EX_glc(e)=(-10,--)"
0.956973417043535

% perl singleopt.pl iJR904.xml open_exchanges.dat "EX_glc(e)=(-10,--)" ">EX_o2(e)"
0.298843355048565

% perl singleopt.pl iJR904.xml open_exchanges.dat "EX_glc(e)=(-10,--)" "ATPM=(7.6,--)"
0.921948095050457


In these, the first of the optimisations is the one done earlier.  In the second one, growth under anaerobic conditions is simulated - note that the O2 exchange flux overwrites the one in open-exchanges.dat because it occurs later in the command line, and we use another of the shorthand notations to set the flux bounds to (0, ∞).  In the third one, the minimum flux through the non-growth-associated maintenance (NGAM) reaction is forced to be 7.6 mmol / (gDW-hr).  If you are wondering what the reaction ATPM is, then it is easy to find out :

% perl inspect.pl iJR904.xml --reactions | grep ATPM
ATPM    ATP_maintenance_requirement     [c] : atp + h2o --> adp + h + pi


A similar approach can be taken for S. cerevisiae, except that we don't have any reaction updates.  Again for convenience the steps to make a working model have been gathered into the Makefile, as the following sequence shows (this assumes you have Sc_iND750_GlcMM.xml and iND750.xml is not yet generated) :

% make sc
perl inspect.pl Sc_iND750_GlcMM.xml --metabolites | gawk '$1 ~ /_b$/' > metabs.dat
perl mogrify.pl Sc_iND750_GlcMM.xml --remove-metabolites=metabs.dat > iND750.xml
rm -f metabs.dat

% perl singleopt.pl iND750.xml open_exchanges.dat "EX_glc(e)=(-10,--)"
SunlightCBM (ReadBounds): in open_exchanges.dat, didn't find reaction EX_fe2(e) to reset bounds
0.973233759037675


It turns out that the same open_exchanges.dat can be used with iND750 as with iJR904 since the exchange reaction abbreviations are all the same.  As you can see, the only issue is that there is no Fe2+ exchange reaction in iND750.  This results in a warning message but is otherwise ignored.  Again, if you use the iND750 model for serious work, you should cite the original publication.

Advanced topic - joining two models

Using labelling it is relatively easy to join two models together.   The trick is to let the models share a common extracellular compartment.  Here, in outline, is one possible approach :
Here we show how this works in practice, by joining the E. coli and S. cerevisiae models.  The following presumes that you have generated iJR904.xml and iND750.xml as discussed in the previous section.  The following two sequences show the first step, making and testing labelled versions of the models :

% perl mogrify.pl iJR904.xml --label=ecoli --compartment="Extra_organism->(Extra_organism, ext)" --exclude-exchanges > model1.xml

% perl inspect.pl model1.xml --compartments
[ecoli_c]       Cytosol__ecoli
[ext]   Extra_organism

% perl singleopt.pl model1.xml open_exchanges.dat "EX_glc(e)=(-10,--)"
0.956973417043535

% perl mogrify.pl iND750.xml --label=yeast --compartment="Extra_organism->(Extra_organism, ext)" --exclude-exchanges > model2.xml

% perl inspect.pl model2.xml --compartments
[ext]   Extra_organism
[yeast_c]       Cytosol__yeast
[yeast_g]       Golgi_Apparatus__yeast
[yeast_m]       Mitochondria__yeast
[yeast_n]       Nucleus__yeast
[yeast_r]       Endoplasmic_Reticulum__yeast
[yeast_v]       Vacuole__yeast
[yeast_x]       Peroxisome__yeast

% perl singleopt.pl model2.xml open_exchanges.dat "EX_glc(e)=(-10,--)"
SunlightCBM (ReadBounds): in open_exchanges.dat, didn't find reaction EX_fe2(e) to reset bounds
0.973233759037675


Now we extract the metabolites and reactions from both models and concatenate them into single files :

% perl inspect.pl model1.xml --metabolites > metabs.dat

% perl inspect.pl model1.xml --reactions > rxns.dat

% perl inspect.pl model2.xml --metabolites >> metabs.dat

% perl inspect.pl model2.xml --reactions >> rxns.dat

At this point we can make a joint model :

% perl mogrify.pl --new-extended-model --add-metabolites=metabs.dat --add-reactions=rxns.dat > new_model.xml

% perl inspect.pl new_model.xml
New Model (new_model__), compartments = 9, metabolites = 1737, reactions = 2239

We can grow each individual model. 

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --target=/BiomassEcoli/ --fluxes | grep -i biomass
BiomassEcoli__ecoli     0.995789136591818       0       basic   BiomassEcoli
biomass_SC4_bal__yeast  0       -0.801102593636717      non-basic, at lower bound       biomass_SC4_bal

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --target=/biomass_SC4/ --fluxes | grep -i biomass
BiomassEcoli__ecoli     0       -0.889614157459108      non-basic, at lower bound       BiomassEcoli
biomass_SC4_bal__yeast  1.08057548905981        0       basic   biomass_SC4_bal


Interestingly the growth rates are faster in the joint models than they are in the separate models.  The reason is that each organism can use pathways in the other organism.  This can be proved by re-running the models but shutting down the appropriate cytosol-extracellular transporter reactions, in which case the original growth rates are recovered.  We show how this works for the growth of yeast.  First we extract the relevant transport reactions and make a tab-delimited file suitable to shut them down :

% perl inspect.pl new_model.xml --reactions | gawk -F "\t" '$3 ~ /\[ecoli_c\]/ && $3 ~ /\[ext\]/ { printf "%s\t0\t0\n", $1 }' > shutdown_transports.dat

The components of the gawk command here are: an option to break into fields on tabs (-F "\t"); a rule to select lines whose reaction schematic (3rd field) contains both [ecoli_c] and [ext] ($3 ~ /\[ecoli_c\]/ && $3 ~ /\[ext\]/); and an action which prints out the reaction abbreviation (first field) followed by two tab separated zeros as a suitable format for resetting the flux bounds (printf "%s\t0\t0\n", $1).  The result is saved in shutdown_transports.dat.  This contains 192 transporter reactions  :

% wc -l shutdown_transports.dat
192 shutdown_transports.dat

% head -5 shutdown_transports.dat
12PPDt__ecoli   0       0
ACACt2__ecoli   0       0
ACALDt__ecoli   0       0
ACGApts__ecoli  0       0
ACMANApts__ecoli        0       0


Now we recalculate the maximum yeast growth rate including shutdown_transports.dat :

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" shutdown_transports.dat --target=/biomass_SC4/ --fluxes | grep -i biomass
BiomassEcoli__ecoli     0       0       non-basic, at lower bound       BiomassEcoli
biomass_SC4_bal__yeast  0.973233759037701       0       basic   biomass_SC4_bal


The result is the same as the yeast model on its own.  This demonstrates that the E. coli transporter reactions are essential to obtain the higher growth rate of yeast in the joint model.  A similar exercise can be done for the growth of E. coli.

Of course what we really want to do is grow the organisms jointly by combining the biomass reactions.  A trick to do this is to introduce a fake 'biomass' metabolite that is generated by the individual biomass reactions, and consumed by a new joint biomass reaction.  Let's see how to do this, working with the intermediate tab-delimited metabolite and reaction files of the above model.  Using your favourite text editor or otherwise, add the following two lines to metabs.dat :

biomass__ecoli_c   biomass   Cytosol__ecoli   E. coli biomass
biomass__yeast_c   biomass   Cytosol__yeast   S. cerevisiae biomass

If you use cut & paste, please note there are four tab-separated fields here, the last field being a descriptive name.  These lines add two instances of the generic metabolite 'biomass', one for each of the cytosol compartments.  Now, edit the biomass reactions in rxns.dat so that ' + biomass' is added to the right hand sides (note that these reactions are compartmentalised to the individual cytsols), and add a new joint biomass reaction to rxns.dat to consume these :

joint_biomass   Joint biomass   (0.2) biomass[ecoli_c] + (0.8) biomass[yeast_c] -->

Again, if you use cut & paste, note there are 3 tab-separated fields, with the second field being a descriptive name (in this case "Joint biomass") and the third field being the reaction.  The stoichiometry coefficients in here are x = gDW (E. coli) / gDW (total), and 1 − x = gDW (S. cerevisiae) / gDW (total).  We have chosen x = 0.2 arbitrarily here to illustrate the approach. 

Now we can build the model again, and this time optimise for flux through the new joint reaction :

% perl mogrify.pl --new-extended-model --add-metabolites=metabs.dat --add-reactions=rxns.dat > new_model.xml

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --target=joint_biomass --fluxes | grep -i biomass
BiomassEcoli__ecoli     0.21767414605297        0       basic   BiomassEcoli
biomass_SC4_bal__yeast  0.87069658421188        0       basic   biomass_SC4_bal
joint_biomass   1.08837073026485        0       basic   Joint biomass


We see that the fluxes is going through the individual biomass reactions are, respectively, 20% and 80% of the flux through the joint reaction. 

In case you are wondering, the growth rate is the flux through the joint biomass reaction.  The calculation can be repeated as a function of x and the result is shown in the figure below (the perl script scan.pl is set up to do this calculation, but is not part of SunlightCBM as such).  There is a weak maximum growth rate around x = 0.35.

For convenience, the steps to make this joint model both with and without the joint biomass reaction are included in the Makefile, and can be run by typing 'make ec_plus_sc' (the editing of the metabolite and reaction files is done using printf and sed commands; x = 0.12345 is set in the Makefile but can be changed). 

Advanced topic - putting one model inside another one

In a similar way to joining models, it is possible to put one model inside another one.  This can be done by making the extracellular compartment of one model the same as the cytosol of the second model.  Here, in outline, is one possible approach to do this :
We illustrate this by putting E. coli inside S. cerevisiae.  Again, the following presumes that you have generated iJR904.xml and iND750.xml models as discussed previously.  Firstly we make a suitably renamed version of iJR904.xml.

% perl mogrify.pl iJR904.xml --label=ecoli --compartment="Extra_organism->(Cytosol, c)" --exclude-exchanges > model1.xml

% perl inspect.pl model1.xml --compartments
[c]     Cytosol
[ecoli_c]       Cytosol__ecoli

% perl singleopt.pl model1.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --fluxes | grep -i biomass
BiomassEcoli__ecoli     0.956973417043535       0       basic   BiomassEcoli


Now we export the metabolites and reactions (the gawk command in here has the effect of removing the exchange reactions) :

% perl inspect.pl model1.xml --metabolites > metabs.dat

% perl inspect.pl model1.xml --reactions | gawk '$1 !~ /EX_/' > rxns.dat


If we try to import these into iND750.xml, we run into trouble because iND750.xml uses the standard format and does not allow multicharacter compartment abbreviations.  Therefore we should first promote iND750.xml to use the extended format, and check it, as shown here :

% perl mogrify.pl --make-extended iND750.xml > model2.xml

% perl singleopt.pl model2.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --fluxes | grep -i biomass
SunlightCBM (ReadBounds): in open_exchanges.dat, didn't find reaction EX_fe2(e) to reset bounds
biomass_SC4_bal 0.973233759037675       0       basic   biomass_SC4_bal


Now we can do the import :

% perl mogrify.pl model2.xml --add-metabolites=metabs.dat --add-reactions=rxns.dat > new_model.xml

% perl inspect.pl new_model.xml
Sc_iND750 (Sc_iND750__), compartments = 9, metabolites = 1727, reactions = 2181


Again, we can grow both organisms :

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --target=/BiomassEcoli/ --fluxes | grep -i biomass
SunlightCBM (ReadBounds): in open_exchanges.dat, didn't find reaction EX_fe2(e) to reset bounds
BiomassEcoli__ecoli     1.37441367226407        0       basic   BiomassEcoli
biomass_SC4_bal 0       -0.809171045529626      non-basic, at lower bound       biomass_SC4_bal

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --target=/biomass_SC4/ --fluxes | grep -i biomass
SunlightCBM (ReadBounds): in open_exchanges.dat, didn't find reaction EX_fe2(e) to reset bounds
BiomassEcoli__ecoli     0       -1.12345672193585       non-basic, at lower bound       BiomassEcoli
biomass_SC4_bal 1.63247226769719        0       basic   biomass_SC4_bal

In these cases the growth rate of the two components is significantly enhanced over the individual growth rates (but see below), again because one organism can use the pathways in the other organism.  We can verify this for the growth of yeast by shutting down the E. coli transporter reactions, as above.  It doesn't make sense to check the other way though since the yeast transporter reactions are the only way that material can enter the yeast cytosol, and from there the E. coli cytosol.  At this point you might question the lack of an Fe2+ transporter (and possibly other transporters) in the yeast model.  However, it turns out this E. coli model (at least) does not need these 'missing' transporter reactions to grow; if it did then no growth possible.

For the last step we can proceed in a very similar way to the previous section and add fake 'biomass' metabolites to keep track of the two biomass reactions, and a new joint biomass reaction to consume these.  Using your favourite text editor or otherwise, add the following two lines to metabs.dat :

biomass__ecoli_c   biomass   Cytosol__ecoli   E. coli biomass
biomass__c         biomass   Cytosol          S. cerevisiae biomass


These lines add two instances of the generic metabolite 'biomass', one for each of the cytosol compartments.  Now, let's export the yeast biomass reaction to rxns.dat,

% perl inspect.pl iND750__ext.xml --reactions | grep -i biomass >> rxns.dat

and edit the two biomass reactions in rxns.dat so that ' + biomass' is added to the right hand sides (note that these reactions are compartmentalised to the individual cytosols).  Also, add a new joint biomass reaction to consume these :

joint_biomass   Joint biomass   (0.1) biomass[ecoli_c] + (0.9) biomass[c] -->

The stoichiometry coefficients in here are again mass fractions, with x = gDW (E. coli) / gDW (total), and 1 − x = gDW (S. cerevisiae) / gDW (total).  We have chosen x = 0.1 arbitrarily here to illustrate the approach. 

If we rebuild the model and re-optimise we find :

% perl mogrify.pl model2.xml --add-metabolites=metabs.dat --add-reactions=rxns.dat > new_model.xml

% perl singleopt.pl new_model.xml open_exchanges.dat "EX_glc(e)=(-10,--)" --target="joint_biomass" --fluxes | grep -i biomass
SunlightCBM (ReadBounds): in open_exchanges.dat, didn't find reaction EX_fe2(e) to reset bounds
BiomassEcoli__ecoli     0.160238602115474       0       basic   BiomassEcoli
biomass_SC4_bal 1.44214741903927        0       basic   biomass_SC4_bal
joint_biomass   1.60238602115474        0       basic   Joint biomass


We see that the growth rate is apparently considerably faster than yeast on its own.  The growth rate can be calculated as a function of the mass fraction, and the result is shown in the figure below, compared to the case of the previous section (the perl script scan.pl is set up to do this calculation, but is not part of SunlightCBM as such).

compete.png

Growth rates of joined E. coli and S. cerevisiae models, in glucose
minimal media under aerobic conditions.  The glucose uptake rate was set to 10 mmol / (gDW-hr).  The apparent enhancement for E. coli inside S. cerevisiae is an artefact, caused by a short-circuit in the proton gradient across the E. coli cell membrane, allowing for ATP to be regenerated from ADP at no cost.

Apparently the growth rate can be enhanced by up to 60% by inserting E. coli into the yeast cytosol, compared to a maximum of the order 10% if both organisms simply share the extracellular space.  However this is an artefact caused by an unanticipated short-circuit in the proton gradient across the E. coli cell membrane, allowing ATP to be regenerated from ADP through the E. coli ATP synthase reaction at no cost.  This ATP can be used in both compartments (not because there is an ATP transport reaction as such, rather there are unanticipated couplings that effectively allow ATP to pass freely between compartments) thus the growth-associated maintenance reactions in both compartments can be trivially satisfied, freeing up resources to go towards production of biomass, and artificially inflating the growth rate.

To prove this, if we shut down all the exchange reactions the flux through the ATPM reaction in the yeast compartment is still unbounded :

% perl singleopt.pl new_model.xml --close-exchanges --target=ATPM
singleopt.pl: flux unbounded, when maximising ATPM
Infinity

(The same is true for the ATPM reaction in the E. coli compartment.) However the maximum ATPM flux is zero if we additionally shut down the ATP synthase reaction across the E. coli cell membrane,

% perl inspect.pl Ec_in_Sc.xml --reactions | grep ATPS4r
ATPS4r__ecoli    ATP_synthase__four_protons_for_one_ATP_    adp[ecoli_c] + pi[ecoli_c] + (4) h[c] <==> atp[ecoli_c] + (3) h[ecoli_c] + h2o[ecoli_c]

% perl singleopt.pl Ec_in_Sc.xml --close-exchanges ATPS4r__ecoli --target=ATPM
0


It is much more difficult to find a subset of reactions which are responsible for protons leaking across the E. coli cell membrane - this is a research exercise left for the reader!  The fact that an artefact can so easily be generated by joining models illustrates the great care that is needed in the interpretation of the results.

The steps to put iJR904 inside iND750, both with and without a joint biomass reaction, are included in the Makefile for convenience (x = 0.12345 is set in the Makefile but can be changed).  They can be run by typing 'make ec_in_sc'. 

Below is an map of this model illustrated in Cytoscape, obtained using the --cytoscape option of export.pl.


cytoscape.png


Cytoscape map of the joint model of E. coli inside S. cerevisiae (3752 nodes and 4161 edges).  Nodes correspond to both reactions and metabolites but only nodes with fewer than 10 links are shown.



Portions of this site are copyright © 2008-12 Unilever UK Central Resources Ltd
Registered in England & Wales, Company No 29140; Registered Office: Unilever House, Blackfriars, London, EC4P 4BQ, UK.
,