From f5fc68c381204dc7ba8e343d5246f67ee5f17dc6 Mon Sep 17 00:00:00 2001 From: Paulocracy <36934614+Paulocracy@users.noreply.github.com> Date: Tue, 20 Jul 2021 11:16:16 +0200 Subject: [PATCH] Update manual --- docs/commmodelpy/commmodelpy.html | 320 +++++++++++++++++++----------- 1 file changed, 204 insertions(+), 116 deletions(-) diff --git a/docs/commmodelpy/commmodelpy.html b/docs/commmodelpy/commmodelpy.html index be1930b..506ef36 100644 --- a/docs/commmodelpy/commmodelpy.html +++ b/docs/commmodelpy/commmodelpy.html @@ -81,7 +81,7 @@

References

import cobra import copy from dataclasses import dataclass -from typing import Dict, List +from typing import Dict, List, Tuple # DATACLASS DEFINITIONS SECTION @@ -212,8 +212,8 @@

References

output_metabolite_ids: List[str] -""" # FUNCTION DEFINITIONS SECTION +""" def community_model_fba_summary(model: cobra.Model, exchange_reaction_id_prefix: str = "EX_C_", optimization_title: str = "FBA") -> Tuple[cobra.Solution, List[Dict[str, int]]]: Performs an FBA (or any kind of modified optimization) on a commmodelpy-generated community model and prints the results. @@ -487,7 +487,7 @@

References

return merged_model -def create_community_model_with_balanced_growth(community: Community, growth_rate: float) -> cobra.Model: +def create_community_model_with_balanced_growth(community: Community, growth_rate: float, organism_exchange_bounds: Dict[str, Tuple[float, float]] = {}) -> cobra.Model: """Creates a combined community model with an stoichiometric-matrix-integrated balanced growth approach. Description @@ -546,6 +546,11 @@

References

metabolites from the respective SingleSpecies instances, as well as from the exchange compartment to the environment for all input/output metabolites of the Community instance. All previous standard exchanges of the single models (usually starting with "EX_") are deleted. + The new exchange reactions start with EXCHG_in_ for input reactions (input to organism) and EXCHG_out_ for output metabolites + (output from organism). Both types of EXCHG_ reactions are irreversible, and EXCHG_in_ reactions get an upper bound of + 1000 mmol/(gDW*h) as standard in order to enforce the incorporation of Msnake_UPPER_ upper bound metabolites so that growth is + actually enforced for all organisms in which reactions occur (which may not be the case if reactions with lower/upper bounds + of inf are used). The principle used herein also means that if another growth rate is to be tested, a new model has to be generated for this specific growth rate. @@ -558,8 +563,11 @@

References

Arguments ---------- - * community: Community ~ - * growth_rate: float ~ + * community: Community ~ A CommModelPy Community instance. + * growth_rate: float ~ The growth rate to which the community shall be fixed. + * organism_exchange_bounds: Dict[Tuple[float, float]] ~ A dictionary containing reaction IDs + (which may also include the EXCHG_ reactions introduced by this function) as keys + and, in the float tuple at index 0 a set lower bound and at index 1 a set upper bound. """ # Get number of SingleModel instances in Community instance num_single_models = len(community.single_models) @@ -660,15 +668,86 @@

References

