Introduction to BacArena

Microbial communities are essential for global ecosystems and human health. Computational modeling of microbial consortia is thus a major goal in systems biology and microbial ecology. BacArena is a project to simulate bacterial behaviour in communities. A lot of progress is done in the last years to create genome wide metabolic reconstructions of certain organisms, which open a wide field of mathematical analysis. One of this new methods is fux balanced analysis (fba) to estimate optimal metabolic fluxes under certain constraints. Some of these models are available in an exchangeable format (SBML) and can be found in http://bigg.ucsd.edu/. The idea of this project is to use this existing reconstructions and put them in a spatial and temporal environment to study their possible interactions. This is achieved by the combination of agent based modeling with fba. Each bacterium is considered as an agent with individual states, own properties and rules to act. Agents are located on a grid where they can move and interact via metabolic exchanges computed by fba. The starting point for our project is curiosity of what could be done with this huge models. We just throw those models into an arena to see what kind of actions will evolve.

Getting started

Simple simulations with the Escherichia coli core metabolic model

First we have to load the installed package in the workspace with

library("BacArena")
## Loading required package: sybil
## Loading required package: Matrix
## Loading required package: lattice
## Loading required package: ReacTran
## Loading required package: rootSolve
## Loading required package: deSolve
## 
## Attaching package: 'deSolve'
## The following object is masked from 'package:graphics':
## 
##     matplot
## Loading required package: shape

Next we set-up the Escherichia coli core metabolic model

data(Ec_core)
ecore <- Ec_core

The model is already integrated in the sybil R package by default. Alternatively you can also load your own model of interest with commands of the sybil and libSBML. After we loaded the model, we convert it into an object of class Bac by calling its constructor

bac <- Bac(ecore)
## Loading required package: glpkAPI
## using GLPK version 4.60

Now we have to set up an environment in which the organisms can interact

arena <- Arena(n=50, m=50)

Here, by default we chose 50 times 50 as the grid size of the environment and a physical area of 0.25mm times 0.25mm. Next we want to put our created organism in its environment by

arena <- addOrg(arena,bac,amount=1,x=25,y=25)

With this command we added one individual of our bacterium in the middle of the environment (by its x and y position). Next we can add the substances to the environment

arena <- addSubs(arena, smax=0.05, unit='mM', difspeed=6.7e-6) 

Now we added all possible substances to the environment arena with a concentration 0.05 mM per gridcell. Finally, we can start the simulation with

eval <- simEnv(arena,time=10)
## 
## iteration: 1      organisms: 1    biomass: 0.4386933 pg 
##                  count   biomass %
## ecoli_core_model     1 0.4386933 0
##  time total:  0.803  diffusion:  0.584  ( 72.7 %)
## 
## iteration: 2      organisms: 2    biomass: 1.968491 pg 
##                  count  biomass        %
## ecoli_core_model     2 1.968491 348.7169
##  time total:  10.577     diffusion:  10.35  ( 97.9 %)
## 
## iteration: 3      organisms: 4    biomass: 9.501979 pg 
##                  count  biomass        %
## ecoli_core_model     4 9.501979 382.7037
##  time total:  11.339     diffusion:  11.094  ( 97.8 %)
## 
## iteration: 4      organisms: 8    biomass: 49.03067 pg 
##                  count  biomass        %
## ecoli_core_model     8 49.03067 416.0049
##  time total:  12.101     diffusion:  11.806  ( 97.6 %)
## 
## iteration: 5      organisms: 16   biomass: 252.4977 pg 
##                  count  biomass       %
## ecoli_core_model    16 252.4977 414.979
##  time total:  12.758     diffusion:  12.364  ( 96.9 %)
## 
## iteration: 6      organisms: 32   biomass: 1295.407 pg 
##                  count  biomass        %
## ecoli_core_model    32 1295.407 413.0373
##  time total:  12.324     diffusion:  11.734  ( 95.2 %)
## 
## iteration: 7      organisms: 64   biomass: 6596.391 pg 
##                  count  biomass        %
## ecoli_core_model    64 6596.391 409.2137
##  time total:  12.998     diffusion:  11.989  ( 92.2 %)
## 
## iteration: 8      organisms: 121      biomass: 33092.19 pg 
##                  count  biomass        %
## ecoli_core_model   121 33092.19 401.6711
##  time total:  13.01  diffusion:  11.322  ( 87 %)
## 
## iteration: 9      organisms: 204      biomass: 161220.3 pg 
##                  count  biomass        %
## ecoli_core_model   204 161220.3 387.1854
##  time total:  14.554     diffusion:  11.702  ( 80.4 %)
## 
## iteration: 10     organisms: 314      biomass: 745079 pg 
##                  count biomass        %
## ecoli_core_model   314  745079 362.1496
##  time total:  15.483     diffusion:  11.518  ( 74.4 %)

