예제 #1
0
 def test_change_coefficient(self, solver_test):
     solver, old_solution, infeasible_model = solver_test
     c = Metabolite("c")
     c._bound = 6
     x = Reaction("x")
     x.lower_bound = 1.
     y = Reaction("y")
     y.lower_bound = 0.
     x.add_metabolites({c: 1})
     z = Reaction("z")
     z.add_metabolites({c: 1})
     z.objective_coefficient = 1
     m = Model("test_model")
     m.add_reactions([x, y, z])
     # change an existing coefficient
     lp = solver.create_problem(m)
     solver.solve_problem(lp)
     sol1 = solver.format_solution(lp, m)
     assert sol1.status == "optimal"
     solver.change_coefficient(lp, 0, 0, 2)
     solver.solve_problem(lp)
     sol2 = solver.format_solution(lp, m)
     assert sol2.status == "optimal"
     assert abs(sol1.f - 5.0) < 10 ** -3
     assert abs(sol2.f - 4.0) < 10 ** -3
     # change a new coefficient
     z.objective_coefficient = 0.
     y.objective_coefficient = 1.
     lp = solver.create_problem(m)
     solver.change_coefficient(lp, 0, 1, 2)
     solver.solve_problem(lp)
     solution = solver.format_solution(lp, m)
     assert solution.status == "optimal"
     assert abs(solution.x_dict["y"] - 2.5) < 10 ** -3
예제 #2
0
    def test_complicated_model(self):
        """Difficult model since the online mean calculation is numerically
        unstable so many samples weakly violate the equality constraints."""
        model = Model('flux_split')
        reaction1 = Reaction('V1')
        reaction2 = Reaction('V2')
        reaction3 = Reaction('V3')
        reaction1.lower_bound = 0
        reaction2.lower_bound = 0
        reaction3.lower_bound = 0
        reaction1.upper_bound = 6
        reaction2.upper_bound = 8
        reaction3.upper_bound = 10
        A = Metabolite('A')
        reaction1.add_metabolites({A: -1})
        reaction2.add_metabolites({A: -1})
        reaction3.add_metabolites({A: 1})
        model.add_reactions([reaction1])
        model.add_reactions([reaction2])
        model.add_reactions([reaction3])

        optgp = OptGPSampler(model, 1, seed=42)
        achr = ACHRSampler(model, seed=42)
        optgp_samples = optgp.sample(100)
        achr_samples = achr.sample(100)
        assert any(optgp_samples.corr().abs() < 1.0)
        assert any(achr_samples.corr().abs() < 1.0)
        # > 95% are valid
        assert(sum(optgp.validate(optgp_samples) == "v") > 95)
        assert(sum(achr.validate(achr_samples) == "v") > 95)
 def test_add_reactions(self, model):
     r1 = Reaction('r1')
     r1.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1})
     r1.lower_bound, r1.upper_bound = -999999., 999999.
     r2 = Reaction('r2')
     r2.add_metabolites({
         Metabolite('A'): -1,
         Metabolite('C'): 1,
         Metabolite('D'): 1
     })
     r2.lower_bound, r2.upper_bound = 0., 999999.
     model.add_reactions([r1, r2])
     r2.objective_coefficient = 3.
     assert r2.objective_coefficient == 3.
     assert model.reactions[-2] == r1
     assert model.reactions[-1] == r2
     assert isinstance(model.reactions[-2].reverse_variable,
                       model.problem.Variable)
     coefficients_dict = model.objective.expression. \
         as_coefficients_dict()
     biomass_r = model.reactions.get_by_id('Biomass_Ecoli_core')
     assert coefficients_dict[biomass_r.forward_variable] == 1.
     assert coefficients_dict[biomass_r.reverse_variable] == -1.
     assert coefficients_dict[model.reactions.r2.forward_variable] == 3.
     assert coefficients_dict[model.reactions.r2.reverse_variable] == -3.
예제 #4
0
 def test_solve_mip(self, solver_test):
     solver, old_solution, infeasible_model = solver_test
     if not hasattr(solver, "_SUPPORTS_MILP") or not solver._SUPPORTS_MILP:
         pytest.skip("no milp support")
     cobra_model = Model('MILP_implementation_test')
     constraint = Metabolite("constraint")
     constraint._bound = 2.5
     x = Reaction("x")
     x.lower_bound = 0.
     x.objective_coefficient = 1.
     x.add_metabolites({constraint: 2.5})
     y = Reaction("y")
     y.lower_bound = 0.
     y.objective_coefficient = 1.
     y.add_metabolites({constraint: 1.})
     cobra_model.add_reactions([x, y])
     float_sol = solver.solve(cobra_model)
     # add an integer constraint
     y.variable_kind = "integer"
     int_sol = solver.solve(cobra_model)
     assert abs(float_sol.f - 2.5) < 10 ** -5
     assert abs(float_sol.x_dict["y"] - 2.5) < 10 ** -5
     assert int_sol.status == "optimal"
     assert abs(int_sol.f - 2.2) < 10 ** -3
     assert abs(int_sol.x_dict["y"] - 2.0) < 10 ** -3
예제 #5
0
 def test_inequality(self, solver_test):
     solver, old_solution, infeasible_model = solver_test
     # The space enclosed by the constraints is a 2D triangle with
     # vertexes as (3, 0), (1, 2), and (0, 1)
     # c1 encodes y - x > 1 ==> y > x - 1
     # c2 encodes y + x < 3 ==> y < 3 - x
     c1 = Metabolite("c1")
     c2 = Metabolite("c2")
     x = Reaction("x")
     x.lower_bound = 0
     y = Reaction("y")
     y.lower_bound = 0
     x.add_metabolites({c1: -1, c2: 1})
     y.add_metabolites({c1: 1, c2: 1})
     c1._bound = 1
     c1._constraint_sense = "G"
     c2._bound = 3
     c2._constraint_sense = "L"
     m = Model()
     m.add_reactions([x, y])
     # test that optimal values are at the vertices
     m.objective = "x"
     assert abs(solver.solve(m).f - 1.0) < 10 ** -3
     assert abs(solver.solve(m).x_dict["y"] - 2.0) < 10 ** -3
     m.objective = "y"
     assert abs(solver.solve(m).f - 3.0) < 10 ** -3
     assert abs(
         solver.solve(m, objective_sense="minimize").f - 1.0) < 10 ** -3
예제 #6
0
    def test_complicated_model(self):
        """Difficult model since the online mean calculation is numerically
        unstable so many samples weakly violate the equality constraints."""
        model = Model('flux_split')
        reaction1 = Reaction('V1')
        reaction2 = Reaction('V2')
        reaction3 = Reaction('V3')
        reaction1.lower_bound = 0
        reaction2.lower_bound = 0
        reaction3.lower_bound = 0
        reaction1.upper_bound = 6
        reaction2.upper_bound = 8
        reaction3.upper_bound = 10
        A = Metabolite('A')
        reaction1.add_metabolites({A: -1})
        reaction2.add_metabolites({A: -1})
        reaction3.add_metabolites({A: 1})
        model.add_reactions([reaction1])
        model.add_reactions([reaction2])
        model.add_reactions([reaction3])

        optgp = OptGPSampler(model, 1, seed=42)
        achr = ACHRSampler(model, seed=42)
        optgp_samples = optgp.sample(100)
        achr_samples = achr.sample(100)
        assert any(optgp_samples.corr().abs() < 1.0)
        assert any(achr_samples.corr().abs() < 1.0)
        # > 95% are valid
        assert (sum(optgp.validate(optgp_samples) == "v") > 95)
        assert (sum(achr.validate(achr_samples) == "v") > 95)
예제 #7
0
 def test_quadratic(self, solver_test):
     solver, old_solution, infeasible_model = solver_test
     if not hasattr(solver, "set_quadratic_objective"):
         pytest.skip("no qp support")
     c = Metabolite("c")
     c._bound = 2
     x = Reaction("x")
     x.objective_coefficient = -0.5
     x.lower_bound = 0.
     y = Reaction("y")
     y.objective_coefficient = -0.5
     y.lower_bound = 0.
     x.add_metabolites({c: 1})
     y.add_metabolites({c: 1})
     m = Model()
     m.add_reactions([x, y])
     lp = solver.create_problem(m)
     quadratic_obj = scipy.sparse.eye(2) * 2
     solver.set_quadratic_objective(lp, quadratic_obj)
     solver.solve_problem(lp, objective_sense="minimize")
     solution = solver.format_solution(lp, m)
     assert solution.status == "optimal"
     # Respecting linear objectives also makes the objective value 1.
     assert abs(solution.f - 1.) < 10 ** -3
     assert abs(solution.x_dict["y"] - 1.) < 10 ** -3
     assert abs(solution.x_dict["y"] - 1.) < 10 ** -3
     # When the linear objectives are removed the objective value is 2.
     solver.change_variable_objective(lp, 0, 0.)
     solver.change_variable_objective(lp, 1, 0.)
     solver.solve_problem(lp, objective_sense="minimize")
     solution = solver.format_solution(lp, m)
     assert solution.status == "optimal"
     assert abs(solution.f - 2.) < 10 ** -3
     # test quadratic from solve function
     solution = solver.solve(m, quadratic_component=quadratic_obj,
                             objective_sense="minimize")
     assert solution.status == "optimal"
     assert abs(solution.f - 1.) < 10 ** -3
     c._bound = 6
     z = Reaction("z")
     x.objective_coefficient = 0.
     y.objective_coefficient = 0.
     z.lower_bound = 0.
     z.add_metabolites({c: 1})
     m.add_reaction(z)
     solution = solver.solve(m, quadratic_component=scipy.sparse.eye(3),
                             objective_sense="minimize")
     # should be 12 not 24 because 1/2 (V^T Q V)
     assert solution.status == "optimal"
     assert abs(solution.f - 6) < 10 ** -3
     assert abs(solution.x_dict["x"] - 2) < 10 ** -6
     assert abs(solution.x_dict["y"] - 2) < 10 ** -6
     assert abs(solution.x_dict["z"] - 2) < 10 ** -6