community_biomass_metabolite: -1, }) - # Add minimal and maximal bound constraint + # Add single species <-> exchange compartment exchanges + for single_model in community.single_models: + exchange_metabolite_ids = list( + set(single_model.input_metabolite_ids + single_model.output_metabolite_ids)) + exchange_metabolite_ids = [ + x+"_"+single_model.species_abbreviation for x in exchange_metabolite_ids] + + for exchange_metabolite_id in exchange_metabolite_ids: + single_model_base_metabolite_id = exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "") + exchange_compartment_metabolite_id = single_model.model_metabolite_to_exchange_id_mapping[single_model_base_metabolite_id] + + # Add metabolites to reaction + try: + internal_metabolite = merged_model.metabolites.get_by_id( + exchange_metabolite_id) + except: + print("ERROR: Internal exchange metabolite ID " + exchange_metabolite_id + "does not exist!") + species_exchange_metabolite_id = exchange_compartment_metabolite_id+"_"+community.exchange_compartment_id + try: + exchange_compartment_metabolite = merged_model.metabolites.get_by_id( + species_exchange_metabolite_id) + except: + new_species_exchange_metabolite = cobra.Metabolite(id=species_exchange_metabolite_id, + compartment="exchg") + merged_model.add_metabolites(new_species_exchange_metabolite) + exchange_compartment_metabolite = merged_model.metabolites.get_by_id( + species_exchange_metabolite_id) + + # Set reaction bounds + is_input = single_model_base_metabolite_id in single_model.input_metabolite_ids + is_output = single_model_base_metabolite_id in single_model.output_metabolite_ids + + # Set reaction instance + if is_input: + reaction_in = cobra.Reaction(id="EXCHG_in_"+single_model.species_abbreviation+"_"+exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "")+"_to_"+exchange_compartment_metabolite_id, + name=f"Input exchange for {exchange_metabolite_id} from single species {single_model.species_abbreviation} to exchange compartment") + reaction_in.add_metabolites({ + exchange_compartment_metabolite: -1, + internal_metabolite: 1, + }) + reaction_in.lower_bound = 0 + reaction_in.upper_bound = 1000 + + merged_model.add_reactions([reaction_in]) + if is_output: + reaction_out = cobra.Reaction(id="EXCHG_out_"+single_model.species_abbreviation+"_"+exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "")+"_to_"+exchange_compartment_metabolite_id, + name=f"Output exchange for {exchange_metabolite_id} from single species {single_model.species_abbreviation} to exchange compartment") + reaction_out.add_metabolites({ + internal_metabolite: -1, + exchange_compartment_metabolite: 1, + }) + reaction_out.lower_bound = 0 + reaction_out.upper_bound = float("inf") + + merged_model.add_reactions([reaction_out]) + + # Add organism-specific reaction bounds + bound_reaction_ids = [x.id for x in merged_model.reactions + if x.id in list(organism_exchange_bounds.keys())] + for bound_reaction_id in bound_reaction_ids: + lower_bound = organism_exchange_bounds[bound_reaction_id][0] + upper_bound = organism_exchange_bounds[bound_reaction_id][1] + reaction = merged_model.reactions.get_by_id(bound_reaction_id) + reaction.lower_bound = lower_bound + reaction.upper_bound = upper_bound + + # Add minimal and maximal bound constraints using pseudo-metabolites and pseudo-reactions reaction_ids = [x.id for x in merged_model.reactions] for reaction_id in reaction_ids: reaction = merged_model.reactions.get_by_id(reaction_id) # Check organism ID - reaction_organism_id = reaction.id.split("_")[-1] - if reaction_organism_id not in organism_id_biomass_reaction_id_mapping.keys(): - continue + if reaction_id.startswith("EXCHG"): + reaction_organism_id = reaction.id.split("_")[2] + if reaction_organism_id not in organism_id_biomass_reaction_id_mapping.keys(): + continue + else: + reaction_organism_id = reaction.id.split("_")[-1] + if reaction_organism_id not in organism_id_biomass_reaction_id_mapping.keys(): + continue organism_biomass_reaction = merged_model.reactions.get_by_id( organism_id_biomass_reaction_id_mapping[reaction_organism_id]) @@ -681,6 +760,7 @@

References

# Add ~r new_reaction = cobra.Reaction(id="Rsnake_UPPER_"+reaction.id, name="Delivery reaction of upper bound enforcing metabolite for "+reaction.id) + # Add ~M to original reaction reaction.add_metabolites({ new_metabolite: 1, @@ -693,6 +773,8 @@

