Formation, characterization and modeling of emergent synthetic microbial communities
Introduction
This narrative was used for the 4-member community modeling using MOPS medium for the bacteria isolated from Populus deltoides (PD). 10 bacterial strains isolated from PD were co-cultured as a synthetic microbial community in MOPS minimal medium. After 15 passages there were 4 members survived in MOPS medium.
The genome of each community member was sequenced and uploaded into KBase for genome annotation and metabolic modeling. To simulate the metabolic interactions among the finally surviving community members, the individual metabolic models of each strain were merged into a compartmentalized community model, and then the community model was gapfilled using MOPS medium. The FBA modeling was performed and the metabolites exchange among community members was proposed.
The publication by Jia Wang, Dana L. Carper, Leah H. Burdick, Him Shrestha, Manasa Appidi, Paul E. Abraham, Collin M. Timm, Robert L. Hettich, Dale A. Pelletier, Mitchel J. Doktycz can be found here: https://doi.org/10.​1016/​j.​csbj.​2021.​03.​034
The metabolic modeling for each individual bacterium in the community can be found at:
Pseudomonas sp. GM17: https://narrative.kbase.us/narrative/73080
Rhizobium sp. CF142: https://narrative.kbase.us/narrative/73214
Sphingobium sp. AP49: https://narrative.kbase.us/narrative/73212
Variovorax sp. CF313: https://narrative.kbase.us/narrative/73213
References
[1] Arkin AP, Cottingham RW, Henry CS, Harris NL, Stevens RL, et al. (2018) KBase: The United States Department of Energy Systems Biology Knowledgebase. Nat Biotechnol 36: 566-569.
[2]. Henry CS, Bernstein HC, Weisenhorn P, Taylor RC, Lee J-Y, et al. (2016) Microbial community metabolic modeling: A community data-driven network reconstruction. Journal of Cell Physiol 231: 2339-2345.
Step 1. Merge the 4 individual metabolic models (GM17, CF142, AP49 and CF313, without gapfilling) into compartmentalized community model
The modeling of community was following post-gapfilled strategy [2]. The individual species models were not gapfilled and they were merged into community model first, and then the community model was gapfilled using MOPS medium conditions.
Step 2. Adjust relative ratio of each species in the community
The relative ratio of each community member in the mixed culture was adjusted using the method in [2]. The relative ratio was adjusted according to the 16S rRNA gene amplicon Illumina sequencing result of the No. 15 passage (the last passage) culture in MOPS medium.
import os
import sys
import re
current_ws = os.environ['KB_WORKSPACE_ID']
#Instantiating work service client, which is all we will use for these alterations
from biokbase.workspace.client import Workspace
ws_client = Workspace()
#Retrieving the selected models into the python enviroment
output = ws_client.get_objects([{"workspace":current_ws,
"name":"MOPS_4_Member_Resequenced_MergedCompartmentalizedModel_NoGF"}])
biomass_array = output[0]['data']['biomasses']
for biorxn in biomass_array:
if biorxn['id'] == "bio1":
biorxn['biomasscompounds'][1]['coefficient'] = -0.060
biorxn['biomasscompounds'][2]['coefficient'] = -0.060
biorxn['biomasscompounds'][3]['coefficient'] = -0.080
biorxn['biomasscompounds'][4]['coefficient'] = -0.800
wsoutput = ws_client.save_objects({'workspace':current_ws,'objects':[{'type':'KBaseFBA.FBAModel','data':output[0]['data'],'name':"MOPS_4_Member_Resequenced_MergedCompartmentalizedModel_NoGF_adjusted"}]})
print ("Successfully adjusted community biomass composition")
Step 3. Gapfill the adjusted community model using MOPS medium conditions
Step 4. FBA modeling for gapfilled community model
The FBA model was applied to predict the metabolic fluxes in the gapfilled community model. No carbon uptake limit was added into the current FBA model.
Step 5. FBA modeling for the gapfilled community model with carbon source uptake limit
The carbon uptake limit was added to the MOPS community FBA model. For constraining microbial growth in the community model, a calibration curve between the carbon uptake limit and growth rate was built using the FBA model of each individual strain, and the carbon uptake limit was calculated based on the experimental growth rate of each strain using the linear regression equation of the corresponding calibration curve. The carbon uptake limit of the community model was the summation of individual growth rate multiply relative percentage.
Step 6. Extract the predicted metabolic exchanges from the community FBA model
The predicted fluxes of metabolite exchanges among the 4 community members were extracted from community FBA model using the method in [2]. Negative values represent uptake, and positive values represent secretion.
import os
import sys
import re
current_ws = os.environ['KB_WORKSPACE_ID']
from biokbase.workspace.client import Workspace
ws_client = Workspace()
output = ws_client.get_objects([{"workspace":current_ws,
"name":"MOPS_4_Member_Resequenced_MergedCompartmentalizedModel_adjusted_Gapfilled"}])
model = output[0]['data']
cpdhash = {}
rxnhash = {}
compound_array = model['modelcompounds']
for cpd in compound_array:
cpdhash[cpd['id']] = cpd
reaction_array = model['modelreactions']
for rxn in reaction_array:
rxnhash[rxn['id']] = rxn
output = ws_client.get_objects([{"workspace":current_ws,
"name":"MOPS_4_Member_Resequenced_MergedCompartmentalizedModel_adjusted_Gapfilled_FBA_CarbonLimit16.72"}])
exchangehash = {}
excpdhash = {}
fba = output[0]['data']
reaction_array = fba['FBAReactionVariables']
for fbarxn in reaction_array:
id_array = fbarxn['modelreaction_ref'].split("/")
rxnid = id_array.pop()
if rxnid in rxnhash.keys():
rxn = rxnhash[rxnid]
rgt_array = rxn['modelReactionReagents']
for rgt in rgt_array:
id_array = rgt['modelcompound_ref'].split("/")
cpdid = id_array.pop()
id_array = cpdid.split("_")
cmpid = id_array.pop()
if cmpid == 'e0':
for rgttwo in rgt_array:
if rgt['coefficient']*rgttwo['coefficient'] < 0:
id_array = rgttwo['modelcompound_ref'].split("/")
newcpdid = id_array.pop()
id_array = newcpdid.split("_")
cmpid = id_array.pop()
if cmpid != 'e0':
if cmpid not in exchangehash.keys():
exchangehash[cmpid] = {}
if cpdid not in exchangehash[cmpid].keys():
exchangehash[cmpid][cpdid] = 0
exchangehash[cmpid][cpdid] += fbarxn['value'] * rgt['coefficient']
excpdhash[cpdid] = 1
line = ""
for cmpid in exchangehash.keys():
line += "\t"
line += cmpid
print (line)
for cpdid in excpdhash.keys():
printline = 0
line = ""
line += cpdhash[cpdid]['name']
for cmpid in exchangehash.keys():
line += "\t"
if cpdid not in exchangehash[cmpid].keys():
line += '0'
else:
if exchangehash[cmpid][cpdid] != 0:
printline = 1
line += str(exchangehash[cmpid][cpdid])
if printline == 1:
print (line)