예제 #8
0
def constrainSumOfFluxes(cobra_model, rxn2avoid, SFvalue, objvalue):
    from cobra.core import Metabolite, Reaction

    temp = cobra_model.copy()
    SFMet = Metabolite("SFMet",
                       name="Sum of fluxes pseudometabolite",
                       compartment="c2")
    for rxn in cobra_model.reactions:
        if not rxn2avoid.__contains__(rxn.id):
            if rxn.id.__contains__("reverse"):
                temp.reactions.get_by_id(rxn.id).add_metabolites({SFMet: -1})
            else:
                temp.reactions.get_by_id(rxn.id).add_metabolites({SFMet: 1})
    SFRxn = Reaction("SFRxn", name="Sum of fluxes pseudoreaction")
    SFRxn.add_metabolites({SFMet: -1})
    SFRxn.lower_bound = SFvalue
    SFRxn.upper_bound = SFvalue
    temp.add_reaction(SFRxn)
    if (not objvalue == "") and (len(
        [rxn
         for rxn in temp.reactions if rxn.objective_coefficient == 1]) == 1):
        for rxn in [
                rxn for rxn in temp.reactions if rxn.objective_coefficient == 1
        ]:
            rxn.lower_bound = float(objvalue)
            rxn.upper_bound = float(objvalue)
    return temp