References

}) merged_model.add_reactions([new_reaction]) + reaction.upper_bound = float("inf") + # Add minimal bound constraint if (reaction.lower_bound != -float("inf")) and (reaction.lower_bound != 0.0): # Add ~M @@ -701,7 +783,8 @@

References

compartment="exchg") # Add ~r new_reaction = cobra.Reaction(id="Rsnake_LOWER_"+reaction.id, - name="Delivery reaction of lower bound enforcing metabolite for "+reaction.id) + name="Consuming reaction of lower bound enforcing metabolite for "+reaction.id) + # Add ~M to original reaction reaction.add_metabolites({ new_metabolite: 1, @@ -714,53 +797,10 @@

References

}) merged_model.add_reactions([new_reaction]) - # Add single species <-> exchange compartment exchanges - for single_model in community.single_models: - exchange_metabolite_ids = list( - set(single_model.input_metabolite_ids + single_model.output_metabolite_ids)) - exchange_metabolite_ids = [ - x+"_"+single_model.species_abbreviation for x in exchange_metabolite_ids] - - # Add mock community biomass metabolites for the ASTHERISC package's species recognition - biomass_metabolite = cobra.Metabolite(id="community_biomass_"+single_model.species_abbreviation, - name="Mock community biomass metabolite for ASTHERISC package species recognition", - compartment="exchg") - merged_model.add_metabolites([biomass_metabolite]) - - for exchange_metabolite_id in exchange_metabolite_ids: - exchange_compartment_metabolite_id = single_model.model_metabolite_to_exchange_id_mapping[exchange_metabolite_id.replace( - "_"+single_model.species_abbreviation, "")] - - # Set reaction instance - reaction = cobra.Reaction(id="EXCHG_"+single_model.species_abbreviation+"_"+exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "")+"_to_"+exchange_compartment_metabolite_id, - name=f"Exchange for {exchange_metabolite_id} from single species {single_model.species_abbreviation} to exchange compartment") - - # Set reaction bounds - is_input = exchange_compartment_metabolite_id in community.input_metabolite_ids - if is_input: - reaction.lower_bound = -float("inf") - else: - reaction.lower_bound = 0 - is_output = exchange_compartment_metabolite_id in community.output_metabolite_ids - if is_output: - reaction.upper_bound = float("inf") - else: - reaction.upper_bound = 0 - - # Add metabolites to reaction - internal_metabolite = merged_model.metabolites.get_by_id( - exchange_metabolite_id) - exchange_compartment_metabolite = merged_model.metabolites.get_by_id( - exchange_compartment_metabolite_id+"_"+community.exchange_compartment_id) - reaction.add_metabolites({ - internal_metabolite: -1, - exchange_compartment_metabolite: 1, - }) - - # Add reaction to model - merged_model.add_reactions([reaction]) + reaction.lower_bound = 0 # Set merged model's objective to community biomass + merged_model.add_reactions([community_biomass_reaction]) merged_model.objective = "COMMUNITY_BIOMASS" return merged_model @@ -837,7 +877,7 @@

References

Functions

-def create_community_model_with_balanced_growth(community: Community, growth_rate: float) ‑> cobra.core.model.Model +def create_community_model_with_balanced_growth(community: Community, growth_rate: float, organism_exchange_bounds: Dict[str, Tuple[float, float]] = {}) ‑> cobra.core.model.Model

Creates a combined community model with an stoichiometric-matrix-integrated balanced growth approach.

@@ -888,7 +928,12 @@

