Ejemplo n.º 1
0
def find_metabolites_consumed_with_closed_bounds(model):
    """
    Return metabolites that can be consumed when boundary reactions are closed.

    Reverse case from 'find_metabolites_produced_with_closed_bounds', just
    like metabolites should not be produced from nothing, mass should not
    simply be removed from the model.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    """
    mets_consumed = list()
    helpers.close_boundaries_sensibly(model)
    for met in model.metabolites:
        with model:
            exch = model.add_boundary(met,
                                      type='irrex',
                                      reaction_id='IRREX',
                                      lb=-1,
                                      ub=0)
            if helpers.run_fba(model, exch.id, direction='min') < 0:
                mets_consumed.append(met)
    return mets_consumed
Ejemplo n.º 2
0
def find_stoichiometrically_balanced_cycles(model):
    u"""
    Find metabolic reactions in stoichiometrically balanced cycles (SBCs).

    Identify forward and reverse cycles by closing all exchanges and using FVA.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Notes
    -----
    "SBCs are artifacts of metabolic reconstructions due to insufficient
    constraints (e.g., thermodynamic constraints and regulatory
    constraints) [1]_." They are defined by internal reactions that carry
    flux in spite of closed exchange reactions.

    References
    ----------
    .. [1] Thiele, I., & Palsson, B. Ø. (2010, January). A protocol for
           generating a high-quality genome-scale metabolic reconstruction.
           Nature protocols. Nature Publishing Group.
           http://doi.org/10.1038/nprot.2009.203

    """
    helpers.close_boundaries_sensibly(model)
    fva_result = flux_variability_analysis(model, loopless=False)
    return fva_result.index[(fva_result["minimum"] == -1) |
                            (fva_result["maximum"] == 1)].tolist()
Ejemplo n.º 3
0
def find_metabolites_produced_with_closed_bounds(model):
    """
    Return metabolites that can be produced when boundary reactions are closed.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    """
    mets_produced = list()
    helpers.close_boundaries_sensibly(model)
    for met in model.metabolites:
        with model:
            exch = model.add_boundary(met,
                                      type='irrex',
                                      reaction_id='IRREX',
                                      lb=0,
                                      ub=1)
            if helpers.run_fba(model, exch.id) > 0:
                mets_produced.append(met)
    return mets_produced
Ejemplo n.º 4
0
def detect_energy_generating_cycles(model, metabolite_id):
    u"""
    Detect erroneous energy-generating cycles for a a single metabolite.

    The function will first build a dissipation reaction corresponding to the
    input metabolite. This reaction is then set as the objective for
    optimization, after closing all exchanges. If the reaction was able to
    carry flux, an erroneous energy-generating cycle must be present. In this
    case a list of reactions with a flux greater than zero is returned.
    Otherwise, the function returns False.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.
    metabolite_id : str
        The identifier of an energy metabolite.

    Notes
    -----
    "[...] energy generating cycles (EGC) [...] charge energy metabolites
    without a source of energy. [...] To efficiently identify the existence of
    diverse EGCs, we first add a dissipation reaction to the metabolic network
    for each metabolite used to transmit cellular energy; e.g., for ATP, the
    irreversible reaction ATP + H2O → ADP + P + H+ is added. These dissipation
    reactions close any existing energy-generating cycles, thereby converting
    them to type-III pathways. Fluxes through any of the dissipation reactions
    at steady state indicate the generation of energy through the metabolic
    network. Second, all uptake reactions are constrained to zero. The sum of
    the fluxes through the energy dissipation reactions is now maximized using
    FBA. For a model without EGCs, these reactions cannot carry any flux
    without the uptake of nutrients. [1]_."

    References
    ----------
    .. [1] Fritzemeier, C. J., Hartleb, D., Szappanos, B., Papp, B., & Lercher,
     M. J. (2017). Erroneous energy-generating cycles in published genome scale
     metabolic networks: Identification and removal. PLoS Computational
     Biology, 13(4), 1–14. http://doi.org/10.1371/journal.pcbi.1005494

    """
    main_comp = helpers.find_compartment_id_in_model(model, 'c')
    met = helpers.find_met_in_model(model, metabolite_id, main_comp)[0]

    dissipation_rxn = Reaction('Dissipation')
    if metabolite_id in ['MNXM3', 'MNXM63', 'MNXM51', 'MNXM121', 'MNXM423']:
        # build nucleotide-type dissipation reaction
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM2', main_comp)[0]:
            -1,
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]:
            1,
            helpers.find_met_in_model(model, 'MNXM9', main_comp)[0]:
            1,
        })
    elif metabolite_id in ['MNXM6', 'MNXM10']:
        # build nicotinamide-type dissipation reaction
        dissipation_rxn.add_metabolites(
            {helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 1})
    elif metabolite_id in [
            'MNXM38', 'MNXM208', 'MNXM191', 'MNXM223', 'MNXM7517', 'MNXM12233',
            'MNXM558'
    ]:
        # build redox-partner-type dissipation reaction
        dissipation_rxn.add_metabolites(
            {helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 2})
    elif metabolite_id == 'MNXM21':
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM2', main_comp)[0]:
            -1,
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]:
            1,
            helpers.find_met_in_model(model, 'MNXM26', main_comp)[0]:
            1,
        })
    elif metabolite_id == 'MNXM89557':
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM2', main_comp)[0]:
            -1,
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]:
            2,
            helpers.find_met_in_model(model, 'MNXM15', main_comp)[0]:
            1,
        })

    dissipation_product = helpers.find_met_in_model(
        model, ENERGY_COUPLES[metabolite_id], main_comp)[0]

    dissipation_rxn.add_metabolites({met: -1, dissipation_product: 1})
    helpers.close_boundaries_sensibly(model)
    model.add_reactions([dissipation_rxn])
    model.objective = dissipation_rxn
    solution = model.optimize(raise_error=True)

    if solution.objective_value > 0.0:
        return solution.fluxes[solution.fluxes.abs() > 0.0].index. \
            drop(["Dissipation"]).tolist()
    else:
        return []
