def test_no_update_if_boundary(self): """ Check that formula is not updated when metabolite is part of a boundary reaction """ react = Reaction("rea") met1 = Metabolite("met1") react.add_metabolites({met1: -1}) result = update_formula_from_neighborhood(met1) assert result is False assert not met1.formula
def test_no_update_if_mutliple_metabolites_wo_formula(self): """ Check that formula is not updated if multiple metabolites have no formula set """ react = Reaction("rea") met1 = Metabolite("met1", formula="C7H8O2") met2 = Metabolite("met2") met3 = Metabolite("met3") react.add_metabolites({met1: 1, met3: 1, met2: -1}) result = update_formula_from_neighborhood(met3) assert result is False assert not met3.formula
def test_successful_update(self): """ Check that metabolite formula is successfully updated from a reaction where all other metabolite formulae are set """ react = Reaction("rea") met1 = Metabolite("met1", formula="C7H8O2") met2 = Metabolite("met2", formula="C8H8O4") met3 = Metabolite("met3") react.add_metabolites({met1: 1, met3: 1, met2: -1}) result = update_formula_from_neighborhood(met3) assert result is True assert met3.formula == "CO2"
def test_invalid_if_any_reaction_not_in_same_compartment(self): self.metabolite1.compartment = "c" self.metabolite2.compartment = "c" self.compartment.id = "c" assert self.evidence.is_valid() is True met1 = Metabolite("m1") met2 = Metabolite("m2") react2 = Reaction("r2") react2.add_metabolites({met1: -1, met2: 1}) react2.add_child(self.gene) assert self.evidence.is_valid() is False
def test_no_map_by_stoichiometry_if_any_metabolite_not_mapped( self, database, progress): model = Model() met1 = Metabolite("m1") met2 = Metabolite("m2") model.add_metabolites((met1, met2)) model.database_mapping.update({met1: 1}) reaction = Reaction("r1") reaction.add_metabolites({met1: -1, met2: -1}) model.add_reactions([reaction]) update_reaction_database_mapping(database, model, progress) assert reaction not in model.database_mapping
def test_map_reaction_by_annotation(self, database, progress): model = Model() met1 = Metabolite("m1") met2 = Metabolite("m2") model.add_metabolites([met1, met2]) reaction = Reaction("r1") reaction.add_metabolites({met1: -1, met2: 1}) reaction.annotation.add( Annotation(identifier="MNXR14892", collection="metanetx.reaction")) model.add_reactions([reaction]) update_reaction_database_mapping(database, model, progress) assert model.database_mapping[reaction] == 1
def test_map_reaction_by_stoichiometry(self, database, progress): model = Model() met1 = Metabolite("m1") met2 = Metabolite("m2") met3 = Metabolite("m3") met4 = Metabolite("m4") model.add_metabolites((met1, met2, met3, met4)) model.database_mapping.update({met1: 1, met2: 2, met3: 3, met4: 4}) reaction = Reaction("r1") reaction.add_metabolites({met1: -1, met2: -1, met3: 1, met4: 1}) model.add_reactions([reaction]) update_reaction_database_mapping(database, model, progress) assert model.database_mapping[reaction] == 1
def test_balancing_status2(self): charge = 0 formula = "H2O" met1 = Metabolite("test1", charge=charge, formula=formula) met2 = Metabolite("test2", charge=charge, formula=formula) stoichiometry = 1 reaction = Reaction("test") reaction.add_metabolites({met1: stoichiometry, met2: -stoichiometry}) self.widget.set_item(reaction, self.model) assert self.widget.statusLabel.toolTip( ) == self.widget.msg_standard.format(status="balanced", charge="OK", elements="OK")
def test_no_update_for_contradicting_formulae(self): """ Check that the formula is not updated if there are multiple reactions and the derived formula of those are contradicting """ react = Reaction("rea") # CO2 expected met1 = Metabolite("met1", formula="C7H8O2") met2 = Metabolite("met2", formula="C8H8O4") met3 = Metabolite("met3") react.add_metabolites({met1: 1, met3: 1, met2: -1}) react1 = Reaction("rea2") # H2O expected met4 = Metabolite("met4", formula="H2O") react1.add_metabolites({met3: -1, met4: 1}) result = update_formula_from_neighborhood(met3) assert result is False assert not met3.formula
def test_updating(self): model = Model() met1 = Metabolite(id="met1", formula="H2O", name="Water", charge=0., compartment="c") react1 = Reaction(id="react1", name="test2", subsystem="test2", lower_bound=0., upper_bound=1000.) react1.add_metabolites({met1: -1}) model.add_metabolites([met1]) model.add_reactions([react1]) model.setup_tables() assert model.QtReactionTable.rowCount() == 1 assert model.QtMetaboliteTable.rowCount() == 1 # Check that content is right for i, element in enumerate(model.QtMetaboliteTable.header): assert str(getattr(met1, element.lower())) == model.QtMetaboliteTable.item(0, i).text() # Check that metabolite id is in table assert met1.id in model.QtReactionTable.item(0, 2).text() # Change metabolite met1.id = "new_id" met1.name = "new_name" met1.formula = "H2O2" met1.name = "None" met1.charge = 1. met1.compartment = "e" # Tables are out of sync for i, element in enumerate(model.QtMetaboliteTable.header): assert str(getattr(met1, element.lower())) != model.QtMetaboliteTable.item(0, i).text() # Check reaction table out of sync assert react1.id not in model.QtReactionTable.item(0, 2).text() model.gem_update_metabolites([met1]) # Metabolite table updated for i, element in enumerate(model.QtMetaboliteTable.header): assert str(getattr(met1, element.lower())) == model.QtMetaboliteTable.item(0, i).text() # Reaction table updated assert met1.id in model.QtReactionTable.item(0, 2).text()
def test_update_iteratively(self): """ Check that metabolite are successfully updated one after another """ react = Reaction("rea") met1 = Metabolite("met1", formula="C7H8O2") met2 = Metabolite("met2") met3 = Metabolite("met3") # Update to CO2 in second iteration react.add_metabolites({met1: 1, met3: 1, met2: -1}) react1 = Reaction("rea2") # Transfer C8H8O4 met4 = Metabolite("met4", formula="C8H8O4") react1.add_metabolites({met2: -1, met4: 1}) # Setup model model = Model("id") model.add_metabolites([met1, met2, met3, met4]) model.add_reactions([react, react1]) return_value = update_formulae_iteratively(model) assert met2.formula == met4.formula assert met3.formula == "CO2" assert set(return_value) == set([met2, met3])
def copy_reaction(self, move=False): """ Copy or move reactions between compartmsntes Parameters ---------- move : bool Returns ------- """ # Get selected items rows = self.dataView.get_selected_rows() reactions = [self.dataTable.item_from_row(i) for i in rows] # Only continue if rows are selected if not rows: return # Collect compartments of metabolites in the selected reactions compartments = set() for reaction in reactions: compartments.update([metabolite.compartment for metabolite in reaction.metabolites]) # Get compartment mapping from user compartment_mapping = dict() for compartment in compartments: value, status = QInputDialog().getItem(self, "Choose target compartment", 'Choose target for compartment "{}":'.format(compartment), list(self.model.gem_compartments.keys()), 0, False) if not status: return else: compartment_mapping[compartment] = value progress = QProgressDialog("{} reactions".format("Moving" if move else "Copying"), "Cancel", 0, len(reactions), self) # Copy reactions using matching metabolite from other compartment for n, reaction in enumerate(reactions): # Check user input and update progress dialog if progress.wasCanceled(): progress.close() return else: progress.setValue(n) QApplication.processEvents() metabolites = dict() # Collect corresponding metabolites in target compartment for key, value in reaction.metabolites.items(): target_compartment = compartment_mapping[key.compartment] putative_target_metabolits = find_duplicate_metabolite(key, [x for x in self.model.metabolites if x.compartment == target_compartment], same_compartment=False) corresponding_metabolite = None if putative_target_metabolits: best_hit, score = putative_target_metabolits[0] if best_hit.compartment == target_compartment and score >= 2.: corresponding_metabolite = best_hit if not corresponding_metabolite: corresponding_metabolite = self.model.copy_metabolite(key, target_compartment) metabolites[corresponding_metabolite] = value # Create new reaction if the move flag is false if not move: new_reaction = Reaction(id=generate_copy_id(reaction.id, self.model.reactions), name=reaction.name, subsystem=reaction.subsystem, lower_bound=reaction.lower_bound, upper_bound=reaction.upper_bound, comment=reaction.comment) new_reaction.annotation = reaction.annotation.copy() new_reaction.add_metabolites(metabolites) self.model.add_reactions([new_reaction]) # Set objective coefficient after adding reaction to model new_reaction.objective_coefficient = reaction.objective_coefficient self.model.QtReactionTable.update_row_from_item(new_reaction) # Update existing reactions with new metabolites if moving else: reaction.clear_metabolites() reaction.add_metabolites(metabolites) self.model.QtReactionTable.update_row_from_link(rows[n]) progress.close()
class TestStoichiometryDisplayWidget: @pytest.fixture(autouse=True) def setup_items(self): self.parent = QWidget() self.widget = StoichiometryDisplayWidget(self.parent) self.test_met_id = "test_id" self.test_react_id = "test_id2" self.test_stoich = -1.5 self.metabolite = Metabolite(id=self.test_met_id) self.reaction = Reaction(id=self.test_react_id) self.reaction.add_metabolites({self.metabolite: self.test_stoich}) self.model = Model("test") def test_setup(self): assert self.widget.dataTable.rowCount() == 0 assert self.widget.add_button.isEnabled() is True assert self.widget.edit_button is None assert self.widget.delete_button.isEnabled() is False assert self.metabolite.id == self.test_met_id assert self.reaction.id == self.test_react_id assert self.reaction.metabolites == {self.metabolite: self.test_stoich} def test_setting_reaction(self): self.widget.set_item(self.reaction, self.model) assert self.widget.dataTable.rowCount() == 1 assert self.widget.dataTable.item(0, 0).text() == self.test_met_id assert self.widget.dataTable.item(0, 0).link is self.metabolite assert self.widget.dataTable.item(0, 1).data(2) == self.test_stoich assert self.widget.dataTable.item(0, 1).link is self.metabolite def test_changed(self): self.widget.set_item(self.reaction, self.model) receiver = MockSlot() self.widget.changed.connect(receiver.slot) assert self.widget.content_changed is False self.widget.dataTable.item(0, 1).setData(12., 2) assert self.widget.dataTable.item(0, 1).data(2) == 12. assert self.widget.content_changed is True assert receiver.called is True assert receiver.last_caller is self.widget def test_changed2(self): self.widget.set_item(self.reaction, self.model) new_metabolite = Metabolite("test_2") new_stoich = 0. receiver = MockSlot() self.widget.changed.connect(receiver.slot) self.widget.dataTable.update_row_from_item( (new_metabolite, new_stoich)) assert self.widget.content_changed is True assert self.widget.dataTable.item(1, 0).text() == new_metabolite.id assert self.widget.dataTable.item(1, 0).link is new_metabolite assert self.widget.dataTable.item(1, 1).data(2) == new_stoich assert self.widget.dataTable.item(1, 1).link is new_metabolite assert receiver.called is True assert receiver.last_caller is self.widget def test_activation_of_delete(self): self.widget.set_item(self.reaction, self.model) assert self.widget.delete_button.isEnabled() is False self.widget.dataView.selectRow(0) assert self.widget.delete_button.isEnabled() is True self.widget.dataView.clearSelection() assert self.widget.delete_button.isEnabled() is False def test_balancing_status(self): self.widget.set_item(self.reaction, self.model) assert self.widget.statusLabel.toolTip() == self.widget.msg_boundary def test_balancing_status2(self): charge = 0 formula = "H2O" met1 = Metabolite("test1", charge=charge, formula=formula) met2 = Metabolite("test2", charge=charge, formula=formula) stoichiometry = 1 reaction = Reaction("test") reaction.add_metabolites({met1: stoichiometry, met2: -stoichiometry}) self.widget.set_item(reaction, self.model) assert self.widget.statusLabel.toolTip( ) == self.widget.msg_standard.format(status="balanced", charge="OK", elements="OK") def test_balancing_status3(self): charge = 0. formula = "H2O" met1 = Metabolite("test1", charge=charge, formula=formula) met2 = Metabolite("test2", charge=charge + 1, formula=formula) stoichiometry = 1 reaction = Reaction("test") reaction.add_metabolites({met1: stoichiometry, met2: -stoichiometry}) self.widget.set_item(reaction, self.model) assert self.widget.statusLabel.toolTip( ) == self.widget.msg_standard.format(status="unbalanced", charge="-1.0", elements="OK") def test_get_stoichiometry(self): self.widget.set_item(self.reaction, self.model) assert self.widget.get_stoichiometry() == self.reaction.metabolites def test_get_stoichiometry2(self): self.widget.set_item(Reaction(), self.model) assert self.widget.get_stoichiometry() == {} def test_save_state(self): self.widget.set_item(self.reaction, self.model) new_stoich = -20. self.widget.dataTable.item(0, 1).setData(new_stoich, 2) self.widget.save_state() assert self.reaction.metabolites == {self.metabolite: new_stoich}
class TestAssertionLocalization: @pytest.fixture(autouse=True) def setup_items(self): self.gene = Gene("g1") self.compartment = Compartment("c") self.metabolite1 = Metabolite("m1") self.metabolite2 = Metabolite("m2") self.reaction = Reaction("r1") self.reaction.add_metabolites({ self.metabolite1: -1, self.metabolite2: 1 }) self.reaction.add_child(self.gene) self.evidence = Evidence(entity=self.gene, assertion="Localization", target=self.compartment) def test_valid_if_metabolites_in_same_compartment_as_gene(self): self.metabolite1.compartment = "c" self.metabolite2.compartment = "c" self.compartment.id = "c" assert self.evidence.is_valid() is True def test_invalid_if_metabolites_not_in_same_compartment(self): self.metabolite1.compartment = "e" self.metabolite2.compartment = "e" self.compartment.id = "c" assert self.evidence.is_valid() is False def test_invalid_if_any_reaction_not_in_same_compartment(self): self.metabolite1.compartment = "c" self.metabolite2.compartment = "c" self.compartment.id = "c" assert self.evidence.is_valid() is True met1 = Metabolite("m1") met2 = Metabolite("m2") react2 = Reaction("r2") react2.add_metabolites({met1: -1, met2: 1}) react2.add_child(self.gene) assert self.evidence.is_valid() is False def test_error_if_gene_not_added_to_reaction(self): gene = Gene("g1") evidence = Evidence(entity=gene, assertion="Localization") assert evidence.is_valid() is None def test_entity_needed(self): evidence = Evidence(assertion="Localization") assert evidence.is_valid() is None evidence.set_entity(self.gene) assert evidence.is_valid() is None evidence.set_target(self.compartment) assert evidence.is_valid() is not None
class TestModelDeleteItems: @pytest.fixture(autouse=True) def setup_complete_model(self): self.model = Model("model") # Setup reaction1 self.metabolite = Metabolite("m1") self.reaction = Reaction("r1") self.gene = Gene("g1") self.reaction.add_child(self.gene) self.model.add_genes((self.gene,)) self.reaction.add_metabolites({self.metabolite: -1}) self.model.add_reactions((self.reaction,)) # Setup reaction2 self.metabolite2 = Metabolite("m2") self.reaction2 = Reaction("r2") self.gene2 = Gene("g2") self.genegroup = GeneGroup() self.genegroup.add_child(self.gene2) self.reaction2.add_child(self.genegroup) self.model.add_genes((self.gene2,)) self.reaction2.add_metabolites({self.metabolite2: 1}) self.model.add_reactions((self.reaction2,)) # Setup evidences self.evidence = Evidence(assertion="Catalyzes") self.evidence.set_entity(self.gene) self.evidence.set_target(self.reaction) self.reference = Reference() self.model.add_reference(self.reference) self.evidence.add_reference(self.reference) self.model.add_evidence(self.evidence) # Setup test case self.testcase = ModelTest() reaction_setting = ReactionSetting(self.reaction, 1000., -1000., 0.) gene_setting = GeneSetting(gene=self.gene2, activity=False) outcome = Outcome(self.reaction2, 0., "greater") self.testcase.add_outcome(outcome) self.testcase.add_setting(gene_setting) self.testcase.add_setting(reaction_setting) self.model.add_test(self.testcase) self.reference2 = Reference() self.model.add_reference(self.reference2) self.testcase.add_reference(self.reference2) self.model.setup_tables() def test_setup(self): # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_deletion_metabolite(self): # Action self.model.gem_remove_metabolites((self.metabolite,)) # Test gene gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model, valid=False) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction, valid=False) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_deletion_metabolite2(self): # Action self.model.gem_remove_metabolites((self.metabolite2,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model, valid=False) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2, valid=False) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_delete_reaction1(self): #### # Delete reaction # Check: # - gene present but removed from reaction1 # - metabolite present but removed from reaction1 # - reaction deleted # - evidence deleted # - testcase deleted # - reference present but removed from evidence # - reference2 present but removed from testcase #### # Action self.model.gem_remove_reactions((self.reaction,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model, valid=False) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test model test case_in_model(self.testcase, self.model, valid=False) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence, valid=False) reference_in_item(self.reference2, self.testcase, valid=False) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction, valid=False) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 # Check metabolite is still in reaction, but reaction not in metabolite assert self.metabolite in self.reaction.metabolites assert self.reaction not in self.metabolite.reactions metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence, valid=False) item_in_evidence(self.reaction, self.evidence, valid=False) # Check evidence is removed when reference deleted del self.evidence gc.collect() assert len(self.model.all_evidences) == 0 def test_deletion_reaction2(self): # Check: # - reaction2 removed # - test case removed # - reference removed from testcase # - gene2 removed from reaction # Action self.model.gem_remove_reactions((self.reaction2,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model, valid=False) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model, valid=False) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase, valid=False) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2, valid=False) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) # Check metabolite still in reaction, but reaction not in metabolite assert self.metabolite2 in self.reaction2.metabolites assert self.reaction2 not in self.metabolite2.reactions # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_delete_gene1(self): # Test gene deletion # Check: # - Gene removed from model # - Evidence removed from model # Action self.model.gem_remove_genes((self.gene,)) # Test genes gene_in_model(self.gene, self.model, valid=False) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test model test case_in_model(self.testcase, self.model) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence, valid=False) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction, valid=False) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence, valid=False) item_in_evidence(self.reaction, self.evidence, valid=False) # Check evidence is removed when reference deleted del self.evidence gc.collect() assert len(self.model.all_evidences) == 0 def test_delete_gene2(self): # Test removal of gene2 # Check: # - Gene2 removed from model # - Gene2 removed from reaction2 # - Testcase deleted from model # - Reference2 removed from testcase # Action self.model.gem_remove_genes((self.gene2,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model, valid=False) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model, valid=False) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase, valid=False) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2, valid=False) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_delete_testcase(self): # Action self.model.gem_remove_tests((self.testcase,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model, valid=False) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase, valid=False) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_delete_referenec(self): # Action self.model.gem_remove_references((self.reference,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model) # Test references reference_in_model(self.reference, self.model, valid=False) reference_in_model(self.reference2, self.model) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence, valid=False) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence) def test_delete_reference2(self): # Action self.model.gem_remove_references((self.reference2,)) # Test genes gene_in_model(self.gene, self.model) gene_in_model(self.gene2, self.model) # Test reactions reaction_in_model(self.reaction, self.model) reaction_in_model(self.reaction2, self.model) # Test metabolites metabolite_in_model(self.metabolite, self.model) metabolite_in_model(self.metabolite2, self.model) # Test evidences evidence_in_model(self.evidence, self.model) # Test model test case_in_model(self.testcase, self.model) # Test references reference_in_model(self.reference, self.model) reference_in_model(self.reference2, self.model, valid=False) # Test connections # Reference <-> Evidence reference_in_item(self.reference, self.evidence) # Reference2 <-> Testcase reference_in_item(self.reference2, self.testcase, valid=False) # Gene1 <-> Reaction1 gene_in_reaction(self.gene, self.reaction) gene_in_reaction(self.gene2, self.reaction2) # Metabolite1 <-> Reaction1 metabolite_in_reaction(self.metabolite, self.reaction) metabolite_in_reaction(self.metabolite2, self.reaction2) # Evidence <-> Gene1/Reaction item_in_evidence(self.gene, self.evidence) item_in_evidence(self.reaction, self.evidence)
class TestRunTest: @pytest.fixture(autouse=True) def setup_test(self): self.model = Model("id") self.metabolite1 = Metabolite("m1") self.metabolite2 = Metabolite("m2") self.reaction1 = Reaction("r1", lower_bound=-1000., upper_bound=1000.) self.model.add_reactions((self.reaction1, )) self.reaction1.objective_coefficient = 0. self.r1_init_setting = self.reaction1.get_setting() self.reaction1.add_metabolites({ self.metabolite1: -1, self.metabolite2: 1 }) self.reaction1.flux_value = 50. self.setting1 = ReactionSetting(reaction=self.reaction1, upper_bound=0., lower_bound=0., objective_coefficient=1.) self.reaction2 = Reaction("r2", lower_bound=0., upper_bound=50.) self.model.add_reactions((self.reaction2, )) self.reaction2.objective_coefficient = 1. self.setting2 = ReactionSetting(reaction=self.reaction2, upper_bound=1000., lower_bound=-1000., objective_coefficient=0.) self.r2_init_setting = self.reaction2.get_setting() self.reaction2.add_metabolites({self.metabolite1: -1}) self.true_outcome1 = Outcome(reaction=self.reaction1, value=15., operator="less than") self.false_outcome1 = Outcome(reaction=self.reaction1, value=15., operator="greater than") @pytest.fixture() def mock_optimize(self, monkeypatch, solution): monkeypatch.setattr("GEMEditor.model.classes.cobra.Model.optimize", Mock(return_value=solution)) @pytest.fixture() def mock_optimize_infeasible(self, monkeypatch, infeasible_solution): monkeypatch.setattr("GEMEditor.model.classes.cobra.Model.optimize", Mock(return_value=infeasible_solution)) return infeasible_solution @pytest.fixture() def mock_get_original_settings(self, monkeypatch): return_value = [Mock(), Mock()] monkeypatch.setattr( "GEMEditor.analysis.model_test._get_original_settings", Mock(return_value=return_value)) return return_value @pytest.fixture() def progress(self): return Mock(wasCanceled=Mock(return_value=False)) def test_outcomes(self, solution): assert self.true_outcome1.check(solution.x_dict) is True assert self.false_outcome1.check(solution.x_dict) is False @pytest.mark.usefixtures("mock_optimize") def test_mock(self): result = Model().optimize() assert isinstance(result.x_dict, dict) @pytest.mark.usefixtures("mock_optimize") def test_run_test_true_outcome(self, progress): model_test = ModelTest() model_test.outcomes = [self.true_outcome1] results = run_tests((model_test, ), Model(), progress) status, _ = results[model_test] assert status is True @pytest.mark.usefixtures("mock_optimize") def test_run_test_false_outcome(self, progress): model_test = ModelTest() model_test.outcomes = [self.false_outcome1] results = run_tests((model_test, ), Model(), progress) status, _ = results[model_test] assert status is False @pytest.mark.usefixtures("mock_optimize") def test_run_test_false_outcome2(self, progress): model_test = ModelTest() model_test.outcomes = [self.true_outcome1, self.false_outcome1] results = run_tests((model_test, ), Model(), progress) status, _ = results[model_test] assert status is False def test_run_test_infeasible_solution(self, mock_optimize_infeasible, progress): model_test = ModelTest() model_test.outcomes = [self.true_outcome1, self.false_outcome1] results = run_tests((model_test, ), Model(), progress) status, solution = results[model_test] assert solution is mock_optimize_infeasible assert status is False @pytest.mark.usefixtures("mock_optimize") def test_value_restored(self, progress): model_test = ModelTest() self.setting2.do = Mock() model_test.reaction_settings = [self.setting1, self.setting2] assert self.setting2.do.called is False assert self.reaction1 is self.setting1.reaction results = run_tests((model_test, ), Model(), progress) status, _ = results[model_test] assert self.setting2.do.called is True assert self.reaction1.upper_bound == self.r1_init_setting.upper_bound assert self.reaction1.lower_bound == self.r1_init_setting.lower_bound assert self.reaction1.objective_coefficient == self.r1_init_setting.objective_coefficient @pytest.mark.usefixtures("mock_optimize") def test_restore_initial_get_original_called(self, mock_get_original_settings, progress): original_settings = mock_get_original_settings assert GEMEditor.analysis.model_test._get_original_settings.called is False model_test = ModelTest() model_test.outcomes = [self.true_outcome1] results = run_tests((model_test, ), Model(), progress) status, _ = results[model_test] assert GEMEditor.analysis.model_test._get_original_settings.called is True for x in original_settings: assert x.do.called is True
class TestGetOriginalSettings: @pytest.fixture(autouse=True) def setup_items(self): self.model = Model("id") self.m1 = Metabolite("m1") self.m2 = Metabolite("m2") self.r1 = Reaction(id="r1") self.model.add_reactions((self.r1, )) def test_boundary_forward(self): self.r1.add_metabolites({self.m1: -1}) # Original settings self.r1.upper_bound = 200. self.r1.lower_bound = -200 self.r1.objective_coefficient = 1 # Get the setting of a boundary reaction setting = _get_original_settings(self.model)[0] # Check that original values are stored assert setting.reaction is self.r1 assert setting.upper_bound == 200 # Check that reaction is producing only assert setting.lower_bound == 0. assert setting.objective_coefficient == 0. def test_boundary_reverse(self): self.r1.add_metabolites({self.m1: 1}) # Original settings self.r1.upper_bound = 200. self.r1.lower_bound = -200 self.r1.objective_coefficient = 1 # Get the setting of a boundary reaction setting = _get_original_settings(self.model)[0] # Check that original values are stored assert setting.reaction is self.r1 assert setting.lower_bound == -200 # Check that reaction is producing only assert setting.upper_bound == 0. assert setting.objective_coefficient == 0. def test_inactive_reaction(self): self.r1.add_metabolites({self.m1: -1, self.m2: 1}) self.r1.lower_bound = 0. self.r1.upper_bound = 0. self.r1.objective_coefficient = 1. # Get the setting of a boundary reaction setting = _get_original_settings(self.model)[0] # Check that objective setting is deactivated assert setting.reaction is self.r1 assert setting.lower_bound == 0. assert setting.upper_bound == 0. assert setting.objective_coefficient == 0. @pytest.mark.parametrize("params, expectations", [((-200, 200, 1.), (-200, 200, 0.)), ((0, 200, 1.), (0., 200, 0.)), ((-200, 0, 1.), (-200, 0, 0.)), ((-200, -50, 1.), (-200, -50, 0.)), ((100, 200, 1.), (100, 200, 0.))]) def test_setting_for_optimized_reactions(self, params, expectations): self.r1.add_metabolites({self.m1: -1, self.m2: 1}) self.r1.lower_bound = params[0] self.r1.upper_bound = params[1] self.r1.objective_coefficient = params[2] setting = _get_original_settings(self.model)[0] # Check that the settings are expected assert setting.lower_bound == expectations[0] assert setting.upper_bound == expectations[1] assert setting.objective_coefficient == expectations[2] @pytest.mark.parametrize("params", [(-200, 200, 0.), (0, 200, 0.), (-200, 0, 0.), (-200, -50, 0.), (100, 200, 0.)]) def test_no_setting_for_nonoptimized_reactions(self, params): self.r1.add_metabolites({self.m1: -1, self.m2: 1}) self.r1.lower_bound = params[0] self.r1.upper_bound = params[1] self.r1.objective_coefficient = params[2] assert not _get_original_settings(self.model)
def parse_reaction(model_node, model, progress=None): """ Parse cobra reactions from a sbml file """ LOGGER.debug("Reading reactions..") reaction_list_node = model_node.find(sbml3_listOfReactions) boundary_list_node = model_node.find(sbml3_listOfParameters) objectives_list_node = model_node.find(fbc_listOfObjectives) # Read objectives objectives = {} if objectives_list_node is not None: objective = objectives_list_node.find(fbc_objective) if objective is not None: list_of_flux_objectives = objective.find(fbc_listOfFluxObjectives) if list_of_flux_objectives is not None: for child in list_of_flux_objectives.iterfind( fbc_fluxObjective): if child.get(fbc_reaction): objectives[clip( child.get(fbc_reaction), "R_")] = child.get(fbc_coefficient) or 0. # Read flux boundaries boundary_dict = {} for child in boundary_list_node.iterfind(sbml3_parameter): value = child.get("value") if value is not None: boundary_dict[child.get("id")] = float(value) reactions = [] if reaction_list_node is None: return elif progress is None: pass elif not progress.wasCanceled(): progress.setLabelText("Reading reactions...") progress.setRange(0, len(reaction_list_node)) else: return for i, reaction_node in enumerate( reaction_list_node.iterfind(sbml3_reaction)): if progress is None: pass elif not progress.wasCanceled(): progress.setValue(i) QApplication.processEvents() else: return reaction_id = clip(reaction_node.get("id"), "R_") new_reaction = Reaction( id=reaction_id, name=reaction_node.get("name"), upper_bound=float( boundary_dict[reaction_node.get(fbc_upperFluxBound)]), lower_bound=float( boundary_dict[reaction_node.get(fbc_lowerFluxBound)]), subsystem=reaction_node.get(ge_subsystem), comment=reaction_node.get(ge_comment)) # Add metabolites metabolites = {} for x in [sbml3_listOfReactants, sbml3_listOfProducts]: metabolite_list = reaction_node.find(x) if metabolite_list is not None: for metabolite_node in metabolite_list.iterfind( sbml3_speciesReference): metabolite = model.metabolites.get_by_id( clip(metabolite_node.get("species"), "M_")) value = float(metabolite_node.get("stoichiometry")) if x == sbml3_listOfReactants: value = -value metabolites[metabolite] = value new_reaction.add_metabolites(metabolites) # Add balancing status new_reaction.update_balancing_status() # Add genes gene_node = reaction_node.find(fbc_geneProductAssociation) if gene_node is not None: _parse_gene_xml_tree(gene_node, new_reaction, model.genes) # Parse annotation annotate_element_from_xml(reaction_node, new_reaction) reactions.append(new_reaction) model.add_reactions(reactions) LOGGER.debug("Reactions added to model!") for key, value in objectives.items(): try: reaction = model.reactions.get_by_id(key) except KeyError: LOGGER.warning( "Reaction {} not existing in the model, but listed in objectives!" .format(key)) continue else: reaction.objective_coefficient = float(value) return reactions