def test_gapfilling(self, salmonella): m = Model() m.add_metabolites([Metabolite(m_id) for m_id in ["a", "b", "c"]]) exa = Reaction("EX_a") exa.add_metabolites({m.metabolites.a: 1}) b2c = Reaction("b2c") b2c.add_metabolites({m.metabolites.b: -1, m.metabolites.c: 1}) dmc = Reaction("DM_c") dmc.add_metabolites({m.metabolites.c: -1}) m.add_reactions([exa, b2c, dmc]) m.objective = 'DM_c' universal = Model() a2b = Reaction("a2b") a2d = Reaction("a2d") universal.add_reactions([a2b, a2d]) a2b.build_reaction_from_string("a --> b", verbose=False) a2d.build_reaction_from_string("a --> d", verbose=False) # # GrowMatch # result = gapfilling.growMatch(m, universal)[0] result = gapfilling.gapfill(m, universal)[0] assert len(result) == 1 assert result[0].id == "a2b" # # SMILEY # result = gapfilling.SMILEY(m, "b", universal)[0] with m: m.objective = m.add_boundary(m.metabolites.b, type='demand') result = gapfilling.gapfill(m, universal)[0] assert len(result) == 1 assert result[0].id == "a2b" # # 2 rounds of GrowMatch with exchange reactions # result = gapfilling.growMatch(m, None, ex_rxns=True, iterations=2) result = gapfilling.gapfill(m, None, exchange_reactions=True, iterations=2) assert len(result) == 2 assert len(result[0]) == 1 assert len(result[1]) == 1 assert {i[0].id for i in result} == {"EX_b", "EX_c"} # somewhat bigger model universal = Model("universal_reactions") with salmonella as model: for i in [i.id for i in model.metabolites.f6p_c.reactions]: reaction = model.reactions.get_by_id(i) universal.add_reactions([reaction.copy()]) model.remove_reactions([reaction]) gf = gapfilling.GapFiller(model, universal, penalties={'TKT2': 1e3}, demand_reactions=False) solution = gf.fill() assert 'TKT2' not in {r.id for r in solution[0]} assert gf.validate(solution[0])
def add_bigg_metabolites(bigg_list, model): """ Create a COBRA metabolite from a BiGG metabolite. Parameters ---------- bigg_list : list of dict List of dictionaries with BiGG metabolite data model : cobra.core.Model Model to add metabolites to """ # Create a Metabolite object for each BiGG metabolite. metabolites = DictList() for bigg_metabolite in bigg_list: # Available data is different for a metabolite from an organism model versus # a metabolite from the universal model. if 'compartment_bigg_id' in bigg_metabolite: compartment = bigg_metabolite['compartment_bigg_id'] elif 'compartments_in_models' in bigg_metabolite: compartment = bigg_metabolite['compartments_in_models'][0][ 'bigg_id'] else: raise ValueError( 'BiGG metabolite {0} does not have a compartment'.format( bigg_metabolite['bigg_id'])) metabolite = Metabolite(id='{0}_{1}'.format(bigg_metabolite['bigg_id'], compartment), name=bigg_metabolite['name'], compartment=compartment) try: metabolite.formula = bigg_metabolite['formula'] except KeyError: try: if len(bigg_metabolite['formulae']) > 0: metabolite.formula = bigg_metabolite['formulae'][0] except KeyError: pass try: metabolite.charge = bigg_metabolite['charge'] except KeyError: try: if len(bigg_metabolite['charges']) > 0: metabolite.charge = bigg_metabolite['charges'][0] except KeyError: pass metabolite.notes['aliases'] = bigg_metabolite['database_links'] metabolites.append(metabolite) if compartment not in model.compartments: try: model.compartments[compartment] = bigg_metabolite[ 'compartment_name'] except KeyError: model.compartments[compartment] = 'unknown' # Add all of the metabolites to the model. model.add_metabolites(metabolites) return
def add_metabolite(self, cid, formula, name, compartment='C'): try: self.metabolites.index(cid) except ValueError: met = Metabolite(id=cid, formula=Formula(formula), name=name, compartment=compartment) self.cobra_model.add_metabolites([met])
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
def add_metabolite(model, id, formula, name, compartment='C'): try: model.metabolites.index(id) except Exception, e: # CobraPy versions differ in what error they raise, # hence catching base Exception. met = Metabolite(id=id, formula=Formula(formula), name=name, compartment=compartment) model.add_metabolites([met])
def test_add_remove_reaction_benchmark(model, benchmark, solver): metabolite_foo = Metabolite("test_foo") metabolite_bar = Metabolite("test_bar") metabolite_baz = Metabolite("test_baz") actual_metabolite = model.metabolites[0] dummy_reaction = Reaction("test_foo_reaction") dummy_reaction.add_metabolites({metabolite_foo: -1, metabolite_bar: 1, metabolite_baz: -2, actual_metabolite: 1}) def benchmark_add_reaction(): model.add_reaction(dummy_reaction) if not getattr(model, 'solver', None): solver_dict[solver].create_problem(model) model.remove_reactions([dummy_reaction]) benchmark(benchmark_add_reaction)
def test_gene_knock_out(self, model): rxn = Reaction('rxn') rxn.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1}) rxn.gene_reaction_rule = 'A2B1 or A2B2 and A2B3' assert hasattr(list(rxn.genes)[0], 'knock_out') model.add_reaction(rxn) with model: model.genes.A2B1.knock_out() assert not model.genes.A2B1.functional model.genes.A2B3.knock_out() assert not rxn.functional assert model.genes.A2B3.functional assert rxn.functional model.genes.A2B1.knock_out() assert not model.genes.A2B1.functional assert model.reactions.rxn.functional model.genes.A2B3.knock_out() assert not model.reactions.rxn.functional
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'
def test_gene_knock_out(model: Model) -> None: """Test gene knockout effect on reaction.""" rxn = Reaction("rxn") rxn.add_metabolites({Metabolite("A"): -1, Metabolite("B"): 1}) rxn.gene_reaction_rule = "A2B1 or A2B2 and A2B3" assert hasattr(list(rxn.genes)[0], "knock_out") model.add_reaction(rxn) with model: model.genes.A2B1.knock_out() assert not model.genes.A2B1.functional model.genes.A2B3.knock_out() assert not rxn.functional assert model.genes.A2B3.functional assert rxn.functional model.genes.A2B1.knock_out() assert not model.genes.A2B1.functional assert model.reactions.rxn.functional model.genes.A2B3.knock_out() assert not model.reactions.rxn.functional
def test_canonical_form(self, model): # add G constraint to test g_constr = Metabolite("SUCCt2_2__test_G_constraint") g_constr._constraint_sense = "G" g_constr._bound = 5.0 model.reactions.get_by_id("SUCCt2_2").add_metabolites({g_constr: 1}) assert abs(model.optimize("maximize").f - 0.855) < 0.001 # convert to canonical form model = canonical_form(model) assert abs(model.optimize("maximize").f - 0.855) < 10**-3
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'
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]
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'
def test_add_reaction(self, model): old_reaction_count = len(model.reactions) old_metabolite_count = len(model.metabolites) dummy_metabolite_1 = Metabolite("test_foo_1") dummy_metabolite_2 = Metabolite("test_foo_2") actual_metabolite = model.metabolites[0] copy_metabolite = model.metabolites[1].copy() dummy_reaction = Reaction("test_foo_reaction") dummy_reaction.add_metabolites({ dummy_metabolite_1: -1, dummy_metabolite_2: 1, copy_metabolite: -2, actual_metabolite: 1 }) model.add_reaction(dummy_reaction) assert model.reactions.get_by_id(dummy_reaction.id) == dummy_reaction for x in [dummy_metabolite_1, dummy_metabolite_2]: assert model.metabolites.get_by_id(x.id) == x # should have added 1 reaction and 2 metabolites assert len(model.reactions) == old_reaction_count + 1 assert len(model.metabolites) == old_metabolite_count + 2 # tests on the added reaction reaction_in_model = model.reactions.get_by_id(dummy_reaction.id) assert type(reaction_in_model) is Reaction assert reaction_in_model is dummy_reaction assert len(reaction_in_model._metabolites) == 4 for i in reaction_in_model._metabolites: assert type(i) == Metabolite # tests on the added metabolites met1_in_model = model.metabolites.get_by_id(dummy_metabolite_1.id) assert met1_in_model is dummy_metabolite_1 copy_in_model = model.metabolites.get_by_id(copy_metabolite.id) assert copy_metabolite is not copy_in_model assert type(copy_in_model) is Metabolite assert dummy_reaction in actual_metabolite._reaction # test adding a different metabolite with the same name as an # existing one uses the metabolite in the model r2 = Reaction("test_foo_reaction2") model.add_reaction(r2) r2.add_metabolites({Metabolite(model.metabolites[0].id): 1}) assert model.metabolites[0] is list(r2._metabolites)[0]
def test_set_id(self, solved_model): solution, model = solved_model met = Metabolite("test") with pytest.raises(TypeError): setattr(met, 'id', 1) model.add_metabolites([met]) with pytest.raises(ValueError): setattr(met, "id", 'g6p_c') met.id = "test2" assert "test2" in model.metabolites assert "test" not in model.metabolites
def test_canonical_form(self): model = create_test_model("textbook") # add G constraint to test g_constr = Metabolite("SUCCt2_2__test_G_constraint") g_constr._constraint_sense = "G" g_constr._bound = 5.0 model.reactions.get_by_id("SUCCt2_2").add_metabolites({g_constr: 1}) self.assertAlmostEqual(model.optimize("maximize").f, 0.855, places=3) # convert to canonical form model = canonical_form(model) self.assertAlmostEqual(model.optimize("maximize").f, 0.855, places=3)
def get_ecoli_core_model(): model_url = 'http://bigg.ucsd.edu/static/models/e_coli_core.xml' model_path, _ = urlretrieve(model_url) model = read_sbml_model(model_url) b_c, b_e = (Metabolite(BIOMASS_CYT_NAME, name='biomass (cytosol)'), Metabolite(BIOMASS_EXT_NAME, name='biomass (extracellular)')) model.reactions.get_by_id(BIOMASS_RX_NAME).add_metabolites({b_c: 1}) b_trans = Reaction(BIOMASS_TRANS_NAME, name='Biomass transport') b_trans.add_metabolites({b_c: -1, b_e: 1}) b_drain = Reaction(BIOMASS_DRAIN_NAME, name='Biomass drain') b_drain.add_metabolites({b_e: -1}) model.add_reaction(b_trans) model.add_reaction(b_drain) return model
def construct_ll_test_model(cls): test_model = Model() test_model.add_metabolites(Metabolite("A")) test_model.add_metabolites(Metabolite("B")) test_model.add_metabolites(Metabolite("C")) EX_A = Reaction("EX_A") EX_A.add_metabolites({test_model.metabolites.A: 1}) DM_C = Reaction("DM_C") DM_C.add_metabolites({test_model.metabolites.C: -1}) v1 = Reaction("v1") v1.add_metabolites({test_model.metabolites.A: -1, test_model.metabolites.B: 1}) v2 = Reaction("v2") v2.add_metabolites({test_model.metabolites.B: -1, test_model.metabolites.C: 1}) v3 = Reaction("v3") v3.add_metabolites({test_model.metabolites.C: -1, test_model.metabolites.A: 1}) test_model.add_reactions([EX_A, DM_C, v1, v2, v3]) DM_C.objective_coefficient = 1 return test_model
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
def test_add_metabolite(self, model): new_metabolite = Metabolite('test_met') assert new_metabolite not in model.metabolites with model: model.add_metabolites(new_metabolite) assert new_metabolite._model == model assert new_metabolite in model.metabolites assert new_metabolite.id in model.solver.constraints assert new_metabolite._model is None assert new_metabolite not in model.metabolites assert new_metabolite.id not in model.solver.constraints
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
def test_model_remove_reaction(self, model): old_reaction_count = len(model.reactions) model.remove_reactions(["PGI"]) assert len(model.reactions) == old_reaction_count - 1 with pytest.raises(KeyError): model.reactions.get_by_id("PGI") model.remove_reactions(model.reactions[:1]) assert len(model.reactions) == old_reaction_count - 2 tmp_metabolite = Metabolite("testing") model.reactions[0].add_metabolites({tmp_metabolite: 1}) assert tmp_metabolite in model.metabolites model.remove_reactions(model.reactions[:1], remove_orphans=True) assert tmp_metabolite not in model.metabolites
def create_example2_model(self): model = Model('example2_model') rs = (r1, r2, r3, r4, r5) = (Reaction('R1'), Reaction('R2'), Reaction('R3'), Reaction('R4'), Reaction('R5')) for r in rs: r.lower_bound = 0. r.upper_bound = 1000. r.objective_coefficient = 0. ms = (m1, m2, m3) = (Metabolite('M1'), Metabolite('M2'), Metabolite('M3')) r1.add_metabolites({m1: 1.0}) r2.add_metabolites({m1: -1.0, m2: 1.0}) r3.add_metabolites({m2: -1.0}) r4.add_metabolites({m1: -1.0, m3: 1.0}) r5.add_metabolites({m3: -1.0}) model.add_reactions(rs) return model
def test_add_metabolite(self, model): with model: reaction = model.reactions.get_by_id("PGI") reaction.add_metabolites({model.metabolites[0]: 1}) assert model.metabolites[0] in reaction._metabolites fake_metabolite = Metabolite("fake") reaction.add_metabolites({fake_metabolite: 1}) assert fake_metabolite in reaction._metabolites assert model.metabolites.has_id("fake") assert model.metabolites.get_by_id("fake") is fake_metabolite assert fake_metabolite._model is None assert fake_metabolite not in reaction._metabolites assert "fake" not in model.metabolites # test adding by string with model: reaction.add_metabolites({"g6p_c": -1}) # already in reaction assert reaction._metabolites[model.metabolites.get_by_id( "g6p_c")] == -2 reaction.add_metabolites({"h_c": 1}) assert reaction._metabolites[model.metabolites.get_by_id( "h_c")] == 1 with pytest.raises(KeyError): reaction.add_metabolites({"missing": 1}) assert reaction._metabolites[model.metabolites.get_by_id( "g6p_c")] == -1 assert model.metabolites.h_c not in reaction._metabolites # test adding to a new Reaction reaction = Reaction("test") assert len(reaction._metabolites) == 0 reaction.add_metabolites({Metabolite("test_met"): -1}) assert len(reaction._metabolites) == 1
def test_get_turnover(): met = Metabolite("m1") r1 = Reaction("r1") r1.add_metabolites({met: -2}) r2 = Reaction("r2") r2.add_metabolites({met: 1}) solution = LegacySolution(f=1, x_dict={r1.id: 500, r2.id: 1000}) assert get_turnover(solution, met) == 1000 solution = Solution(objective_value=1, status="optimal", fluxes=pd.Series(data=[500, 1000], index=[r1.id, r2.id])) assert get_turnover(solution, met) == 1000
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.
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
def test_validate_mass_balance(self, model): assert len(check_mass_balance(model)) == 0 # if we remove the SBO term which marks the reaction as # mass balanced, then the reaction should be detected as # no longer mass balanced EX_rxn = model.reactions.query("EX")[0] EX_rxn.annotation.pop("SBO") balance = check_mass_balance(model) assert len(balance) == 1 assert EX_rxn in balance m1 = Metabolite('m1', formula='()') r1 = Reaction('r1') r1.add_metabolites({m1: 1}) with pytest.raises(ValueError): r1.check_mass_balance()
def test_validate_mass_balance(model: Model) -> None: """Test reaction mass balance validation.""" assert len(check_mass_balance(model)) == 0 # if we remove the SBO term which marks the reaction as # mass balanced, then the reaction should be detected as # no longer mass balanced EX_rxn = model.reactions.query(lambda r: r.boundary)[0] EX_rxn.annotation.pop("sbo") balance = check_mass_balance(model) assert len(balance) == 1 assert EX_rxn in balance m1 = Metabolite("m1", formula="()") r1 = Reaction("r1") r1.add_metabolites({m1: 1}) with pytest.raises(ValueError), pytest.warns(UserWarning): r1.check_mass_balance()
def test_add_metabolites_combine_false(self, model): test_metabolite = Metabolite('test') for reaction in model.reactions: reaction.add_metabolites({test_metabolite: -66}, combine=False) assert reaction.metabolites[test_metabolite] == -66 assert model.constraints['test'].expression.has( -66. * reaction.forward_variable) assert model.constraints['test'].expression.has( 66. * reaction.reverse_variable) already_included_metabolite = \ list(reaction.metabolites.keys())[0] reaction.add_metabolites({already_included_metabolite: 10}, combine=False) assert reaction.metabolites[already_included_metabolite] == 10 assert model.constraints[ already_included_metabolite.id].expression.has( 10 * reaction.forward_variable) assert model.constraints[ already_included_metabolite.id].expression.has( -10 * reaction.reverse_variable)