Ejemplo n.º 5
0
def detect_energy_generating_cycles(model, metabolite_id):
    u"""
    Detect erroneous energy-generating cycles for a a single metabolite.

    The function will first build a dissipation reaction corresponding to the
    input metabolite. This reaction is then set as the objective for
    optimization, after closing all exchanges. If the reaction was able to
    carry flux, an erroneous energy-generating cycle must be present. In this
    case a list of reactions with a flux greater than zero is returned.
    Otherwise, the function returns False.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.
    metabolite_id : str
        The identifier of an energy metabolite.

    Notes
    -----
    "[...] energy generating cycles (EGC) [...] charge energy metabolites
    without a source of energy. [...] To efficiently identify the existence of
    diverse EGCs, we first add a dissipation reaction to the metabolic network
    for each metabolite used to transmit cellular energy; e.g., for ATP, the
    irreversible reaction ATP + H2O → ADP + P + H+ is added. These dissipation
    reactions close any existing energy-generating cycles, thereby converting
    them to type-III pathways. Fluxes through any of the dissipation reactions
    at steady state indicate the generation of energy through the metabolic
    network. Second, all uptake reactions are constrained to zero. The sum of
    the fluxes through the energy dissipation reactions is now maximized using
    FBA. For a model without EGCs, these reactions cannot carry any flux
    without the uptake of nutrients. [1]_."

    References
    ----------
    .. [1] Fritzemeier, C. J., Hartleb, D., Szappanos, B., Papp, B., & Lercher,
     M. J. (2017). Erroneous energy-generating cycles in published genome scale
     metabolic networks: Identification and removal. PLoS Computational
     Biology, 13(4), 1–14. http://doi.org/10.1371/journal.pcbi.1005494

    """
    met = model.metabolites.get_by_id(metabolite_id)
    dissipation_product = model.metabolites.get_by_id(ENERGY_COUPLES[met.id])
    dissipation_rxn = Reaction('Dissipation')
    model = helpers.close_boundaries_sensibly(model)
    model.add_reactions([dissipation_rxn])
    if met.id in ['atp_c', 'ctp_c', 'gtp_c', 'utp_c', 'itp_c']:
        # build nucleotide-type dissipation reaction
        dissipation_rxn.reaction = "h2o_c --> h_c + pi_c"
    elif met.id in ['nadph_c', 'nadh_c']:
        # build nicotinamide-type dissipation reaction
        dissipation_rxn.reaction = "--> h_c"
    elif met.id in [
            'fadh2_c', 'fmnh2_c', 'q8h2_c', 'mql8_c', 'mql6_c', 'mql7_c',
            'dmmql8_c'
    ]:
        # build redox-partner-type dissipation reaction
        dissipation_rxn.reaction = "--> 2 h_c"
    elif met.id == 'accoa_c':
        dissipation_rxn.reaction = "h2o_c --> h_c + ac_c"
    elif met.id == 'glu__L_c':
        dissipation_rxn.reaction = "h2o_c --> 2 h_c + nh3_c"
    elif met.id == 'h_p':
        pass

    dissipation_rxn.add_metabolites({met.id: -1, dissipation_product: 1})
    model.objective = dissipation_rxn
    solution = model.optimize()
    if solution.status == 'infeasible':
        raise RuntimeError("The model cannot be solved as the solver status is"
                           "infeasible. This may be a bug.")
    elif solution.objective_value > 0.0:
        return solution.fluxes[solution.fluxes.abs() > 0.0].index. \
            drop(["Dissipation"]).tolist()
    else:
        return []