Description

  • Exchange reactions between the single species comparments and the exchange compartment for all input/output metabolites from the respective SingleSpecies instances, as well as from the exchange compartment to the environment for all input/output metabolites of the Community instance. All previous standard -exchanges of the single models (usually starting with "EX_") are deleted.
  • +exchanges of the single models (usually starting with "EX_") are deleted. +The new exchange reactions start with EXCHG_in_ for input reactions (input to organism) and EXCHG_out_ for output metabolites +(output from organism). Both types of EXCHG_ reactions are irreversible, and EXCHG_in_ reactions get an upper bound of +1000 mmol/(gDW*h) as standard in order to enforce the incorporation of Msnake_UPPER_ upper bound metabolites so that growth is +actually enforced for all organisms in which reactions occur (which may not be the case if reactions with lower/upper bounds +of inf are used).

    The principle used herein also means that if another growth rate is to be tested, a new model has to be generated for this specific growth rate.

    @@ -898,14 +943,17 @@

    Return Value

    ratios - can be e.g. used with the ASTHERISC package.

    Arguments

      -
    • community: Community ~
    • -
    • growth_rate: float ~
    • +
    • community: Community ~ A CommModelPy Community instance.
    • +
    • growth_rate: float ~ The growth rate to which the community shall be fixed.
    • +
    • organism_exchange_bounds: Dict[Tuple[float, float]] ~ A dictionary containing reaction IDs +(which may also include the EXCHG_ reactions introduced by this function) as keys +and, in the float tuple at index 0 a set lower bound and at index 1 a set upper bound.
    Expand source code -
    def create_community_model_with_balanced_growth(community: Community, growth_rate: float) -> cobra.Model:
    +
    def create_community_model_with_balanced_growth(community: Community, growth_rate: float, organism_exchange_bounds: Dict[str, Tuple[float, float]] = {}) -> cobra.Model:
         """Creates a combined community model with an stoichiometric-matrix-integrated balanced growth approach.
     
         Description
    @@ -964,6 +1012,11 @@ 

    Arguments

    metabolites from the respective SingleSpecies instances, as well as from the exchange compartment to the environment for all input/output metabolites of the Community instance. All previous standard exchanges of the single models (usually starting with "EX_") are deleted. + The new exchange reactions start with EXCHG_in_ for input reactions (input to organism) and EXCHG_out_ for output metabolites + (output from organism). Both types of EXCHG_ reactions are irreversible, and EXCHG_in_ reactions get an upper bound of + 1000 mmol/(gDW*h) as standard in order to enforce the incorporation of Msnake_UPPER_ upper bound metabolites so that growth is + actually enforced for all organisms in which reactions occur (which may not be the case if reactions with lower/upper bounds + of inf are used). The principle used herein also means that if another growth rate is to be tested, a new model has to be generated for this specific growth rate. @@ -976,8 +1029,11 @@

    Arguments

    Arguments ---------- - * community: Community ~ - * growth_rate: float ~ + * community: Community ~ A CommModelPy Community instance. + * growth_rate: float ~ The growth rate to which the community shall be fixed. + * organism_exchange_bounds: Dict[Tuple[float, float]] ~ A dictionary containing reaction IDs + (which may also include the EXCHG_ reactions introduced by this function) as keys + and, in the float tuple at index 0 a set lower bound and at index 1 a set upper bound. """ # Get number of SingleModel instances in Community instance num_single_models = len(community.single_models) @@ -1078,15 +1134,86 @@

    Arguments

    community_biomass_metabolite: -1, }) - # Add minimal and maximal bound constraint + # Add single species <-> exchange compartment exchanges + for single_model in community.single_models: + exchange_metabolite_ids = list( + set(single_model.input_metabolite_ids + single_model.output_metabolite_ids)) + exchange_metabolite_ids = [ + x+"_"+single_model.species_abbreviation for x in exchange_metabolite_ids] + + for exchange_metabolite_id in exchange_metabolite_ids: + single_model_base_metabolite_id = exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "") + exchange_compartment_metabolite_id = single_model.model_metabolite_to_exchange_id_mapping[single_model_base_metabolite_id] + + # Add metabolites to reaction + try: + internal_metabolite = merged_model.metabolites.get_by_id( + exchange_metabolite_id) + except: + print("ERROR: Internal exchange metabolite ID " + exchange_metabolite_id + "does not exist!") + species_exchange_metabolite_id = exchange_compartment_metabolite_id+"_"+community.exchange_compartment_id + try: + exchange_compartment_metabolite = merged_model.metabolites.get_by_id( + species_exchange_metabolite_id) + except: + new_species_exchange_metabolite = cobra.Metabolite(id=species_exchange_metabolite_id, + compartment="exchg") + merged_model.add_metabolites(new_species_exchange_metabolite) + exchange_compartment_metabolite = merged_model.metabolites.get_by_id( + species_exchange_metabolite_id) + + # Set reaction bounds + is_input = single_model_base_metabolite_id in single_model.input_metabolite_ids + is_output = single_model_base_metabolite_id in single_model.output_metabolite_ids + + # Set reaction instance + if is_input: + reaction_in = cobra.Reaction(id="EXCHG_in_"+single_model.species_abbreviation+"_"+exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "")+"_to_"+exchange_compartment_metabolite_id, + name=f"Input exchange for {exchange_metabolite_id} from single species {single_model.species_abbreviation} to exchange compartment") + reaction_in.add_metabolites({ + exchange_compartment_metabolite: -1, + internal_metabolite: 1, + }) + reaction_in.lower_bound = 0 + reaction_in.upper_bound = 1000 + + merged_model.add_reactions([reaction_in]) + if is_output: + reaction_out = cobra.Reaction(id="EXCHG_out_"+single_model.species_abbreviation+"_"+exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "")+"_to_"+exchange_compartment_metabolite_id, + name=f"Output exchange for {exchange_metabolite_id} from single species {single_model.species_abbreviation} to exchange compartment") + reaction_out.add_metabolites({ + internal_metabolite: -1, + exchange_compartment_metabolite: 1, + }) + reaction_out.lower_bound = 0 + reaction_out.upper_bound = float("inf") + + merged_model.add_reactions([reaction_out]) + + # Add organism-specific reaction bounds + bound_reaction_ids = [x.id for x in merged_model.reactions + if x.id in list(organism_exchange_bounds.keys())] + for bound_reaction_id in bound_reaction_ids: + lower_bound = organism_exchange_bounds[bound_reaction_id][0] + upper_bound = organism_exchange_bounds[bound_reaction_id][1] + reaction = merged_model.reactions.get_by_id(bound_reaction_id) + reaction.lower_bound = lower_bound + reaction.upper_bound = upper_bound + + # Add minimal and maximal bound constraints using pseudo-metabolites and pseudo-reactions reaction_ids = [x.id for x in merged_model.reactions] for reaction_id in reaction_ids: reaction = merged_model.reactions.get_by_id(reaction_id) # Check organism ID - reaction_organism_id = reaction.id.split("_")[-1] - if reaction_organism_id not in organism_id_biomass_reaction_id_mapping.keys(): - continue + if reaction_id.startswith("EXCHG"): + reaction_organism_id = reaction.id.split("_")[2] + if reaction_organism_id not in organism_id_biomass_reaction_id_mapping.keys(): + continue + else: + reaction_organism_id = reaction.id.split("_")[-1] + if reaction_organism_id not in organism_id_biomass_reaction_id_mapping.keys(): + continue organism_biomass_reaction = merged_model.reactions.get_by_id( organism_id_biomass_reaction_id_mapping[reaction_organism_id]) @@ -1099,6 +1226,7 @@

    Arguments

    # Add ~r new_reaction = cobra.Reaction(id="Rsnake_UPPER_"+reaction.id, name="Delivery reaction of upper bound enforcing metabolite for "+reaction.id) + # Add ~M to original reaction reaction.add_metabolites({ new_metabolite: 1, @@ -1111,6 +1239,8 @@

    Arguments

    }) merged_model.add_reactions([new_reaction]) + reaction.upper_bound = float("inf") + # Add minimal bound constraint if (reaction.lower_bound != -float("inf")) and (reaction.lower_bound != 0.0): # Add ~M @@ -1119,7 +1249,8 @@

    Arguments

    compartment="exchg") # Add ~r new_reaction = cobra.Reaction(id="Rsnake_LOWER_"+reaction.id, - name="Delivery reaction of lower bound enforcing metabolite for "+reaction.id) + name="Consuming reaction of lower bound enforcing metabolite for "+reaction.id) + # Add ~M to original reaction reaction.add_metabolites({ new_metabolite: 1, @@ -1132,53 +1263,10 @@

    Arguments

    }) merged_model.add_reactions([new_reaction]) - # Add single species <-> exchange compartment exchanges - for single_model in community.single_models: - exchange_metabolite_ids = list( - set(single_model.input_metabolite_ids + single_model.output_metabolite_ids)) - exchange_metabolite_ids = [ - x+"_"+single_model.species_abbreviation for x in exchange_metabolite_ids] - - # Add mock community biomass metabolites for the ASTHERISC package's species recognition - biomass_metabolite = cobra.Metabolite(id="community_biomass_"+single_model.species_abbreviation, - name="Mock community biomass metabolite for ASTHERISC package species recognition", - compartment="exchg") - merged_model.add_metabolites([biomass_metabolite]) - - for exchange_metabolite_id in exchange_metabolite_ids: - exchange_compartment_metabolite_id = single_model.model_metabolite_to_exchange_id_mapping[exchange_metabolite_id.replace( - "_"+single_model.species_abbreviation, "")] - - # Set reaction instance - reaction = cobra.Reaction(id="EXCHG_"+single_model.species_abbreviation+"_"+exchange_metabolite_id.replace("_"+single_model.species_abbreviation, "")+"_to_"+exchange_compartment_metabolite_id, - name=f"Exchange for {exchange_metabolite_id} from single species {single_model.species_abbreviation} to exchange compartment") - - # Set reaction bounds - is_input = exchange_compartment_metabolite_id in community.input_metabolite_ids - if is_input: - reaction.lower_bound = -float("inf") - else: - reaction.lower_bound = 0 - is_output = exchange_compartment_metabolite_id in community.output_metabolite_ids - if is_output: - reaction.upper_bound = float("inf") - else: - reaction.upper_bound = 0 - - # Add metabolites to reaction - internal_metabolite = merged_model.metabolites.get_by_id( - exchange_metabolite_id) - exchange_compartment_metabolite = merged_model.metabolites.get_by_id( - exchange_compartment_metabolite_id+"_"+community.exchange_compartment_id) - reaction.add_metabolites({ - internal_metabolite: -1, - exchange_compartment_metabolite: 1, - }) - - # Add reaction to model - merged_model.add_reactions([reaction]) + reaction.lower_bound = 0 # Set merged model's objective to community biomass + merged_model.add_reactions([community_biomass_reaction]) merged_model.objective = "COMMUNITY_BIOMASS" return merged_model
    @@ -1530,7 +1618,7 @@

    Usage Example

    set the prefix of the community's exchange metabolites to "EX_C" and E. coli has the input metabolites glc__D, o2, h and h2o, and V. natriegens the additional input metabolite biotin, and both habe the output metabolites ac and co2, -then we could set the Community instance as follows: +then we could set the Community instance as follows:

     community_example = Community(
         single_models = [ecoli_core, vnatriegens_core],
    @@ -1539,7 +1627,7 @@ 

    Usage Example

    input_metabolite_ids = ["glc__D", "o2", "h", "h2o", "ac", "biotin"], output_metabolite_ids = ["ac", "co2"] ) -

    +
    Expand source code @@ -1662,7 +1750,7 @@

    Usage Example

    Suppose we defined a BiGG-compliant core model of E. coli, and we set the exchange compartment metabolite names just as the metabolite IDs themselves without the addition of the underscore plus compartment name, then -a SingleModel definition could look like this: +a SingleModel definition could look like this:

     single_ec_core_model = SingleModel(
         cobra_model=e_coli_core_model,
    @@ -1679,7 +1767,7 @@ 

    Usage Example

    "ac_e": "ac", } ) -

    +
    Expand source code