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_iadd(self, 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 have changed assert EX_h2o.gene_reaction_rule == '' assert EX_h2o.metabolites[model.metabolites.h2o_e] == -1.0 # what about adding 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 # what about combining 2 gpr's 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__has_gene_reaction_rule(): reaction = Reaction('rxn') assert _has_gene_reaction_rule(reaction) is False reaction.gene_reaction_rule = 'b1779' assert _has_gene_reaction_rule(reaction) is True reaction.gene_reaction_rule = ' ' assert _has_gene_reaction_rule(reaction) is False
def test_add_reaction_context(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 }) 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_gpr(): model = Model() reaction = Reaction("test") # Set GPR to a reaction not in a model reaction.gene_reaction_rule = "(g1 or g2) and g3" assert reaction.gene_reaction_rule == "(g1 or g2) and g3" assert len(reaction.genes) == 3 # Adding reaction with a GPR propagates to the model model.add_reactions([reaction]) assert len(model.genes) == 3 # Ensure the gene objects are the same in the model and reaction reaction_gene = list(reaction.genes)[0] model_gene = model.genes.get_by_id(reaction_gene.id) assert reaction_gene is model_gene # Test ability to handle uppercase AND/OR with warnings.catch_warnings(): warnings.simplefilter("ignore") reaction.gene_reaction_rule = "(b1 AND b2) OR (b3 and b4)" assert reaction.gene_reaction_rule == "(b1 and b2) or (b3 and b4)" assert len(reaction.genes) == 4 # Ensure regular expressions correctly extract genes from malformed # GPR string with warnings.catch_warnings(): warnings.simplefilter("ignore") reaction.gene_reaction_rule = "(a1 or a2" assert len(reaction.genes) == 2 reaction.gene_reaction_rule = "(forT or " assert len(reaction.genes) == 1
def convert_modelreaction(self, reaction, bigg=False): mr_id = reaction.id name = reaction.name annotation = reaction.annotation lower_bound, upper_bound = reaction.get_reaction_constraints() id = build_rxn_id(mr_id) if bigg and "bigg.reaction" in annotation: id = annotation["bigg.reaction"] gpr = reaction.get_gpr() cobra_reaction = Reaction(id, name=name, lower_bound=lower_bound, upper_bound=upper_bound) cobra_reaction.annotation[self.SBO_ANNOTATION] = "SBO:0000176" #biochemical reaction cobra_reaction.annotation.update(annotation) if id.startswith('rxn'): cobra_reaction.annotation["seed.reaction"] = id.split("_")[0] cobra_reaction.add_metabolites(self.convert_modelreaction_stoichiometry(reaction)) cobra_reaction.gene_reaction_rule = reaction.gene_reaction_rule for genes in gpr: for gene in genes: if not gene in self.genes: self.genes[gene] = gene return cobra_reaction
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_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_reverse_reaction(): model = Model() reaction = Reaction('AB') model.add_reaction(reaction) reaction.build_reaction_from_string('a --> b') _reverse_reaction(reaction) assert reaction.reaction == 'b <-- a'
def test_iadd(model: Model) -> None: """Test in-place addition of reaction.""" 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__normalize_pseudoreaction_biomass_has_gpr(): reaction = Reaction('my_biomass_2') 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 == 'my_biomass_2'
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__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__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_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)
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_find_boundary_types_demand(model: Model) -> None: """Test boundary type identification for demands.""" dm = Reaction("demand") model.add_reaction(dm) dm.build_reaction_from_string("atp_c ->") dm = model.demands assert len(dm) == 1 assert "demand" in [r.id for r in dm]
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 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 test_find_boundary_types_sink(model: Model) -> None: """Test boundary type identification for sinks.""" sn = Reaction("sink") model.add_reaction(sn) sn.build_reaction_from_string("atp_c <->") sn.bounds = -1000, 1000 sn = model.sinks assert len(sn) == 1 assert "sink" in [r.id for r in sn]
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(): 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_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_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__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(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 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 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 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_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 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(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_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_custom_hashes(): # These hashes are generated from old IDs in models (in reaction strings), # and they match to these corrected BiGG reaction IDs cases = [ ('39b5f90a1919aef07473e2f835ce63af', 'EX_frmd_e', 'foam_e <=>'), ('92f1047c72db0a36413d822863be514e', 'EX_phllqne_e', 'phyQ_e <=>'), ] model = Model() for reaction_hash, bigg_id, reaction_string in cases: reaction = Reaction(bigg_id) model.add_reaction(reaction) reaction.build_reaction_from_string(reaction_string) lookup_dict = {m.id: m.id for m in model.metabolites} assert hash_reaction(reaction, lookup_dict) == reaction_hash
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 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 reaction_component_production(model, reaction): tm = TimeMachine() for metabolite in reaction.metabolites: test = Reaction("EX_%s_temp" % metabolite.id) test._metabolites[metabolite] = -1 # hack frozen set from cobrapy to be able to add a reaction metabolite._reaction = set(metabolite._reaction) tm(do=partial(model.add_reactions, [test]), undo=partial(model.remove_reactions, [test])) tm(do=partial(setattr, model, "objective", test.id), undo=partial(setattr, model, "objective", model.objective)) try: print(metabolite.id, "= ", model.solve().f) except SolveError: print(metabolite, " cannot be produced (reactions: %s)" % metabolite.reactions) finally: tm.reset()
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 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 convert_ids_model(example_model): example_model.id = 'A bad id' example_model.add_reaction(Reaction('DADA')) example_model.reactions.get_by_id('DADA').add_metabolites({ Metabolite('dad_DASH_2_c'): -1 }) return convert_ids(example_model.copy())
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_prune_unused_rxns_output_type(self, model): # test that the output contains reaction objects reaction = Reaction('foo') model.add_reaction(reaction) model_pruned, unused = delete.prune_unused_reactions(model) assert isinstance(model_pruned, Model) assert isinstance(unused[0], Reaction)
def test_prune_unused_reactions_output_type(model: Model) -> None: """Test the output type of unused reactions pruning.""" reaction = Reaction("foo") model.add_reactions([reaction]) model_pruned, unused = prune_unused_reactions(model) assert isinstance(model_pruned, Model) # test that the output contains reaction objects assert isinstance(unused[0], 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