The object eval stores all 10 simulation steps, that we performed. After we retrieve the eval object we can plot now the results of the simulation

plotCurves2(eval)

This will plot the growth curve and curves of substance concentration changes over the 10 simulation steps. If we are interested in the spatial and temporal changes of our constructed population we can use

evalArena(eval,time=10)

This will produce multiple plots one by one for each simulation step with the spatial structure of the population (black dots represent individuals). We can also investigate the spatial change of the population together with the main subtrate glucose

par(mar=c(1,1,1,1))
evalArena(eval,c("Population","EX_glc(e)"),time=10)

Here we only plot the last result of the simulation steps given by the parameter time. At the same time we can also integrate the visualization of different phenotypes into the population

par(mar=c(1,1,1,1))
evalArena(eval,c("Population","EX_glc(e)"),phencol=T,time=10)

Now we can see that the periphery of the population has a different color than the individuals in the center. This indicates that individuals on the outside of the population use a different metabolism (respiration of glucose) than the center (fermentation of glucose and acetate). To visualize the differences of the apparent phenotypes we can use

minePheno(eval)

This will create a PCA plot with the similarity of the different phenotypes. If we are interested in the definition of the phenotypes we can retreive the original phenotype matrix with

pmat <- getPhenoMat(eval)

The object pmat carries now the different phenotypes which are defined by used exchange reactions within individuals on the population. A value of 1 means secretion, 2 means uptake and 0 means no usage of the substance of interest.

Simulation of multiple organisms

Now we want to multiple organisms or organism types in the environment. For this we create two different types of the Escherichia coli core metabolic model: A wildtype E. coli and an auxotrophic mutant which is unable to use aerobic respiration.

bac1 <- Bac(ecore,type="ecoli_wt")

Now we create the auxotrophic mutant by using basic commands of the sybil package.

ecore_aux <- changeBounds(ecore,"EX_o2(e)",lb=0)
bac2 <- Bac(ecore_aux,type="ecoli_aux", setExInf=FALSE)

Again we set up an environment and insert organisms and substances