예제 #9
0
def test__normalize_pseudoreaction_demand():
    reaction = Reaction('DM_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): -1})
    reaction.lower_bound = 0
    reaction.upper_bound = 1000
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'DM_glu__L_c'
    assert reaction.subsystem == 'Intracellular demand'
예제 #10
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_exchange():
    reaction = Reaction('EX_gone')
    reaction.add_metabolites({Metabolite('glu__L_e'): -1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'EX_glu__L_e'
    assert reaction.subsystem == 'Extracellular exchange'
예제 #11
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_sink():
    reaction = Reaction('SInk_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): -1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'SK_glu__L_c'
    assert reaction.subsystem == 'Intracellular source/sink'
예제 #12
0
def test__normalize_pseudoreaction_sink():
    reaction = Reaction('SInk_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): -1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'SK_glu__L_c'
    assert reaction.subsystem == 'Intracellular source/sink'
예제 #13
0
def test_add_reactions_single_existing(model):
    rxn = model.reactions[0]
    r1 = Reaction(rxn.id)
    r1.add_metabolites({Metabolite("A"): -1, Metabolite("B"): 1})
    r1.lower_bound, r1.upper_bound = -999999.0, 999999.0
    model.add_reactions([r1])
    assert rxn in model.reactions
    assert r1 is not model.reactions.get_by_id(rxn.id)
예제 #14
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_demand():
    reaction = Reaction('DM_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): -1})
    reaction.lower_bound = 0
    reaction.upper_bound = 1000
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'DM_glu__L_c'
    assert reaction.subsystem == 'Intracellular demand'
예제 #15
0
def test__normalize_pseudoreaction_exchange():
    reaction = Reaction('EX_gone')
    reaction.add_metabolites({Metabolite('glu__L_e'): -1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'EX_glu__L_e'
    assert reaction.subsystem == 'Extracellular exchange'
예제 #16
0
 def test_add_reactions_single_existing(self, model):
     rxn = model.reactions[0]
     r1 = Reaction(rxn.id)
     r1.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1})
     r1.lower_bound, r1.upper_bound = -999999., 999999.
     model.add_reactions([r1])
     assert rxn in model.reactions
     assert r1 is not model.reactions.get_by_id(rxn.id)
예제 #17
0
def tiny_toy_model():
    model = Model("Toy Model")
    m1 = Metabolite("M1")
    d1 = Reaction("ex1")
    d1.add_metabolites({m1: -1})
    d1.upper_bound = 0
    d1.lower_bound = -1000
    model.add_reactions([d1])
    return model
예제 #18
0
def test__normalize_pseudoreaction_demand_reversed_prefer_sink_name():
    reaction = Reaction('sink_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): 1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    _normalize_pseudoreaction(reaction)
    assert list(reaction.metabolites.values()) == [-1]
    assert reaction.lower_bound == 0
    assert reaction.upper_bound == 1000
    assert reaction.id == 'SK_glu__L_c'
예제 #19
0
def test__normalize_pseudoreaction_sink_reversed():
    reaction = Reaction('Sink_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): 1})
    reaction.lower_bound = 0
    reaction.upper_bound = 50
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert list(reaction.metabolites.values()) == [-1]
    assert reaction.lower_bound == -50
    assert reaction.upper_bound == 0
    assert pseudo_id == 'SK_glu__L_c'
예제 #20
0
def test__normalize_pseudoreaction_demand_reversed():
    reaction = Reaction('DM_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): 1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert list(reaction.metabolites.values()) == [-1]
    assert reaction.lower_bound == 0
    assert reaction.upper_bound == 1000
    assert pseudo_id == 'DM_glu__L_c'
예제 #21
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_sink_reversed():
    reaction = Reaction('Sink_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): 1})
    reaction.lower_bound = 0
    reaction.upper_bound = 50
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert list(reaction.metabolites.values()) == [-1]
    assert reaction.lower_bound == -50
    assert reaction.upper_bound == 0
    assert pseudo_id == 'SK_glu__L_c'
예제 #22
0
def test__normalize_pseudoreaction_exchange_reversed():
    reaction = Reaction('EX_gone')
    reaction.add_metabolites({Metabolite('glu__L_e'): 1})
    reaction.lower_bound = 0
    reaction.upper_bound = 1000
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'EX_glu__L_e'
    assert reaction.lower_bound == -1000
    assert reaction.upper_bound == 0
    assert list(reaction.metabolites.values()) == [-1]
예제 #23
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_exchange_reversed():
    reaction = Reaction('EX_gone')
    reaction.add_metabolites({Metabolite('glu__L_e'): 1})
    reaction.lower_bound = 0
    reaction.upper_bound = 1000
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'EX_glu__L_e'
    assert reaction.lower_bound == -1000
    assert reaction.upper_bound == 0
    assert list(reaction.metabolites.values()) == [-1]
예제 #24
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_demand_reversed():
    reaction = Reaction('DM_gone')
    reaction.add_metabolites({Metabolite('glu__L_c'): 1})
    reaction.lower_bound = -1000
    reaction.upper_bound = 0
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert list(reaction.metabolites.values()) == [-1]
    assert reaction.lower_bound == 0
    assert reaction.upper_bound == 1000
    assert pseudo_id == 'DM_glu__L_c'
예제 #25
0
def construct_loopless_model(cobra_model):
    """Construct a loopless model.

    This adds MILP constraints to prevent flux from proceeding in a loop, as
    done in http://dx.doi.org/10.1016/j.bpj.2010.12.3707
    Please see the documentation for an explanation of the algorithm.

    This must be solved with an MILP capable solver.

    """
    # copy the model and make it irreversible
    model = cobra_model.copy()
    convert_to_irreversible(model)
    max_ub = max(model.reactions.list_attr("upper_bound"))
    # a dict for storing S^T
    thermo_stoic = {
        "thermo_var_" + metabolite.id: {}
        for metabolite in model.metabolites
    }
    # Slice operator is so that we don't get newly added metabolites
    original_metabolites = model.metabolites[:]
    for reaction in model.reactions[:]:
        # Boundary reactions are not subjected to these constraints
        if len(reaction._metabolites) == 1:
            continue
        # populate the S^T dict
        bound_id = "thermo_bound_" + reaction.id
        for met, stoic in iteritems(reaction._metabolites):
            thermo_stoic["thermo_var_" + met.id][bound_id] = stoic
        # I * 1000 > v --> I * 1000 - v > 0
        reaction_ind = Reaction(reaction.id + "_indicator")
        reaction_ind.variable_kind = "integer"
        reaction_ind.upper_bound = 1
        reaction_ub = Metabolite(reaction.id + "_ind_ub")
        reaction_ub._constraint_sense = "G"
        reaction.add_metabolites({reaction_ub: -1})
        reaction_ind.add_metabolites({reaction_ub: max_ub})
        # This adds a compensating term for 0 flux reactions, so we get
        # S^T x - (1 - I) * 1001 < -1 which becomes
        # S^T x < 1000 for 0 flux reactions and
        # S^T x < -1 for reactions with nonzero flux.
        reaction_bound = Metabolite(bound_id)
        reaction_bound._constraint_sense = "L"
        reaction_bound._bound = max_ub
        reaction_ind.add_metabolites({reaction_bound: max_ub + 1})
        model.add_reaction(reaction_ind)
    for metabolite in original_metabolites:
        metabolite_var = Reaction("thermo_var_" + metabolite.id)
        metabolite_var.lower_bound = -max_ub
        model.add_reaction(metabolite_var)
        metabolite_var.add_metabolites({
            model.metabolites.get_by_id(k): v
            for k, v in iteritems(thermo_stoic[metabolite_var.id])
        })
    return model
예제 #26
0
def test_add_reactions_duplicate(model):
    rxn = model.reactions[0]
    r1 = Reaction('r1')
    r1.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1})
    r1.lower_bound, r1.upper_bound = -999999., 999999.
    r2 = Reaction(rxn.id)
    r2.add_metabolites(
        {Metabolite('A'): -1, Metabolite('C'): 1, Metabolite('D'): 1})
    model.add_reactions([r1, r2])
    assert r1 in model.reactions
    assert rxn in model.reactions
    assert r2 is not model.reactions.get_by_id(rxn.id)
예제 #27
0
 def test_add_reactions_duplicate(self, model):
     rxn = model.reactions[0]
     r1 = Reaction('r1')
     r1.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1})
     r1.lower_bound, r1.upper_bound = -999999., 999999.
     r2 = Reaction(rxn.id)
     r2.add_metabolites(
         {Metabolite('A'): -1, Metabolite('C'): 1, Metabolite('D'): 1})
     model.add_reactions([r1, r2])
     assert r1 in model.reactions
     assert rxn in model.reactions
     assert r2 is not model.reactions.get_by_id(rxn.id)
예제 #28
0
파일: loopless.py 프로젝트: cdiener/cobrapy
def construct_loopless_model(cobra_model):
    """Construct a loopless model.

    This adds MILP constraints to prevent flux from proceeding in a loop, as
    done in http://dx.doi.org/10.1016/j.bpj.2010.12.3707
    Please see the documentation for an explanation of the algorithm.

    This must be solved with an MILP capable solver.

    """
    # copy the model and make it irreversible
    model = cobra_model.copy()
    convert_to_irreversible(model)
    max_ub = max(model.reactions.list_attr("upper_bound"))
    # a dict for storing S^T
    thermo_stoic = {"thermo_var_" + metabolite.id: {}
                    for metabolite in model.metabolites}
    # Slice operator is so that we don't get newly added metabolites
    original_metabolites = model.metabolites[:]
    for reaction in model.reactions[:]:
        # Boundary reactions are not subjected to these constraints
        if len(reaction._metabolites) == 1:
            continue
        # populate the S^T dict
        bound_id = "thermo_bound_" + reaction.id
        for met, stoic in iteritems(reaction._metabolites):
            thermo_stoic["thermo_var_" + met.id][bound_id] = stoic
        # I * 1000 > v --> I * 1000 - v > 0
        reaction_ind = Reaction(reaction.id + "_indicator")
        reaction_ind.variable_kind = "integer"
        reaction_ind.upper_bound = 1
        reaction_ub = Metabolite(reaction.id + "_ind_ub")
        reaction_ub._constraint_sense = "G"
        reaction.add_metabolites({reaction_ub: -1})
        reaction_ind.add_metabolites({reaction_ub: max_ub})
        # This adds a compensating term for 0 flux reactions, so we get
        # S^T x - (1 - I) * 1001 < -1 which becomes
        # S^T x < 1000 for 0 flux reactions and
        # S^T x < -1 for reactions with nonzero flux.
        reaction_bound = Metabolite(bound_id)
        reaction_bound._constraint_sense = "L"
        reaction_bound._bound = max_ub
        reaction_ind.add_metabolites({reaction_bound: max_ub + 1})
        model.add_reaction(reaction_ind)
    for metabolite in original_metabolites:
        metabolite_var = Reaction("thermo_var_" + metabolite.id)
        metabolite_var.lower_bound = -max_ub
        model.add_reaction(metabolite_var)
        metabolite_var.add_metabolites(
            {model.metabolites.get_by_id(k): v
             for k, v in iteritems(thermo_stoic[metabolite_var.id])})
    return model
예제 #29
0
def test__normalize_pseudoreaction_atpm_reversed():
    reaction = Reaction('notATPM')
    reaction.add_metabolites({Metabolite('atp_c'): 1,
                              Metabolite('h2o_c'): 1,
                              Metabolite('pi_c'): -1,
                              Metabolite('h_c'): -1,
                              Metabolite('adp_c'): -1})
    reaction.lower_bound = -50
    reaction.upper_bound = 100
    _normalize_pseudoreaction(reaction)
    assert reaction.id == 'ATPM'
    assert reaction.lower_bound == -100
    assert reaction.upper_bound == 50
예제 #30
0
def solver_test(request):
    solver = solvers.solver_dict[request.param]
    old_solution = 0.8739215
    infeasible_model = Model()
    metabolite_1 = Metabolite("met1")
    reaction_1 = Reaction("rxn1")
    reaction_2 = Reaction("rxn2")
    reaction_1.add_metabolites({metabolite_1: 1})
    reaction_2.add_metabolites({metabolite_1: 1})
    reaction_1.lower_bound = 1
    reaction_2.upper_bound = 2
    infeasible_model.add_reactions([reaction_1, reaction_2])
    return solver, old_solution, infeasible_model
예제 #31
0
파일: test_parse.py 프로젝트: SBRG/ome
def test__normalize_pseudoreaction_atpm_reversed():
    reaction = Reaction('notATPM')
    reaction.add_metabolites({Metabolite('atp_c'): 1,
                              Metabolite('h2o_c'): 1,
                              Metabolite('pi_c'): -1,
                              Metabolite('h_c'): -1,
                              Metabolite('adp_c'): -1})
    reaction.lower_bound = -50
    reaction.upper_bound = 100
    pseudo_id = _normalize_pseudoreaction(reaction.id, reaction)
    assert pseudo_id == 'ATPM'
    assert reaction.lower_bound == -100
    assert reaction.upper_bound == 50
예제 #32
0
파일: moma.py 프로젝트: sandrejev/bioopt
def construct_difference_model(model_1, model_2, norm_type='euclidean'):
    """Combine two models into a larger model that is designed to calculate differences
    between the models

    """
    #Get index mappings
    common_dict = {}
    #Using copies of the models so things are modified above
    combined_model = model_1 = model_1.copy()
    model_2 = model_2.copy()
    for reaction_1 in model_1.reactions:
        try:
            reaction_2 = model_2.reactions.get_by_id(reaction_1.id)
            common_dict[reaction_1] = reaction_2
        except:
            continue
            
    #Add a prefix in front of the mutant_model metabolites and reactions to prevent
    #name collisions in DictList
    for the_dict_list in [model_2.metabolites,
                          model_2.reactions]:
        [setattr(x, 'id', 'mutant_%s'%x.id)
         for x in the_dict_list]
        the_dict_list._generate_index() #Update the DictList.dicts

    
    combined_model.add_reactions(model_2.reactions)
    [setattr(x, 'objective_coefficient', 0.)
     for x in combined_model.reactions]
    #Add in the difference reactions.  The mutant reactions and metabolites are already added.
    #This must be a list to maintain the correct order when adding the difference_metabolites
    difference_reactions = [] #Add the difference reactions at the end to speed things up
    difference_metabolites = []
    for reaction_1, reaction_2 in iteritems(common_dict):
        reaction_1._difference_partner = reaction_2
        reaction_2._difference_partner = reaction_1
        difference_reaction = Reaction('difference_%s'%reaction_1.id)
        difference_reactions.append(difference_reaction)
        difference_reaction.upper_bound = 100000
        difference_reaction.lower_bound = -1* difference_reaction.upper_bound
        difference_metabolite = Metabolite('difference_%s'%reaction_1.id)
        difference_metabolites.append(difference_metabolite)
        if norm_type == 'linear':
            difference_metabolite._constraint_sense = 'G'
        reaction_1.add_metabolites({difference_metabolite: -1.}, add_to_container_model=False)
        reaction_2.add_metabolites({difference_metabolite: 1.}, add_to_container_model=False)
        difference_reaction.add_metabolites({difference_metabolite: 1.}, add_to_container_model=False)

    combined_model.add_metabolites(difference_metabolites)
    combined_model.add_reactions(difference_reactions)
    return(combined_model)
예제 #33
0
def test_add_reactions_duplicate(model):
    rxn = model.reactions[0]
    r1 = Reaction("r1")
    r1.add_metabolites({Metabolite("A"): -1, Metabolite("B"): 1})
    r1.lower_bound, r1.upper_bound = -999999.0, 999999.0
    r2 = Reaction(rxn.id)
    r2.add_metabolites({
        Metabolite("A"): -1,
        Metabolite("C"): 1,
        Metabolite("D"): 1
    })
    model.add_reactions([r1, r2])
    assert r1 in model.reactions
    assert rxn in model.reactions
    assert r2 is not model.reactions.get_by_id(rxn.id)
예제 #34
0
def test_add_reactions(model):
    r1 = Reaction("r1")
    r1.add_metabolites({Metabolite("A"): -1, Metabolite("B"): 1})
    r1.lower_bound, r1.upper_bound = -999999.0, 999999.0
    r2 = Reaction("r2")
    r2.add_metabolites({
        Metabolite("A"): -1,
        Metabolite("C"): 1,
        Metabolite("D"): 1
    })
    r2.lower_bound, r2.upper_bound = 0.0, 999999.0
    model.add_reactions([r1, r2])
    r2.objective_coefficient = 3.0
    assert r2.objective_coefficient == 3.0
    assert model.reactions[-2] == r1
    assert model.reactions[-1] == r2
    assert isinstance(model.reactions[-2].reverse_variable,
                      model.problem.Variable)
    coefficients_dict = model.objective.expression.as_coefficients_dict()
    biomass_r = model.reactions.get_by_id("Biomass_Ecoli_core")
    assert coefficients_dict[biomass_r.forward_variable] == 1.0
    assert coefficients_dict[biomass_r.reverse_variable] == -1.0
    assert coefficients_dict[model.reactions.r2.forward_variable] == 3.0
    assert coefficients_dict[model.reactions.r2.reverse_variable] == -3.0
예제 #35
0
 def test_add_reactions(self, model):
     r1 = Reaction('r1')
     r1.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1})
     r1.lower_bound, r1.upper_bound = -999999., 999999.
     r2 = Reaction('r2')
     r2.add_metabolites(
         {Metabolite('A'): -1, Metabolite('C'): 1, Metabolite('D'): 1})
     r2.lower_bound, r2.upper_bound = 0., 999999.
     model.add_reactions([r1, r2])
     r2.objective_coefficient = 3.
     assert r2.objective_coefficient == 3.
     assert model.reactions[-2] == r1
     assert model.reactions[-1] == r2
     assert isinstance(model.reactions[-2].reverse_variable,
                       model.problem.Variable)
     coefficients_dict = model.objective.expression. \
         as_coefficients_dict()
     biomass_r = model.reactions.get_by_id('Biomass_Ecoli_core')
     assert coefficients_dict[biomass_r.forward_variable] == 1.
     assert coefficients_dict[biomass_r.reverse_variable] == -1.
     assert coefficients_dict[
                model.reactions.r2.forward_variable] == 3.
     assert coefficients_dict[
                model.reactions.r2.reverse_variable] == -3.
예제 #36
0
 def test_array_based_model_add(self, model):
     array_model = model.to_array_based_model()
     m = len(array_model.metabolites)
     n = len(array_model.reactions)
     for matrix_type in ["scipy.dok_matrix", "scipy.lil_matrix"]:
         test_model = model.copy().to_array_based_model(
             matrix_type=matrix_type)
         test_reaction = Reaction("test")
         test_reaction.add_metabolites({test_model.metabolites[0]: 4})
         test_reaction.lower_bound = -3.14
         test_model.add_reaction(test_reaction)
         assert len(test_model.reactions) == n + 1
         assert test_model.S.shape == (m, n + 1)
         assert len(test_model.lower_bounds) == n + 1
         assert len(test_model.upper_bounds) == n + 1
         assert test_model.S[0, n] == 4
         assert test_model.S[7, 0] == -1
         assert test_model.lower_bounds[n] == -3.14
예제 #37
0
def add_reaction(model, id, name, sparse,
                 lower_bound=0, upper_bound=1000):
    """
        Adds a reaction to the model
    """
    # convert the sparse representation using the metabolites in the model
    for key in sparse.keys():
        if key not in model.metabolites:
            raise Exception("cannot find the cytoplasmic metabolite %s in the model" % key)

    r = dict([(model.metabolites[model.metabolites.index(key)], val)
              for key, val in sparse.iteritems()])
    reaction = Reaction(name)
    reaction.id = id
    reaction.add_metabolites(r)
    reaction.lower_bound = lower_bound
    reaction.upper_bound = upper_bound
    model.add_reactions([reaction])
    return reaction
예제 #38
0
def convert_to_irreversible(model):
    """Split reversible reactions into two irreversible reactions

    These two reactions will proceed in opposite directions. This
    guarentees that all reactions in the model will only allow
    positive flux values, which is useful for some modeling problems.

    Arguments
    ----------
    * model: cobra.Model ~ A Model object which will be modified in place.

    """
    #warn("deprecated, not applicable for optlang solvers", DeprecationWarning)
    reactions_to_add = []
    coefficients = {}
    for reaction in model.reactions:
        # If a reaction is reverse only, the forward reaction (which
        # will be constrained to 0) will be left in the model.
        if reaction.lower_bound < 0 and reaction.upper_bound > 0:
            reverse_reaction = Reaction(reaction.id + "_reverse")
            reverse_reaction.lower_bound = max(0, -reaction.upper_bound)
            reverse_reaction.upper_bound = -reaction.lower_bound
            coefficients[
                reverse_reaction] = reaction.objective_coefficient * -1
            reaction.lower_bound = max(0, reaction.lower_bound)
            reaction.upper_bound = max(0, reaction.upper_bound)
            # Make the directions aware of each other
            reaction.notes["reflection"] = reverse_reaction.id
            reverse_reaction.notes["reflection"] = reaction.id
            reaction_dict = {
                k: v * -1
                for k, v in reaction._metabolites.items()
            }
            reverse_reaction.add_metabolites(reaction_dict)
            reverse_reaction._model = reaction._model
            reverse_reaction._genes = reaction._genes
            for gene in reaction._genes:
                gene._reaction.add(reverse_reaction)
            reverse_reaction.subsystem = reaction.subsystem
            reverse_reaction._gene_reaction_rule = reaction._gene_reaction_rule
            reactions_to_add.append(reverse_reaction)
    model.add_reactions(reactions_to_add)
    set_objective(model, coefficients, additive=True)
예제 #39
0
def test_make_lhs_irreversible_reversible(model):
    rxn = Reaction('test')
    rxn.add_metabolites({model.metabolites[0]: -1., model.metabolites[1]: 1.})
    rxn.lower_bound = -1000.
    rxn.upper_bound = -100
    model.add_reaction(rxn)
    assert rxn.lower_bound == -1000.
    assert rxn.upper_bound == -100.
    assert rxn.forward_variable.lb == 0.
    assert rxn.forward_variable.ub == 0.
    assert rxn.reverse_variable.lb == 100.
    assert rxn.reverse_variable.ub == 1000.
    rxn.upper_bound = 666.
    assert rxn.lower_bound == -1000.
    assert rxn.upper_bound == 666.
    assert rxn.forward_variable.lb == 0.
    assert rxn.forward_variable.ub == 666
    assert rxn.reverse_variable.lb == 0.
    assert rxn.reverse_variable.ub == 1000.
예제 #40
0
def add_reaction(model, id, name, sparse,
                 lower_bound=0, upper_bound=1000):
    """
        Adds a reaction to the model
    """
    # convert the sparse representation using the metabolites in the model
    for key in sparse.keys():
        if key not in model.metabolites:
            raise Exception("cannot find the cytoplasmic metabolite %s in the model" % key)

    r = dict([(model.metabolites[model.metabolites.index(key)], val)
              for key, val in sparse.iteritems()])
    reaction = Reaction(name)
    reaction.id = id
    reaction.add_metabolites(r)
    reaction.lower_bound = lower_bound
    reaction.upper_bound = upper_bound
    model.add_reactions([reaction])
    return reaction
예제 #41
0
def test_make_lhs_irreversible_reversible(model):
    rxn = Reaction('test')
    rxn.add_metabolites(
        {model.metabolites[0]: -1., model.metabolites[1]: 1.})
    rxn.lower_bound = -1000.
    rxn.upper_bound = -100
    model.add_reaction(rxn)
    assert rxn.lower_bound == -1000.
    assert rxn.upper_bound == -100.
    assert rxn.forward_variable.lb == 0.
    assert rxn.forward_variable.ub == 0.
    assert rxn.reverse_variable.lb == 100.
    assert rxn.reverse_variable.ub == 1000.
    rxn.upper_bound = 666.
    assert rxn.lower_bound == -1000.
    assert rxn.upper_bound == 666.
    assert rxn.forward_variable.lb == 0.
    assert rxn.forward_variable.ub == 666
    assert rxn.reverse_variable.lb == 0.
    assert rxn.reverse_variable.ub == 1000.
예제 #42
0
파일: modify.py 프로젝트: cdiener/cobrapy
def convert_to_irreversible(cobra_model):
    """Split reversible reactions into two irreversible reactions

    These two reactions will proceed in opposite directions. This
    guarentees that all reactions in the model will only allow
    positive flux values, which is useful for some modeling problems.

    cobra_model: A Model object which will be modified in place.

    """
    warn("deprecated, not applicable for optlang solvers", DeprecationWarning)
    reactions_to_add = []
    coefficients = {}
    for reaction in cobra_model.reactions:
        # If a reaction is reverse only, the forward reaction (which
        # will be constrained to 0) will be left in the model.
        if reaction.lower_bound < 0:
            reverse_reaction = Reaction(reaction.id + "_reverse")
            reverse_reaction.lower_bound = max(0, -reaction.upper_bound)
            reverse_reaction.upper_bound = -reaction.lower_bound
            coefficients[
                reverse_reaction] = reaction.objective_coefficient * -1
            reaction.lower_bound = max(0, reaction.lower_bound)
            reaction.upper_bound = max(0, reaction.upper_bound)
            # Make the directions aware of each other
            reaction.notes["reflection"] = reverse_reaction.id
            reverse_reaction.notes["reflection"] = reaction.id
            reaction_dict = {k: v * -1
                             for k, v in iteritems(reaction._metabolites)}
            reverse_reaction.add_metabolites(reaction_dict)
            reverse_reaction._model = reaction._model
            reverse_reaction._genes = reaction._genes
            for gene in reaction._genes:
                gene._reaction.add(reverse_reaction)
            reverse_reaction.subsystem = reaction.subsystem
            reverse_reaction._gene_reaction_rule = reaction._gene_reaction_rule
            reactions_to_add.append(reverse_reaction)
    cobra_model.add_reactions(reactions_to_add)
    set_objective(cobra_model, coefficients, additive=True)
예제 #43
0
파일: mat.py 프로젝트: opencobra/cobrapy
def from_mat_struct(mat_struct, model_id=None, inf=inf):
    """create a model from the COBRA toolbox struct

    The struct will be a dict read in by scipy.io.loadmat

    """
    m = mat_struct
    if m.dtype.names is None:
        raise ValueError("not a valid mat struct")
    if not {"rxns", "mets", "S", "lb", "ub"} <= set(m.dtype.names):
        raise ValueError("not a valid mat struct")
    if "c" in m.dtype.names:
        c_vec = m["c"][0, 0]
    else:
        c_vec = None
        warn("objective vector 'c' not found")
    model = Model()
    if model_id is not None:
        model.id = model_id
    elif "description" in m.dtype.names:
        description = m["description"][0, 0][0]
        if not isinstance(description, string_types) and len(description) > 1:
            model.id = description[0]
            warn("Several IDs detected, only using the first.")
        else:
            model.id = description
    else:
        model.id = "imported_model"
    for i, name in enumerate(m["mets"][0, 0]):
        new_metabolite = Metabolite()
        new_metabolite.id = str(name[0][0])
        if all(var in m.dtype.names for var in
               ['metComps', 'comps', 'compNames']):
            comp_index = m["metComps"][0, 0][i][0] - 1
            new_metabolite.compartment = m['comps'][0, 0][comp_index][0][0]
            if new_metabolite.compartment not in model.compartments:
                comp_name = m['compNames'][0, 0][comp_index][0][0]
                model.compartments[new_metabolite.compartment] = comp_name
        else:
            new_metabolite.compartment = _get_id_compartment(new_metabolite.id)
            if new_metabolite.compartment not in model.compartments:
                model.compartments[
                    new_metabolite.compartment] = new_metabolite.compartment
        try:
            new_metabolite.name = str(m["metNames"][0, 0][i][0][0])
        except (IndexError, ValueError):
            pass
        try:
            new_metabolite.formula = str(m["metFormulas"][0][0][i][0][0])
        except (IndexError, ValueError):
            pass
        try:
            new_metabolite.charge = float(m["metCharge"][0, 0][i][0])
            int_charge = int(new_metabolite.charge)
            if new_metabolite.charge == int_charge:
                new_metabolite.charge = int_charge
        except (IndexError, ValueError):
            pass
        model.add_metabolites([new_metabolite])
    new_reactions = []
    coefficients = {}
    for i, name in enumerate(m["rxns"][0, 0]):
        new_reaction = Reaction()
        new_reaction.id = str(name[0][0])
        new_reaction.lower_bound = float(m["lb"][0, 0][i][0])
        new_reaction.upper_bound = float(m["ub"][0, 0][i][0])
        if isinf(new_reaction.lower_bound) and new_reaction.lower_bound < 0:
            new_reaction.lower_bound = -inf
        if isinf(new_reaction.upper_bound) and new_reaction.upper_bound > 0:
            new_reaction.upper_bound = inf
        if c_vec is not None:
            coefficients[new_reaction] = float(c_vec[i][0])
        try:
            new_reaction.gene_reaction_rule = str(m['grRules'][0, 0][i][0][0])
        except (IndexError, ValueError):
            pass
        try:
            new_reaction.name = str(m["rxnNames"][0, 0][i][0][0])
        except (IndexError, ValueError):
            pass
        try:
            new_reaction.subsystem = str(m['subSystems'][0, 0][i][0][0])
        except (IndexError, ValueError):
            pass
        new_reactions.append(new_reaction)
    model.add_reactions(new_reactions)
    set_objective(model, coefficients)
    coo = scipy_sparse.coo_matrix(m["S"][0, 0])
    for i, j, v in zip(coo.row, coo.col, coo.data):
        model.reactions[j].add_metabolites({model.metabolites[i]: v})
    return model
예제 #44
0
파일: sbml.py 프로젝트: cdiener/cobrapy
def create_cobra_model_from_sbml_file(sbml_filename, old_sbml=False,
                                      legacy_metabolite=False,
                                      print_time=False, use_hyphens=False):
    """convert an SBML XML file into a cobra.Model object.

    Supports SBML Level 2 Versions 1 and 4.  The function will detect if the
    SBML fbc package is used in the file and run the converter if the fbc
    package is used.

    Parameters
    ----------
    sbml_filename: string
    old_sbml: bool
        Set to True if the XML file has metabolite formula appended to
        metabolite names. This was a poorly designed artifact that persists in
        some models.
    legacy_metabolite: bool
        If True then assume that the metabolite id has the compartment id
         appended after an underscore (e.g. _c for cytosol). This has not been
         implemented but will be soon.
    print_time: bool
         deprecated
    use_hyphens: bool
        If True, double underscores (__) in an SBML ID will be converted to
        hyphens

    Returns
    -------
    Model : The parsed cobra model
    """
    if not libsbml:
        raise ImportError('create_cobra_model_from_sbml_file '
                          'requires python-libsbml')

    __default_lower_bound = -1000
    __default_upper_bound = 1000
    __default_objective_coefficient = 0
    # Ensure that the file exists
    if not isfile(sbml_filename):
        raise IOError('Your SBML file is not found: %s' % sbml_filename)
    # Expressions to change SBML Ids to Palsson Lab Ids
    metabolite_re = re.compile('^M_')
    reaction_re = re.compile('^R_')
    compartment_re = re.compile('^C_')
    if print_time:
        warn("print_time is deprecated", DeprecationWarning)
    model_doc = libsbml.readSBML(sbml_filename)
    if model_doc.getPlugin("fbc") is not None:
        from libsbml import ConversionProperties, LIBSBML_OPERATION_SUCCESS
        conversion_properties = ConversionProperties()
        conversion_properties.addOption(
            "convert fbc to cobra", True, "Convert FBC model to Cobra model")
        result = model_doc.convert(conversion_properties)
        if result != LIBSBML_OPERATION_SUCCESS:
            raise Exception("Conversion of SBML+fbc to COBRA failed")
    sbml_model = model_doc.getModel()
    sbml_model_id = sbml_model.getId()
    sbml_species = sbml_model.getListOfSpecies()
    sbml_reactions = sbml_model.getListOfReactions()
    sbml_compartments = sbml_model.getListOfCompartments()
    compartment_dict = dict([(compartment_re.split(x.getId())[-1], x.getName())
                             for x in sbml_compartments])
    if legacy_metabolite:
        # Deal with the palsson lab appending the compartment id to the
        # metabolite id
        new_dict = {}
        for the_id, the_name in compartment_dict.items():
            if the_name == '':
                new_dict[the_id[0].lower()] = the_id
            else:
                new_dict[the_id] = the_name
        compartment_dict = new_dict
        legacy_compartment_converter = dict(
            [(v, k) for k, v in iteritems(compartment_dict)])

    cobra_model = Model(sbml_model_id)
    metabolites = []
    metabolite_dict = {}
    # Convert sbml_metabolites to cobra.Metabolites
    for sbml_metabolite in sbml_species:
        # Skip sbml boundary species
        if sbml_metabolite.getBoundaryCondition():
            continue

        if (old_sbml or legacy_metabolite) and \
                sbml_metabolite.getId().endswith('_b'):
            # Deal with incorrect sbml from bigg.ucsd.edu
            continue
        tmp_metabolite = Metabolite()
        metabolite_id = tmp_metabolite.id = sbml_metabolite.getId()
        tmp_metabolite.compartment = compartment_re.split(
            sbml_metabolite.getCompartment())[-1]
        if legacy_metabolite:
            if tmp_metabolite.compartment not in compartment_dict:
                tmp_metabolite.compartment = legacy_compartment_converter[
                    tmp_metabolite.compartment]
            tmp_metabolite.id = parse_legacy_id(
                tmp_metabolite.id, tmp_metabolite.compartment,
                use_hyphens=use_hyphens)
        if use_hyphens:
            tmp_metabolite.id = metabolite_re.split(
                tmp_metabolite.id)[-1].replace('__', '-')
        else:
            # Just in case the SBML ids are ill-formed and use -
            tmp_metabolite.id = metabolite_re.split(
                tmp_metabolite.id)[-1].replace('-', '__')
        tmp_metabolite.name = sbml_metabolite.getName()
        tmp_formula = ''
        tmp_metabolite.notes = parse_legacy_sbml_notes(
            sbml_metabolite.getNotesString())
        if sbml_metabolite.isSetCharge():
            tmp_metabolite.charge = sbml_metabolite.getCharge()
        if "CHARGE" in tmp_metabolite.notes:
            note_charge = tmp_metabolite.notes["CHARGE"][0]
            try:
                note_charge = float(note_charge)
                if note_charge == int(note_charge):
                    note_charge = int(note_charge)
            except:
                warn("charge of %s is not a number (%s)" %
                     (tmp_metabolite.id, str(note_charge)))
            else:
                if ((tmp_metabolite.charge is None) or
                        (tmp_metabolite.charge == note_charge)):
                    tmp_metabolite.notes.pop("CHARGE")
                    # set charge to the one from notes if not assigend before
                    # the same
                    tmp_metabolite.charge = note_charge
                else:  # tmp_metabolite.charge != note_charge
                    msg = "different charges specified for %s (%d and %d)"
                    msg = msg % (tmp_metabolite.id,
                                 tmp_metabolite.charge, note_charge)
                    warn(msg)
                    # Chances are a 0 note charge was written by mistake. We
                    # will default to the note_charge in this case.
                    if tmp_metabolite.charge == 0:
                        tmp_metabolite.charge = note_charge

        for the_key in tmp_metabolite.notes.keys():
            if the_key.lower() == 'formula':
                tmp_formula = tmp_metabolite.notes.pop(the_key)[0]
                break
        if tmp_formula == '' and old_sbml:
            tmp_formula = tmp_metabolite.name.split('_')[-1]
            tmp_metabolite.name = tmp_metabolite.name[:-len(tmp_formula) - 1]
        tmp_metabolite.formula = tmp_formula
        metabolite_dict.update({metabolite_id: tmp_metabolite})
        metabolites.append(tmp_metabolite)
    cobra_model.add_metabolites(metabolites)

    # Construct the vectors and matrices for holding connectivity and numerical
    # info to feed to the cobra toolbox.
    # Always assume steady state simulations so b is set to 0
    cobra_reaction_list = []
    coefficients = {}
    for sbml_reaction in sbml_reactions:
        if use_hyphens:
            # Change the ids to match conventions used by the Palsson lab.
            reaction = Reaction(reaction_re.split(
                sbml_reaction.getId())[-1].replace('__', '-'))
        else:
            # Just in case the SBML ids are ill-formed and use -
            reaction = Reaction(reaction_re.split(
                sbml_reaction.getId())[-1].replace('-', '__'))
        cobra_reaction_list.append(reaction)
        # reaction.exchange_reaction = 0
        reaction.name = sbml_reaction.getName()
        cobra_metabolites = {}
        # Use the cobra.Metabolite class here
        for sbml_metabolite in sbml_reaction.getListOfReactants():
            tmp_metabolite_id = sbml_metabolite.getSpecies()
            # This deals with boundary metabolites
            if tmp_metabolite_id in metabolite_dict:
                tmp_metabolite = metabolite_dict[tmp_metabolite_id]
                cobra_metabolites[tmp_metabolite] = - \
                    sbml_metabolite.getStoichiometry()
        for sbml_metabolite in sbml_reaction.getListOfProducts():
            tmp_metabolite_id = sbml_metabolite.getSpecies()
            # This deals with boundary metabolites
            if tmp_metabolite_id in metabolite_dict:
                tmp_metabolite = metabolite_dict[tmp_metabolite_id]
                # Handle the case where the metabolite was specified both
                # as a reactant and as a product.
                if tmp_metabolite in cobra_metabolites:
                    warn("%s appears as a reactant and product %s" %
                         (tmp_metabolite_id, reaction.id))
                    cobra_metabolites[
                        tmp_metabolite] += sbml_metabolite.getStoichiometry()
                    # if the combined stoichiometry is 0, remove the metabolite
                    if cobra_metabolites[tmp_metabolite] == 0:
                        cobra_metabolites.pop(tmp_metabolite)
                else:
                    cobra_metabolites[
                        tmp_metabolite] = sbml_metabolite.getStoichiometry()
        # check for nan
        for met, v in iteritems(cobra_metabolites):
            if isnan(v) or isinf(v):
                warn("invalid value %s for metabolite '%s' in reaction '%s'" %
                     (str(v), met.id, reaction.id))
        reaction.add_metabolites(cobra_metabolites)
        # Parse the kinetic law info here.
        parameter_dict = {}
        # If lower and upper bounds are specified in the Kinetic Law then
        # they override the sbml reversible attribute.  If they are not
        # specified then the bounds are determined by getReversible.
        if not sbml_reaction.getKineticLaw():

            if sbml_reaction.getReversible():
                parameter_dict['lower_bound'] = __default_lower_bound
                parameter_dict['upper_bound'] = __default_upper_bound
            else:
                # Assume that irreversible reactions only proceed from left to
                # right.
                parameter_dict['lower_bound'] = 0
                parameter_dict['upper_bound'] = __default_upper_bound

            parameter_dict[
                'objective_coefficient'] = __default_objective_coefficient
        else:
            for sbml_parameter in \
                    sbml_reaction.getKineticLaw().getListOfParameters():
                parameter_dict[
                    sbml_parameter.getId().lower()] = sbml_parameter.getValue()

        if 'lower_bound' in parameter_dict:
            reaction.lower_bound = parameter_dict['lower_bound']
        elif 'lower bound' in parameter_dict:
            reaction.lower_bound = parameter_dict['lower bound']
        elif sbml_reaction.getReversible():
            reaction.lower_bound = __default_lower_bound
        else:
            reaction.lower_bound = 0

        if 'upper_bound' in parameter_dict:
            reaction.upper_bound = parameter_dict['upper_bound']
        elif 'upper bound' in parameter_dict:
            reaction.upper_bound = parameter_dict['upper bound']
        else:
            reaction.upper_bound = __default_upper_bound

        objective_coefficient = parameter_dict.get(
            'objective_coefficient', parameter_dict.get(
                'objective_coefficient', __default_objective_coefficient))
        if objective_coefficient != 0:
            coefficients[reaction] = objective_coefficient

        # ensure values are not set to nan or inf
        if isnan(reaction.lower_bound) or isinf(reaction.lower_bound):
            reaction.lower_bound = __default_lower_bound
        if isnan(reaction.upper_bound) or isinf(reaction.upper_bound):
            reaction.upper_bound = __default_upper_bound

        reaction_note_dict = parse_legacy_sbml_notes(
            sbml_reaction.getNotesString())
        # Parse the reaction notes.
        # POTENTIAL BUG: DEALING WITH LEGACY 'SBML' THAT IS NOT IN A
        # STANDARD FORMAT
        # TODO: READ IN OTHER NOTES AND GIVE THEM A reaction_ prefix.
        # TODO: Make sure genes get added as objects
        if 'GENE ASSOCIATION' in reaction_note_dict:
            rule = reaction_note_dict['GENE ASSOCIATION'][0]
            try:
                rule.encode('ascii')
            except (UnicodeEncodeError, UnicodeDecodeError):
                warn("gene_reaction_rule '%s' is not ascii compliant" % rule)
            if rule.startswith("&quot;") and rule.endswith("&quot;"):
                rule = rule[6:-6]
            reaction.gene_reaction_rule = rule
            if 'GENE LIST' in reaction_note_dict:
                reaction.systematic_names = reaction_note_dict['GENE LIST'][0]
            elif ('GENES' in reaction_note_dict and
                  reaction_note_dict['GENES'] != ['']):
                reaction.systematic_names = reaction_note_dict['GENES'][0]
            elif 'LOCUS' in reaction_note_dict:
                gene_id_to_object = dict([(x.id, x) for x in reaction._genes])
                for the_row in reaction_note_dict['LOCUS']:
                    tmp_row_dict = {}
                    the_row = 'LOCUS:' + the_row.lstrip('_').rstrip('#')
                    for the_item in the_row.split('#'):
                        k, v = the_item.split(':')
                        tmp_row_dict[k] = v
                    tmp_locus_id = tmp_row_dict['LOCUS']
                    if 'TRANSCRIPT' in tmp_row_dict:
                        tmp_locus_id = tmp_locus_id + \
                                       '.' + tmp_row_dict['TRANSCRIPT']

                    if 'ABBREVIATION' in tmp_row_dict:
                        gene_id_to_object[tmp_locus_id].name = tmp_row_dict[
                            'ABBREVIATION']

        if 'SUBSYSTEM' in reaction_note_dict:
            reaction.subsystem = reaction_note_dict.pop('SUBSYSTEM')[0]

        reaction.notes = reaction_note_dict

    # Now, add all of the reactions to the model.
    cobra_model.id = sbml_model.getId()
    # Populate the compartment list - This will be done based on
    # cobra.Metabolites in cobra.Reactions in the future.
    cobra_model.compartments = compartment_dict

    cobra_model.add_reactions(cobra_reaction_list)
    set_objective(cobra_model, coefficients)
    return cobra_model
예제 #45
0
파일: sbml3.py 프로젝트: tpfau/cobrapy
def parse_xml_into_model(xml, number=float):
    xml_model = xml.find(ns("sbml:model"))
    if get_attrib(xml_model, "fbc:strict") != "true":
        warn('loading SBML model without fbc:strict="true"')

    model_id = get_attrib(xml_model, "id")
    model = Model(model_id)
    model.name = xml_model.get("name")

    model.compartments = {c.get("id"): c.get("name") for c in
                          xml_model.findall(COMPARTMENT_XPATH)}
    # add metabolites
    for species in xml_model.findall(SPECIES_XPATH % 'false'):
        met = get_attrib(species, "id", require=True)
        met = Metabolite(clip(met, "M_"))
        met.name = species.get("name")
        annotate_cobra_from_sbml(met, species)
        met.compartment = species.get("compartment")
        met.charge = get_attrib(species, "fbc:charge", int)
        met.formula = get_attrib(species, "fbc:chemicalFormula")
        model.add_metabolites([met])
    # Detect boundary metabolites - In case they have been mistakenly
    # added. They should not actually appear in a model
    boundary_metabolites = {clip(i.get("id"), "M_")
                            for i in xml_model.findall(SPECIES_XPATH % 'true')}

    # add genes
    for sbml_gene in xml_model.iterfind(GENES_XPATH):
        gene_id = get_attrib(sbml_gene, "fbc:id").replace(SBML_DOT, ".")
        gene = Gene(clip(gene_id, "G_"))
        gene.name = get_attrib(sbml_gene, "fbc:name")
        if gene.name is None:
            gene.name = get_attrib(sbml_gene, "fbc:label")
        annotate_cobra_from_sbml(gene, sbml_gene)
        model.genes.append(gene)

    def process_gpr(sub_xml):
        """recursively convert gpr xml to a gpr string"""
        if sub_xml.tag == OR_TAG:
            return "( " + ' or '.join(process_gpr(i) for i in sub_xml) + " )"
        elif sub_xml.tag == AND_TAG:
            return "( " + ' and '.join(process_gpr(i) for i in sub_xml) + " )"
        elif sub_xml.tag == GENEREF_TAG:
            gene_id = get_attrib(sub_xml, "fbc:geneProduct", require=True)
            return clip(gene_id, "G_")
        else:
            raise Exception("unsupported tag " + sub_xml.tag)

    bounds = {bound.get("id"): get_attrib(bound, "value", type=number)
              for bound in xml_model.iterfind(BOUND_XPATH)}
    # add reactions
    reactions = []
    for sbml_reaction in xml_model.iterfind(
            ns("sbml:listOfReactions/sbml:reaction")):
        reaction = get_attrib(sbml_reaction, "id", require=True)
        reaction = Reaction(clip(reaction, "R_"))
        reaction.name = sbml_reaction.get("name")
        annotate_cobra_from_sbml(reaction, sbml_reaction)
        lb_id = get_attrib(sbml_reaction, "fbc:lowerFluxBound", require=True)
        ub_id = get_attrib(sbml_reaction, "fbc:upperFluxBound", require=True)
        try:
            reaction.upper_bound = bounds[ub_id]
            reaction.lower_bound = bounds[lb_id]
        except KeyError as e:
            raise CobraSBMLError("No constant bound with id '%s'" % str(e))
        reactions.append(reaction)

        stoichiometry = defaultdict(lambda: 0)
        for species_reference in sbml_reaction.findall(
                ns("sbml:listOfReactants/sbml:speciesReference")):
            met_name = clip(species_reference.get("species"), "M_")
            stoichiometry[met_name] -= \
                number(species_reference.get("stoichiometry"))
        for species_reference in sbml_reaction.findall(
                ns("sbml:listOfProducts/sbml:speciesReference")):
            met_name = clip(species_reference.get("species"), "M_")
            stoichiometry[met_name] += \
                get_attrib(species_reference, "stoichiometry",
                           type=number, require=True)
        # needs to have keys of metabolite objects, not ids
        object_stoichiometry = {}
        for met_id in stoichiometry:
            if met_id in boundary_metabolites:
                warn("Boundary metabolite '%s' used in reaction '%s'" %
                     (met_id, reaction.id))
                continue
            try:
                metabolite = model.metabolites.get_by_id(met_id)
            except KeyError:
                warn("ignoring unknown metabolite '%s' in reaction %s" %
                     (met_id, reaction.id))
                continue
            object_stoichiometry[metabolite] = stoichiometry[met_id]
        reaction.add_metabolites(object_stoichiometry)
        # set gene reaction rule
        gpr_xml = sbml_reaction.find(GPR_TAG)
        if gpr_xml is not None and len(gpr_xml) != 1:
            warn("ignoring invalid geneAssociation for " + repr(reaction))
            gpr_xml = None
        gpr = process_gpr(gpr_xml[0]) if gpr_xml is not None else ''
        # remove outside parenthesis, if any
        if gpr.startswith("(") and gpr.endswith(")"):
            gpr = gpr[1:-1].strip()
        gpr = gpr.replace(SBML_DOT, ".")
        reaction.gene_reaction_rule = gpr
    try:
        model.add_reactions(reactions)
    except ValueError as e:
        warn(str(e))

    # objective coefficients are handled after all reactions are added
    obj_list = xml_model.find(ns("fbc:listOfObjectives"))
    if obj_list is None:
        warn("listOfObjectives element not found")
        return model
    target_objective_id = get_attrib(obj_list, "fbc:activeObjective")
    target_objective = obj_list.find(
        ns("fbc:objective[@fbc:id='{}']".format(target_objective_id)))
    obj_direction_long = get_attrib(target_objective, "fbc:type")
    obj_direction = LONG_SHORT_DIRECTION[obj_direction_long]

    obj_query = OBJECTIVES_XPATH % target_objective_id
    coefficients = {}
    for sbml_objective in obj_list.findall(obj_query):
        rxn_id = clip(get_attrib(sbml_objective, "fbc:reaction"), "R_")
        try:
            objective_reaction = model.reactions.get_by_id(rxn_id)
        except KeyError:
            raise CobraSBMLError("Objective reaction '%s' not found" % rxn_id)
        try:
            coefficients[objective_reaction] = get_attrib(
                sbml_objective, "fbc:coefficient", type=number)
        except ValueError as e:
            warn(str(e))
    set_objective(model, coefficients)
    model.solver.objective.direction = obj_direction
    return model
#add reactions to represent day-night metabolite accumulation
from cobra.core import Metabolite, Reaction

#Adding transfer reactions
tmfile = open("MetabolitesToTransfer.txt", "r")
tmset = set()
for line in tmfile:
    tmset.add(line.replace("\n", ""))

for met in tmset:
    tempRxn = Reaction(met + "_dielTransfer")
    tempRxn.add_metabolites({
        cobra_model.metabolites.get_by_id(met + "1"): -1,
        cobra_model.metabolites.get_by_id(met + "2"): 1
    })
    tempRxn.lower_bound = -1000
    if not ((met == "STARCH_p") or (met == "SUCROSE_v") or (met == "MAL_v") or
            (met == "aMAL_v") or (met == "NITRATE_v") or (met == "CIT_v") or
            (met == "aCIT_v") or (met == "PROTON_v")):
        tempRxn.lower_bound = 0
    tempRxn.upper_bound = 1000
    cobra_model.add_reaction(tempRxn)

fractionMets = dict()
for rxn in cobra_model.reactions:
    for met in rxn.metabolites.keys():
        a = re.search("^a{1,3}", met.id)
        anion = ""
        if a:
            anion = a.group(0)
        b = re.search("^b{1,3}", met.id)
#add reactions to represent day-night metabolite accumulation
from cobra.core import Metabolite, Reaction

#Adding transfer reactions
tmfile = open("MetabolitesToTransfer.txt", "r")
tmset = set()
for line in tmfile:
    tmset.add(line.replace("\n", ""))

for met in tmset:
    tempRxn = Reaction(met + "_dielTransfer")
    tempRxn.add_metabolites({
        cobra_model.metabolites.get_by_id(met + "1"): -1,
        cobra_model.metabolites.get_by_id(met + "2"): 1
    })
    tempRxn.lower_bound = -1000
    if not ((met == "STARCH_p") or (met == "SUCROSE_v") or (met == "MAL_v") or
            (met == "aMAL_v") or (met == "NITRATE_v") or (met == "CIT_v") or
            (met == "aCIT_v") or (met == "PROTON_v")):
        tempRxn.lower_bound = 0
    tempRxn.upper_bound = 1000
    cobra_model.add_reaction(tempRxn)

fractionMets = dict()
for rxn in cobra_model.reactions:
    for met in rxn.metabolites.keys():
        a = re.search("^a{1,3}", met.id)
        anion = ""
        if a:
            anion = a.group(0)
        b = re.search("^b{1,3}", met.id)
예제 #48
0
파일: sbml.py 프로젝트: wbryant/cobrapy
def create_cobra_model_from_sbml_file(sbml_filename, old_sbml=False,
                                      legacy_metabolite=False,
                                      print_time=False, use_hyphens=False):
    """convert an SBML XML file into a cobra.Model object.

    Supports SBML Level 2 Versions 1 and 4.  The function will detect if the
    SBML fbc package is used in the file and run the converter if the fbc
    package is used.

    Parameters
    ----------
    sbml_filename: string
    old_sbml: bool
        Set to True if the XML file has metabolite formula appended to
        metabolite names. This was a poorly designed artifact that persists in
        some models.
    legacy_metabolite: bool
        If True then assume that the metabolite id has the compartment id
         appended after an underscore (e.g. _c for cytosol). This has not been
         implemented but will be soon.
    print_time: bool
         deprecated
    use_hyphens: bool
        If True, double underscores (__) in an SBML ID will be converted to
        hyphens

    Returns
    -------
    Model : The parsed cobra model
    """
    if not libsbml:
        raise ImportError('create_cobra_model_from_sbml_file '
                          'requires python-libsbml')

    __default_lower_bound = -1000
    __default_upper_bound = 1000
    __default_objective_coefficient = 0
    # Ensure that the file exists
    if not isfile(sbml_filename):
        raise IOError('Your SBML file is not found: %s' % sbml_filename)
    # Expressions to change SBML Ids to Palsson Lab Ids
    metabolite_re = re.compile('^M_')
    reaction_re = re.compile('^R_')
    compartment_re = re.compile('^C_')
    if print_time:
        warn("print_time is deprecated", DeprecationWarning)
    model_doc = libsbml.readSBML(sbml_filename)
    if model_doc.getPlugin("fbc") is not None:
        from libsbml import ConversionProperties, LIBSBML_OPERATION_SUCCESS
        conversion_properties = ConversionProperties()
        conversion_properties.addOption(
            "convert fbc to cobra", True, "Convert FBC model to Cobra model")
        result = model_doc.convert(conversion_properties)
        if result != LIBSBML_OPERATION_SUCCESS:
            raise Exception("Conversion of SBML+fbc to COBRA failed")
    sbml_model = model_doc.getModel()
    sbml_model_id = sbml_model.getId()
    sbml_species = sbml_model.getListOfSpecies()
    sbml_reactions = sbml_model.getListOfReactions()
    sbml_compartments = sbml_model.getListOfCompartments()
    compartment_dict = dict([(compartment_re.split(x.getId())[-1], x.getName())
                             for x in sbml_compartments])
    if legacy_metabolite:
        # Deal with the palsson lab appending the compartment id to the
        # metabolite id
        new_dict = {}
        for the_id, the_name in compartment_dict.items():
            if the_name == '':
                new_dict[the_id[0].lower()] = the_id
            else:
                new_dict[the_id] = the_name
        compartment_dict = new_dict
        legacy_compartment_converter = dict(
            [(v, k) for k, v in iteritems(compartment_dict)])

    cobra_model = Model(sbml_model_id)
    metabolites = []
    metabolite_dict = {}
    # Convert sbml_metabolites to cobra.Metabolites
    for sbml_metabolite in sbml_species:
        # Skip sbml boundary species
        if sbml_metabolite.getBoundaryCondition():
            continue

        if (old_sbml or legacy_metabolite) and \
                sbml_metabolite.getId().endswith('_b'):
            # Deal with incorrect sbml from bigg.ucsd.edu
            continue
        tmp_metabolite = Metabolite()
        metabolite_id = tmp_metabolite.id = sbml_metabolite.getId()
        tmp_metabolite.compartment = compartment_re.split(
            sbml_metabolite.getCompartment())[-1]
        if legacy_metabolite:
            if tmp_metabolite.compartment not in compartment_dict:
                tmp_metabolite.compartment = legacy_compartment_converter[
                    tmp_metabolite.compartment]
            tmp_metabolite.id = parse_legacy_id(
                tmp_metabolite.id, tmp_metabolite.compartment,
                use_hyphens=use_hyphens)
        if use_hyphens:
            tmp_metabolite.id = metabolite_re.split(
                tmp_metabolite.id)[-1].replace('__', '-')
        else:
            # Just in case the SBML ids are ill-formed and use -
            tmp_metabolite.id = metabolite_re.split(
                tmp_metabolite.id)[-1].replace('-', '__')
        tmp_metabolite.name = sbml_metabolite.getName()
        tmp_formula = ''
        tmp_metabolite.notes = parse_legacy_sbml_notes(
            sbml_metabolite.getNotesString())
        if sbml_metabolite.isSetCharge():
            tmp_metabolite.charge = sbml_metabolite.getCharge()
        if "CHARGE" in tmp_metabolite.notes:
            note_charge = tmp_metabolite.notes["CHARGE"][0]
            try:
                note_charge = float(note_charge)
                if note_charge == int(note_charge):
                    note_charge = int(note_charge)
            except:
                warn("charge of %s is not a number (%s)" %
                     (tmp_metabolite.id, str(note_charge)))
            else:
                if ((tmp_metabolite.charge is None) or
                        (tmp_metabolite.charge == note_charge)):
                    tmp_metabolite.notes.pop("CHARGE")
                    # set charge to the one from notes if not assigend before
                    # the same
                    tmp_metabolite.charge = note_charge
                else:  # tmp_metabolite.charge != note_charge
                    msg = "different charges specified for %s (%d and %d)"
                    msg = msg % (tmp_metabolite.id,
                                 tmp_metabolite.charge, note_charge)
                    warn(msg)
                    # Chances are a 0 note charge was written by mistake. We
                    # will default to the note_charge in this case.
                    if tmp_metabolite.charge == 0:
                        tmp_metabolite.charge = note_charge

        for the_key in tmp_metabolite.notes.keys():
            if the_key.lower() == 'formula':
                tmp_formula = tmp_metabolite.notes.pop(the_key)[0]
                break
        if tmp_formula == '' and old_sbml:
            tmp_formula = tmp_metabolite.name.split('_')[-1]
            tmp_metabolite.name = tmp_metabolite.name[:-len(tmp_formula) - 1]
        tmp_metabolite.formula = tmp_formula
        metabolite_dict.update({metabolite_id: tmp_metabolite})
        metabolites.append(tmp_metabolite)
    cobra_model.add_metabolites(metabolites)

    # Construct the vectors and matrices for holding connectivity and numerical
    # info to feed to the cobra toolbox.
    # Always assume steady state simulations so b is set to 0
    cobra_reaction_list = []
    coefficients = {}
    for sbml_reaction in sbml_reactions:
        if use_hyphens:
            # Change the ids to match conventions used by the Palsson lab.
            reaction = Reaction(reaction_re.split(
                sbml_reaction.getId())[-1].replace('__', '-'))
        else:
            # Just in case the SBML ids are ill-formed and use -
            reaction = Reaction(reaction_re.split(
                sbml_reaction.getId())[-1].replace('-', '__'))
        cobra_reaction_list.append(reaction)
        # reaction.exchange_reaction = 0
        reaction.name = sbml_reaction.getName()
        cobra_metabolites = {}
        # Use the cobra.Metabolite class here
        for sbml_metabolite in sbml_reaction.getListOfReactants():
            tmp_metabolite_id = sbml_metabolite.getSpecies()
            # This deals with boundary metabolites
            if tmp_metabolite_id in metabolite_dict:
                tmp_metabolite = metabolite_dict[tmp_metabolite_id]
                cobra_metabolites[tmp_metabolite] = - \
                    sbml_metabolite.getStoichiometry()
        for sbml_metabolite in sbml_reaction.getListOfProducts():
            tmp_metabolite_id = sbml_metabolite.getSpecies()
            # This deals with boundary metabolites
            if tmp_metabolite_id in metabolite_dict:
                tmp_metabolite = metabolite_dict[tmp_metabolite_id]
                # Handle the case where the metabolite was specified both
                # as a reactant and as a product.
                if tmp_metabolite in cobra_metabolites:
                    warn("%s appears as a reactant and product %s" %
                         (tmp_metabolite_id, reaction.id))
                    cobra_metabolites[
                        tmp_metabolite] += sbml_metabolite.getStoichiometry()
                    # if the combined stoichiometry is 0, remove the metabolite
                    if cobra_metabolites[tmp_metabolite] == 0:
                        cobra_metabolites.pop(tmp_metabolite)
                else:
                    cobra_metabolites[
                        tmp_metabolite] = sbml_metabolite.getStoichiometry()
        # check for nan
        for met, v in iteritems(cobra_metabolites):
            if isnan(v) or isinf(v):
                warn("invalid value %s for metabolite '%s' in reaction '%s'" %
                     (str(v), met.id, reaction.id))
        reaction.add_metabolites(cobra_metabolites)
        # Parse the kinetic law info here.
        parameter_dict = {}
        # If lower and upper bounds are specified in the Kinetic Law then
        # they override the sbml reversible attribute.  If they are not
        # specified then the bounds are determined by getReversible.
        if not sbml_reaction.getKineticLaw():

            if sbml_reaction.getReversible():
                parameter_dict['lower_bound'] = __default_lower_bound
                parameter_dict['upper_bound'] = __default_upper_bound
            else:
                # Assume that irreversible reactions only proceed from left to
                # right.
                parameter_dict['lower_bound'] = 0
                parameter_dict['upper_bound'] = __default_upper_bound

            parameter_dict[
                'objective_coefficient'] = __default_objective_coefficient
        else:
            for sbml_parameter in \
                    sbml_reaction.getKineticLaw().getListOfParameters():
                parameter_dict[
                    sbml_parameter.getId().lower()] = sbml_parameter.getValue()

        if 'lower_bound' in parameter_dict:
            reaction.lower_bound = parameter_dict['lower_bound']
        elif 'lower bound' in parameter_dict:
            reaction.lower_bound = parameter_dict['lower bound']
        elif sbml_reaction.getReversible():
            reaction.lower_bound = __default_lower_bound
        else:
            reaction.lower_bound = 0

        if 'upper_bound' in parameter_dict:
            reaction.upper_bound = parameter_dict['upper_bound']
        elif 'upper bound' in parameter_dict:
            reaction.upper_bound = parameter_dict['upper bound']
        else:
            reaction.upper_bound = __default_upper_bound

        objective_coefficient = parameter_dict.get(
            'objective_coefficient', parameter_dict.get(
                'objective_coefficient', __default_objective_coefficient))
        if objective_coefficient != 0:
            coefficients[reaction] = objective_coefficient

        # ensure values are not set to nan or inf
        if isnan(reaction.lower_bound) or isinf(reaction.lower_bound):
            reaction.lower_bound = __default_lower_bound
        if isnan(reaction.upper_bound) or isinf(reaction.upper_bound):
            reaction.upper_bound = __default_upper_bound

        reaction_note_dict = parse_legacy_sbml_notes(
            sbml_reaction.getNotesString())
        # Parse the reaction notes.
        # POTENTIAL BUG: DEALING WITH LEGACY 'SBML' THAT IS NOT IN A
        # STANDARD FORMAT
        # TODO: READ IN OTHER NOTES AND GIVE THEM A reaction_ prefix.
        # TODO: Make sure genes get added as objects
        if 'GENE ASSOCIATION' in reaction_note_dict:
            rule = reaction_note_dict['GENE ASSOCIATION'][0]
            try:
                rule.encode('ascii')
            except (UnicodeEncodeError, UnicodeDecodeError):
                warn("gene_reaction_rule '%s' is not ascii compliant" % rule)
            if rule.startswith("&quot;") and rule.endswith("&quot;"):
                rule = rule[6:-6]
            reaction.gene_reaction_rule = rule
            if 'GENE LIST' in reaction_note_dict:
                reaction.systematic_names = reaction_note_dict['GENE LIST'][0]
            elif ('GENES' in reaction_note_dict and
                  reaction_note_dict['GENES'] != ['']):
                reaction.systematic_names = reaction_note_dict['GENES'][0]
            elif 'LOCUS' in reaction_note_dict:
                gene_id_to_object = dict([(x.id, x) for x in reaction._genes])
                for the_row in reaction_note_dict['LOCUS']:
                    tmp_row_dict = {}
                    the_row = 'LOCUS:' + the_row.lstrip('_').rstrip('#')
                    for the_item in the_row.split('#'):
                        k, v = the_item.split(':')
                        tmp_row_dict[k] = v
                    tmp_locus_id = tmp_row_dict['LOCUS']
                    if 'TRANSCRIPT' in tmp_row_dict:
                        tmp_locus_id = tmp_locus_id + \
                                       '.' + tmp_row_dict['TRANSCRIPT']

                    if 'ABBREVIATION' in tmp_row_dict:
                        gene_id_to_object[tmp_locus_id].name = tmp_row_dict[
                            'ABBREVIATION']

        if 'SUBSYSTEM' in reaction_note_dict:
            reaction.subsystem = reaction_note_dict.pop('SUBSYSTEM')[0]

        reaction.notes = reaction_note_dict

    # Now, add all of the reactions to the model.
    cobra_model.id = sbml_model.getId()
    # Populate the compartment list - This will be done based on
    # cobra.Metabolites in cobra.Reactions in the future.
    cobra_model.compartments = compartment_dict

    cobra_model.add_reactions(cobra_reaction_list)
    set_objective(cobra_model, coefficients)
    return cobra_model
예제 #49
0
파일: moma.py 프로젝트: sandrejev/bioopt
def optimize_minimum_flux(model, objective_sense='maximize',
                 tolerance_optimality=1e-8, tolerance_feasibility=1e-8):
    # return the flux distribution in which the total amount of fluxes is minimum while the growth is maximum
    #Get the optimal wt objective value and adjust based on optimality tolerances
    model.optimize()
    optimal_value = deepcopy(model.solution.f)
    # print('opt val: %s' % optimal_value)
    if objective_sense == 'maximize':
        optimal_value = floor(optimal_value/tolerance_optimality)*tolerance_optimality
    else:
        optimal_value = ceil(optimal_value/tolerance_optimality)*tolerance_optimality
    # print('adjusted opt val: %s' % optimal_value)
    #Add in the virtual objective metabolite to constrain the wt_model to the space where
    #the objective was maximal
    objective_metabolite = Metabolite('objective metabolite')
    objective_metabolite._bound = optimal_value
    if objective_sense == 'maximize':
        objective_metabolite._constraint_sense = 'G'
    else:
        objective_metabolite._constraint_sense = 'L'
    # print('objm const sense: %s, objm bound: %s' % (objective_metabolite._constraint_sense, objective_metabolite._bound))

    # construct irreversible model to assure all flux values are positive
    irreve_model = model.copy()
    # this is necessary to avoid invalid bound error when model is changed to irreversible
    for r in irreve_model.reactions:
        if r.upper_bound < 0:
            reverse_reaction = Reaction(r.id + "_reverse")
            reverse_reaction.lower_bound = r.upper_bound * -1
            reverse_reaction.upper_bound = r.lower_bound * -1
            reverse_reaction.objective_coefficient = r.objective_coefficient * -1
            reaction_dict = dict([(k, v*-1)
                                  for k, v in r.metabolites.items()])
            reverse_reaction.add_metabolites(reaction_dict)
            irreve_model.add_reaction(reverse_reaction)
            r.upper_bound, r.lower_bound = 0, 0

    cobra.manipulation.modify.convert_to_irreversible(irreve_model)
    objective_reaction_coefficient_dict = dict([(x.id, x.objective_coefficient)
                                                    for x in model.reactions
                                                    if x.objective_coefficient])
    # this couples the objective reaction to the virtual metabolite
    [irreve_model.reactions.get_by_id(k).add_metabolites({objective_metabolite: v})
     for k, v in objective_reaction_coefficient_dict.items()]
    # print('irregular metabolites: %s' % [(m.id, m._constraint_sense, m._bound)
    #                                      for m in irreve_model.metabolites if m._constraint_sense != 'E' or m._bound != 0])

    # minimize the sum of fluxes
    for r in irreve_model.reactions:
        r.objective_coefficient = 1
    # print([r.id for r in irreve_model.reactions if r.objective_coefficient != 1])
    # print(tolerance_feasibility)
    irreve_model.optimize(objective_sense='minimize',
                          tolerance_feasibility=tolerance_feasibility)

    # adjust this to the solution of wt_model
    original_flux = model.solution.x_dict
    irreve_flux = irreve_model.solution.x_dict
    for k in original_flux.keys():
        original_flux[k] = irreve_flux[k]
        # if reverse reaction exists and its flux is not zero, assign as a negative flux in wt_flux
        if k + '_reverse' in irreve_flux.keys() and irreve_flux[k + '_reverse'] != 0:
            if irreve_flux[k] != 0:
                print('Attention: non-optimal solution')
            original_flux[k] = -irreve_flux[k + '_reverse']

    model.solution.status = irreve_model.solution.status
    model.solution.f = sum([irreve_model.reactions.get_by_id(k).x * v for k, v in
                            objective_reaction_coefficient_dict.items()])
    return model.solution