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
def test_iadd(model): PGI = model.reactions.PGI EX_h2o = model.reactions.EX_h2o_e original_PGI_gpr = PGI.gene_reaction_rule PGI += EX_h2o assert PGI.gene_reaction_rule == original_PGI_gpr assert PGI.metabolites[model.metabolites.h2o_e] == -1.0 # Original should not change assert EX_h2o.gene_reaction_rule == '' assert EX_h2o.metabolites[model.metabolites.h2o_e] == -1.0 # Add a reaction not in the model new_reaction = Reaction("test") new_reaction.add_metabolites({Metabolite("A"): -1, Metabolite("B"): 1}) PGI += new_reaction assert PGI.gene_reaction_rule == original_PGI_gpr assert len(PGI.gene_reaction_rule) == 5 # And vice versa new_reaction += PGI assert len(new_reaction.metabolites) == 5 # not assert len(new_reaction.genes) == 1 assert new_reaction.gene_reaction_rule == original_PGI_gpr # Combine two GPRs model.reactions.ACKr += model.reactions.ACONTa expected_rule = '(b2296 or b3115 or b1849) and (b0118 or b1276)' assert model.reactions.ACKr.gene_reaction_rule == expected_rule assert len(model.reactions.ACKr.genes) == 5
def test_add_reaction_context(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}) dummy_reaction.gene_reaction_rule = 'dummy_gene' with model: model.add_reaction(dummy_reaction) assert model.reactions.get_by_id( dummy_reaction.id) == dummy_reaction assert len(model.reactions) == old_reaction_count + 1 assert len(model.metabolites) == old_metabolite_count + 2 assert dummy_metabolite_1._model == model assert 'dummy_gene' in model.genes assert len(model.reactions) == old_reaction_count assert len(model.metabolites) == old_metabolite_count with pytest.raises(KeyError): model.reactions.get_by_id(dummy_reaction.id) assert dummy_metabolite_1._model is None assert 'dummy_gene' not in model.genes
def test__normalize_pseudoreaction_exchange_error_bad_coeff(): reaction = Reaction('EX_gone') reaction.add_metabolites({Metabolite('glu__L_e'): -2}) with pytest.raises(ConflictingPseudoreaction) as excinfo: _ = _normalize_pseudoreaction(reaction.id, reaction) assert 'with coefficient' in str(excinfo.value) assert reaction.id == 'EX_gone'
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
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
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'
def test__normalize_pseudoreaction_exchange_error_has_gpr(): reaction = Reaction('EX_gone') reaction.add_metabolites({Metabolite('glu__L_e'): -1}) reaction.gene_reaction_rule = 'b1779' with pytest.raises(ConflictingPseudoreaction) as excinfo: _ = _normalize_pseudoreaction(reaction.id, reaction) assert 'has a gene_reaction_rule' in str(excinfo.value) assert reaction.id == 'EX_gone'
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)
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'
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 _normalize_pseudoreaction(reaction) assert reaction.id == 'DM_glu__L_c' assert reaction.subsystem == 'Intracellular demand'
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'
def get_debug_plasmid(model, has_rnap=False): h2o_c = model.metabolites.h2o_c h2o_e = model.metabolites.h2o_e # CO2 Exchange h2o_tpp = Reaction(id='h2otpp', name='H2O Exchange') h2o_tpp.add_metabolites({ h2o_c: 1, h2o_e: -1, }) reaction_list = [h2o_tpp] ############# # Genes # ############# DBG = ExpressedGene(id='DBG_gene', name='Debug synthase', sequence='AATTTCGGTTGA'.lower()) ############# # Enzymes # ############# DBG_enz = Enzyme(id='DBG', kcat=65 * 3600, kdeg=kdeg_enz, composition={'DBG_gene': 3}) ############ # Coupling # ############ coupling_dict = {'h2otpp': [DBG_enz]} ########### # Plasmid # ########### if 1: rnap_genes = [] rnap = None gene_list = [DBG] + rnap_genes plasmid_seq = DBG.sequence my_plasmid = Plasmid(id_='debug', sequence=plasmid_seq, genes=gene_list, reactions=reaction_list, coupling_dict=coupling_dict, rnap=rnap) my_plasmid.build_default_mrna(kdeg_mrna) return my_plasmid
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 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__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_atpm(): 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}) pseudo_id = _normalize_pseudoreaction(reaction.id, reaction) assert pseudo_id == 'ATPM' assert reaction.subsystem == 'Biomass and maintenance functions'
def test__normalize_pseudoreaction_atpm(): 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}) _normalize_pseudoreaction(reaction) assert reaction.id == 'ATPM' assert reaction.subsystem == 'Biomass and maintenance functions'
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__normalize_pseudoreaction_atpm_has_gpr(): reaction = Reaction('NPT1') reaction.add_metabolites({Metabolite('atp_c'): -1, Metabolite('h2o_c'): -1, Metabolite('pi_c'): 1, Metabolite('h_c'): 1, Metabolite('adp_c'): 1}) reaction.gene_reaction_rule = 'b1779' _normalize_pseudoreaction(reaction) # should not change assert reaction.id == 'NPT1'
def test_compartments(self, model): assert set(model.compartments) == {"c", "e"} model = Model("test", "test") met_c = Metabolite("a_c", compartment="c") met_e = Metabolite("a_e", compartment="e") rxn = Reaction("foo") rxn.add_metabolites({met_e: -1, met_c: 1}) model.add_reactions([rxn]) assert model.compartments == {'c': '', 'e': ''} model.compartments = {'c': 'cytosol'} assert model.compartments == {'c': 'cytosol', 'e': ''}
def test_compartments(model): assert set(model.compartments) == {"c", "e"} model = Model("test", "test") met_c = Metabolite("a_c", compartment="c") met_e = Metabolite("a_e", compartment="e") rxn = Reaction("foo") rxn.add_metabolites({met_e: -1, met_c: 1}) model.add_reactions([rxn]) assert model.compartments == {'c': '', 'e': ''} model.compartments = {'c': 'cytosol'} assert model.compartments == {'c': 'cytosol', 'e': ''}
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)
def reaction_from_dict(reaction, model): new_reaction = Reaction() for k, v in iteritems(reaction): if k in {'objective_coefficient', 'reversibility', 'reaction'}: continue elif k == 'metabolites': new_reaction.add_metabolites( OrderedDict((model.metabolites.get_by_id(str(met)), coeff) for met, coeff in iteritems(v))) else: setattr(new_reaction, k, v) return new_reaction
def test_get_yield(self): model = Model("test") met1 = Metabolite(id="S7P", formula="C7H15O10P") met2 = Metabolite(id="T3P1", formula="C3H7O6P") met3 = Metabolite(id="E4P", formula="C4H9O7P") met4 = Metabolite(id="F6P", formula="C6H13O9P") model.add_metabolites((met1, met2, met3, met4)) react1 = Reaction(id="r1", name="Transaldolase") react1.add_metabolites({met1: -1, met2: -1, met3: 1, met4: 1}) react2 = Reaction(id="r2") react2.add_metabolites({met1: -1}) react3 = Reaction(id="r3") react3.add_metabolites({met2: -1}) react4 = Reaction(id="r4") react4.add_metabolites({met3: -1}) react5 = Reaction(id="r5") react5.add_metabolites({met4: -1}) model.add_reactions((react1, react2, react3, react4, react5)) fluxes = { react1.id: 1, react2.id: -1, react3.id: -1, react4.id: 1, react5.id: 1 } status, yields = get_yields(fluxes, model) assert status is True assert yields == { "C": { met3: 0.4, met4: 0.6 }, "H": { met3: 9 / 22, met4: 13 / 22 }, "O": { met3: 7 / 16, met4: 9 / 16 }, "P": { met3: 0.5, met4: 0.5 } }
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)
def reaction_from_dict(reaction, model): new_reaction = Reaction() for k, v in iteritems(reaction): if k in {'objective_coefficient', 'reversibility', 'reaction'}: continue elif k == 'metabolites': new_reaction.add_metabolites(OrderedDict( (model.metabolites.get_by_id(str(met)), coeff) for met, coeff in iteritems(v))) else: setattr(new_reaction, k, v) return new_reaction
def test_sbo_annotation(self, model): rxns = model.reactions rxns.EX_o2_e.annotation.clear() fake_DM = Reaction("DM_h_c") model.add_reaction(fake_DM) fake_DM.add_metabolites({model.metabolites.get_by_id("h_c"): -1}) # this exchange will be set wrong. The function should not overwrite # an existing SBO annotation rxns.get_by_id("EX_h_e").annotation["SBO"] = "SBO:0000628" add_SBO(model) assert rxns.EX_o2_e.annotation["SBO"] == "SBO:0000627" assert rxns.DM_h_c.annotation["SBO"] == "SBO:0000628" assert rxns.EX_h_e.annotation["SBO"] == "SBO:0000628"
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__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
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
def test_add_metabolite(self, model): with pytest.raises(ValueError): model.add_metabolites(Metabolite()) with 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 len(model._contexts[0]._history) == 0 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 combine=False reaction = model.reactions.get_by_id("ATPM") old_stoich = reaction._metabolites[model.metabolites.get_by_id( "h2o_c")] with model: reaction.add_metabolites({'h2o_c': 2.5}, combine=False) assert reaction._metabolites[model.metabolites.get_by_id( "h2o_c")] == 2.5 assert reaction._metabolites[model.metabolites.get_by_id( "h2o_c")] == old_stoich # 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 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)
def test_add_metabolite(model): with pytest.raises(ValueError): model.add_metabolites(Metabolite()) with 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 len(model._contexts[0]._history) == 0 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 combine=False reaction = model.reactions.get_by_id("ATPM") old_stoich = reaction._metabolites[ model.metabolites.get_by_id("h2o_c")] with model: reaction.add_metabolites({'h2o_c': 2.5}, combine=False) assert reaction._metabolites[ model.metabolites.get_by_id("h2o_c")] == 2.5 assert reaction._metabolites[ model.metabolites.get_by_id("h2o_c")] == old_stoich # 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_SBO_annotation(self): model = create_test_model("textbook") rxns = model.reactions rxns.EX_o2_e.annotation.clear() fake_DM = Reaction("DM_h_c") model.add_reaction(fake_DM) fake_DM.add_metabolites({model.metabolites.get_by_id("h_c"): -1}) # this exchange will be set wrong. The function should not overwrite # an existing SBO annotation rxns.get_by_id("EX_h_e").annotation["SBO"] = "SBO:0000628" add_SBO(model) self.assertEqual(rxns.EX_o2_e.annotation["SBO"], "SBO:0000627") self.assertEqual(rxns.DM_h_c.annotation["SBO"], "SBO:0000628") self.assertEqual(rxns.EX_h_e.annotation["SBO"], "SBO:0000628")
def geometric_fba_model(): """ Generate geometric FBA model as described in [1]_ References ---------- .. [1] Smallbone, Kieran & Simeonidis, Vangelis. (2009). Flux balance analysis: A geometric perspective. Journal of theoretical biology.258. 311-5. 10.1016/j.jtbi.2009.01.027. """ test_model = Model("geometric_fba_paper_model") test_model.add_metabolites(Metabolite("A")) test_model.add_metabolites(Metabolite("B")) v_1 = Reaction("v1", upper_bound=1.0) v_1.add_metabolites({test_model.metabolites.A: 1.0}) v_2 = Reaction("v2", lower_bound=-1000.0) v_2.add_metabolites({ test_model.metabolites.A: -1.0, test_model.metabolites.B: 1.0 }) v_3 = Reaction("v3", lower_bound=-1000.0) v_3.add_metabolites({ test_model.metabolites.A: -1.0, test_model.metabolites.B: 1.0 }) v_4 = Reaction("v4", lower_bound=-1000.0) v_4.add_metabolites({ test_model.metabolites.A: -1.0, test_model.metabolites.B: 1.0 }) v_5 = Reaction("v5") v_5.add_metabolites({ test_model.metabolites.A: 0.0, test_model.metabolites.B: -1.0 }) test_model.add_reactions([v_1, v_2, v_3, v_4, v_5]) test_model.objective = "v5" return test_model
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)
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_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(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_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_assess(self, model, solver): with model: assert assess(model, model.reactions.GLCpts, solver=solver) is True pyr = model.metabolites.pyr_c a = Metabolite('a') b = Metabolite('b') model.add_metabolites([a, b]) pyr_a2b = Reaction('pyr_a2b') pyr_a2b.add_metabolites({pyr: -1, a: -1, b: 1}) model.add_reactions([pyr_a2b]) res = assess(model, pyr_a2b, 0.01, solver=solver) expected = { 'precursors': {a: {'required': 0.01, 'produced': 0.0}}, 'products': {b: {'required': 0.01, 'capacity': 0.0}}} assert res == expected
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 build_drain_from_metabolite_id(self, cpd_id, lower_bound, upper_bound, prefix = 'EX_', prefix_name = 'Exchange for ', sbo = 'SBO:0000627'): if cpd_id in self.metabolites: id = prefix + cpd_id cobra_metabolite = self.metabolites[cpd_id] object_stoichiometry = {cobra_metabolite : -1} drain_reaction = Reaction(id=id, name= prefix_name + cobra_metabolite.name, lower_bound=lower_bound, upper_bound=upper_bound) drain_reaction.add_metabolites(object_stoichiometry) # exchange reaction - ... provide matter influx or efflux to a model, for example to replenish a #metabolic network with raw materials ... drain_reaction.annotation[self.SBO_ANNOTATION] = sbo return drain_reaction
def test_assess(model: Model, all_solvers: List[str]) -> None: """Test assess functions.""" with model: assert assess(model, model.reactions.GLCpts, solver=all_solvers) is True pyr = model.metabolites.pyr_c a = Metabolite("a") b = Metabolite("b") model.add_metabolites([a, b]) pyr_a2b = Reaction("pyr_a2b") pyr_a2b.add_metabolites({pyr: -1, a: -1, b: 1}) model.add_reactions([pyr_a2b]) res = assess(model, pyr_a2b, 0.01, solver=all_solvers) expected = { "precursors": {a: {"required": 0.01, "produced": 0.0}}, "products": {b: {"required": 0.01, "capacity": 0.0}}, } assert res == expected
def test_gene_knock_out(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_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