arena <- Arena(n=50, m=50)
arena <- addOrg(arena,bac1,amount=1)
arena <- addOrg(arena,bac2,amount=1)
arena <- addSubs(arena,100)
eval <- simEnv(arena,time=10)
## 
## iteration: 1      organisms: 2    biomass: 0.8671937 pg 
##           count   biomass %
## ecoli_wt      1 0.3885879 0
## ecoli_aux     1 0.4786057 0
##  time total:  1.514  diffusion:  1.272  ( 84 %)
## 
## iteration: 2      organisms: 3    biomass: 16.84111 pg 
##           count    biomass          %
## ecoli_wt      2 16.2642964 4085.48685
## ecoli_aux     1  0.5768101   20.51885
##  time total:  1.295  diffusion:  1.054  ( 81.4 %)
## 
## iteration: 3      organisms: 5    biomass: 681.4704 pg 
##           count     biomass          %
## ecoli_wt      4 680.7399870 4085.48685
## ecoli_aux     1   0.7304485   26.63586
##  time total:  1.132  diffusion:  0.869  ( 76.8 %)
## 
## iteration: 4      organisms: 9    biomass: 28493.28 pg 
##           count      biomass          %
## ecoli_wt      8 2.849228e+04 4085.48685
## ecoli_aux     1 9.949129e-01   36.20576
##  time total:  1.169  diffusion:  0.853  ( 73 %)
## 
## iteration: 5      organisms: 18   biomass: 1192542 pg 
##           count      biomass          %
## ecoli_wt     16 1.192541e+06 4085.48685
## ecoli_aux     2 1.519022e+00   52.67886
##  time total:  1.474  diffusion:  1.05  ( 71.2 %)
## 
## iteration: 6      organisms: 34   biomass: 49913638 pg 
##           count      biomass          %
## ecoli_wt     32 4.991364e+07 4085.48685
## ecoli_aux     2 2.096493e+00   38.01601
##  time total:  1.49   diffusion:  0.852  ( 57.2 %)
## 
## iteration: 7      organisms: 68   biomass: 2089128667 pg 
##           count      biomass          %
## ecoli_wt     64 2.089129e+09 4085.48685
## ecoli_aux     4 3.270549e+00   56.00093
##  time total:  1.9    diffusion:  0.854  ( 44.9 %)
## 
## iteration: 8      organisms: 124      biomass: 87440205445 pg 
##           count      biomass          %
## ecoli_wt    120 8.744021e+10 4085.48685
## ecoli_aux     4 4.632295e+00   41.63662
##  time total:  2.779  diffusion:  1.063  ( 38.3 %)
## 
## iteration: 9      organisms: 207      biomass: 3.659798e+12 pg 
##           count      biomass          %
## ecoli_wt    199 3.659798e+12 4085.48685
## ecoli_aux     8 7.543317e+00   62.84191
##  time total:  3.54   diffusion:  0.861  ( 24.3 %)
## 
## iteration: 10     organisms: 297      biomass: 1.531804e+14 pg 
##           count      biomass          %
## ecoli_wt    281 1.531804e+14 4085.48685
## ecoli_aux    16 1.127273e+01   49.43997
##  time total:  4.769  diffusion:  1.059  ( 22.2 %)

Here we put the both organism types we created next to each other (given by their x position) in the environment and then started the simulation for 10 time steps. Next we perform again all evaluation steps

plotCurves2(eval)

And the spatial pattern of the community with the substances glucose, acetate and oxygen:

par(mar=c(1,1,1,1))
evalArena(eval,c("Population","EX_glc(e)","EX_ac(e)","EX_o2(e)"),
          time=10)

Here different point colors indicate the two different organism types. Finally also the different phenotypes:

minePheno(eval)

print(getPhenoMat(eval))
##             EX_ac(e) EX_acald(e) EX_akg(e) EX_co2(e) EX_etoh(e) EX_for(e)
## ecoli_wt.1         0           0         0         1          0         0
## ecoli_wt.2         1           2         1         1          1         0
## ecoli_aux.1        1           0         0         2          1         1
##             EX_fru(e) EX_fum(e) EX_glc(e) EX_gln_L(e) EX_glu_L(e) EX_h(e)
## ecoli_wt.1          0         0         2           0           0       1
## ecoli_wt.2          2         0         0           2           2       1
## ecoli_aux.1         0         0         2           0           0       1
##             EX_h2o(e) EX_lac_D(e) EX_mal_L(e) EX_nh4(e) EX_o2(e) EX_pi(e)
## ecoli_wt.1          1           0           0         2        2        2
## ecoli_wt.2          2           1           2         1        2        2
## ecoli_aux.1         2           0           0         2        0        2
##             EX_pyr(e) EX_succ(e)
## ecoli_wt.1          0          0
## ecoli_wt.2          2          0
## ecoli_aux.1         0          0

Based on these results we can see, that the auxotrophic organism type grows slower in general and uses just fermentation of glucose, whereas the the wildtype can respire glucose with the aid of oxygen. We can also create customized microbial communities or multicellular systems by importing external SBML models using the readSBMLmod function in the sybilSBML package.

Advanced

in preparation …