def query_owlsim(patient: MmeRequest, sim_engine: PhenoSimEngine, taxon: str = None) -> MmeResponse: """ Query owlsim with features from MmeRequest object, see extract_features_from_mme for what features are selected to be sent to owlsim """ features = extract_features_from_mme(patient) results = sim_engine.search(id_list=features, limit=100, taxon_filter=taxon, is_feature_set=False) mme_response = MmeResponse() for result in results.matches: mme_score = Score(patient=result.score) mme_result = Result(mme_score) if result.id.startswith('MONDO'): mme_result._disease = result.id mme_result._disease_label = result.label else: mme_result._gene = result.id mme_result._gene_label = result.label mme_response.results.append(mme_result) return mme_response
def setup_class(self): self.resolve_mock = patch.object(PhenoSimEngine, '_resolve_nodes_to_phenotypes', side_effect=mock_resolve_nodes) self.mock_scigraph = patch( 'ontobio.util.scigraph_util.get_scigraph_nodes', side_effect=mock_get_scigraph_nodes) self.owlsim2_api = OwlSim2Api() self.owlsim2_api.statistics = IcStatistic(mean_mean_ic=6.82480, mean_sum_ic=120.89767, mean_cls=15.47425, max_max_ic=16.16108, max_sum_ic=6746.96160, individual_count=65309, mean_max_ic=9.51535) self.pheno_sim = PhenoSimEngine(self.owlsim2_api) self.resolve_mock.start() self.mock_scigraph.start()
class SimSearch(Resource): sim_engine = PhenoSimEngine(get_owlsim_api()) @api.expect(sim_search_parser) @api.marshal_with(sim_result) def get(self): """ Search for phenotypically similar diseases or model genes """ input_args = sim_search_parser.parse_args() return SimCompare.sim_engine.search( id_list=input_args['id'], limit=input_args['limit'], taxon_filter=input_args['taxon'], method=SimAlgorithm(input_args['metric']), is_feature_set=input_args['is_feature_set'] )
class SimCompare(Resource): sim_engine = PhenoSimEngine(get_owlsim_api()) @api.expect(compare_input) @api.marshal_with(sim_result) def post(self): """ Compare a reference profile vs one or more profiles """ data = request.json if 'metric' not in data: data['metric'] = 'phenodigm' if 'is_feature_set' not in data: data['is_feature_set'] = True return SimCompare.sim_engine.compare( reference_ids=data['reference_ids'], query_profiles=data['query_ids'], method=SimAlgorithm(data['metric']), is_feature_set=data['is_feature_set'] ) @api.expect(sim_compare_parser) @api.marshal_with(sim_result) def get(self): """ Compare a reference profile vs one profiles """ input_args = sim_compare_parser.parse_args() return SimCompare.sim_engine.compare( reference_ids=input_args['ref_id'], query_profiles=[input_args['query_id']], method=SimAlgorithm(input_args['metric']), is_feature_set = input_args['is_feature_set'] )
from pathlib import Path import json import pytest from dacite import from_dict, Config from ontobio.sim.mme import clean_feature_ids, query_owlsim from ontobio.model.mme.request import MmeRequest, Observed from ontobio.sim.api.owlsim2 import OwlSim2Api from ontobio.sim.phenosim_engine import PhenoSimEngine patient_1 = Path(__file__).parent / 'resources' / 'mme' / 'patient1.json' owlsim_api = PhenoSimEngine(OwlSim2Api()) @pytest.mark.parametrize("id, clean_id", [("MIM:1234", "OMIM:1234"), ("SHH", "HGNC:10848"), ("some-term-we-dont-have", "some-term-we-dont-have")] ) def test_clean_feature_ids(id, clean_id): test_id = clean_feature_ids(id) assert clean_id == test_id def test_mme_query(): with open(patient_1, 'r') as patient_1_json: patient1 = json.load(patient_1_json) mme_request = from_dict(MmeRequest, patient1, config=Config(cast=[Observed])) response = query_owlsim(mme_request, owlsim_api, taxon='9606')
from flask_restplus import Resource from flask import request from ontobio.sim.api.owlsim2 import OwlSim2Api from ontobio.sim.phenosim_engine import PhenoSimEngine from biolink.api.restplus import api from biolink.datamodel.sim_serializers import sim_result, compare_input sim_engine = PhenoSimEngine(OwlSim2Api()) def get_compare_parser(): help_msg = 'A phenotype or identifier that is composed of phenotypes (eg disease, gene)' sim_get_parser = api.parser() sim_get_parser.add_argument('ref_id', action='append', help=help_msg, default=[]) sim_get_parser.add_argument('query_id', action='append', help=help_msg, default=[]) return sim_get_parser def get_search_parser(): sim_search_parser = api.parser() sim_search_parser.add_argument( 'id',
class TestPhenoSimEngine(): """ Functional test of ontobio.sim.phenosim_engine.PhenoSimEngine using mock return values from owlsim2, scigraph, and solr assocs """ @classmethod def setup_class(self): patch('ontobio.sim.api.owlsim2.get_owlsim_stats', return_value=(None, None)).start() self.resolve_mock = patch.object(PhenoSimEngine, '_resolve_nodes_to_phenotypes', side_effect=mock_resolve_nodes) self.mock_scigraph = patch( 'ontobio.util.scigraph_util.get_scigraph_nodes', side_effect=mock_get_scigraph_nodes) self.owlsim2_api = OwlSim2Api() self.owlsim2_api.statistics = IcStatistic(mean_mean_ic=6.82480, mean_sum_ic=120.89767, mean_cls=15.47425, max_max_ic=16.16108, max_sum_ic=6746.96160, individual_count=65309, mean_max_ic=9.51535) self.pheno_sim = PhenoSimEngine(self.owlsim2_api) self.resolve_mock.start() self.mock_scigraph.start() @classmethod def teardown_class(self): self.owlsim2_api = None self.pheno_sim = None self.resolve_mock.stop() self.mock_scigraph.stop() def test_sim_search(self): # Load fake output from owlsim2 and mock search_by_attribute_set mock_search_fh = os.path.join( os.path.dirname(__file__), 'resources/owlsim2/mock-owlsim-search.json') mock_search = json.load(open(mock_search_fh)) patch('ontobio.sim.api.owlsim2.search_by_attribute_set', return_value=mock_search).start() expected_fh = os.path.join(os.path.dirname(__file__), 'resources/owlsim2/mock-sim-search.json') expected_sim_results = json.load(open(expected_fh)) classes = ['HP:0002367', 'HP:0031466', 'HP:0007123'] search_results = self.pheno_sim.search(classes) results = json.loads( json.dumps(search_results, default=lambda obj: getattr(obj, '__dict__', str(obj)))) assert expected_sim_results == results def test_sim_compare(self): # Load fake output from owlsim2 and mock compare mock_search_fh = os.path.join( os.path.dirname(__file__), 'resources/owlsim2/mock-owlsim-compare.json') mock_compare = json.load(open(mock_search_fh)) patch('ontobio.sim.api.owlsim2.compare_attribute_sets', return_value=mock_compare).start() expected_fh = os.path.join(os.path.dirname(__file__), 'resources/owlsim2/mock-sim-compare.json') expected_sim_results = json.load(open(expected_fh)) individuals_a = ['MONDO:0008199'] individuals_b = [['HP:0002367', 'HP:0031466', 'HP:0007123']] compare_results = self.pheno_sim.compare(individuals_a, individuals_b) results = json.loads( json.dumps(compare_results, default=lambda obj: getattr(obj, '__dict__', str(obj)))) assert expected_sim_results == results def test_no_results(self): """ Make sure ontobio handles no results correctly """ # Load fake output from owlsim2 where no results are returned mock_search_fh = os.path.join( os.path.dirname(__file__), 'resources/owlsim2/mock-owlsim-noresults.json') mock_search = json.load(open(mock_search_fh)) patch('ontobio.sim.api.owlsim2.search_by_attribute_set', return_value=mock_search).start() classes = ['HP:0002367', 'HP:0031466', 'HP:0007123'] search_results = self.pheno_sim.search(classes, method=SimAlgorithm.SIM_GIC) assert search_results.matches == []
class TestOwlSimIntegration(): """ Hodgepodge of integration tests for ontobio and owlsim2 to assist in development """ @classmethod def setup_class(self): self.owlsim2_api = OwlSim2Api() self.annot_scorer = AnnotationScorer(self.owlsim2_api) self.pheno_sim = PhenoSimEngine(self.owlsim2_api) @classmethod def teardown_class(self): self.annot_scorer = None self.pheno_sim = None self.owlsim2_api = None def test_stat_type(self): """ Test stat type """ assert isinstance(self.owlsim2_api.statistics, IcStatistic) def test_fetch_stats(self): """ Test that we're getting stats back and they're the correct type """ assert isinstance(self.owlsim2_api.statistics.mean_mean_ic, float) assert isinstance(self.owlsim2_api.statistics.individual_count, int) def test_fetch_ic(self): """ Fetch two classes that are parent-child and test that the child has a higher IC than the parent :return: """ classes = ['HP:0000739', 'HP:0000740'] ic_dict = self.owlsim2_api.get_profile_ic(classes) assert isinstance(ic_dict['HP:0000740'], float) assert ic_dict['HP:0000740'] > ic_dict['HP:0000739'] def test_get_annotation_suff(self): classes = ['HP:0000739', 'HP:0000740'] negated_classes = [] annot_suff = self.annot_scorer.get_annotation_sufficiency( classes, negated_classes) assert 0 < annot_suff.simple_score < 1 assert 0 < annot_suff.scaled_score < 1 assert 0 < annot_suff.categorical_score < 1 def test_sim_search(self): classes = ['HP:0000739', 'HP:0000740'] search_results = self.pheno_sim.search(classes) assert search_results.matches[0].rank == 1 assert 0 < search_results.matches[0].score < 100 assert search_results.matches[0].type in [ 'gene', 'phenotype', 'disease' ] assert search_results.matches[0].taxon.id is not None assert len(search_results.matches[0].pairwise_match) > 0 assert search_results.matches[0].pairwise_match[0].lcs.IC > 0 def test_sim_compare(self): """ Comparison where a disease is the reference """ classes_a = ['MONDO:0008199'] classes_b = [['HP:0002367', 'HP:0031466', 'HP:0007123']] compare_results = self.pheno_sim.compare(classes_a, classes_b) assert compare_results.query.reference.id == "MONDO:0008199" assert compare_results.query.reference.type == "disease" assert compare_results.query.reference.taxon.id == "NCBITaxon:9606" assert compare_results.matches[0].pairwise_match[ 0].match.id in classes_b[0] assert compare_results.matches[0].score > 0 def test_sim_compare_ind(self): """ Comparison where a disease is the query """ classes_a = ['HP:0002367', 'HP:0031466', 'HP:0007123'] classes_b = [['MONDO:0008199']] compare_results = self.pheno_sim.compare(classes_a, classes_b) assert compare_results.matches[0].id == "MONDO:0008199" assert compare_results.matches[0].type == "disease" assert compare_results.matches[0].taxon.id == "NCBITaxon:9606" assert compare_results.matches[0].score > 0 def test_sim_compare_multiple(self): """ Comparison against multiple profiles """ classes_a = ['HP:0002367', 'HP:0031466', 'HP:0007123'] classes_b = [['HP:0000716', 'HP:0011307'], ['HP:0001004']] compare_results = self.pheno_sim.compare(classes_a, classes_b) assert compare_results.query.target_ids[1][0].id == 'HP:0001004'
def setup_class(self): self.owlsim2_api = OwlSim2Api() self.annot_scorer = AnnotationScorer(self.owlsim2_api) self.pheno_sim = PhenoSimEngine(self.owlsim2_api)
from dataclasses import asdict from flask_restplus import Resource from flask import request, make_response from marshmallow import ValidationError from biolink.api.restplus import api from biolink.api.sim.endpoints.owlsim import get_owlsim_api from biolink.datamodel.mme_serializers import mme_request_marshmallow from biolink.datamodel.serializers import mme from ontobio.sim.mme import query_owlsim from ontobio.sim.phenosim_engine import PhenoSimEngine sim_engine = PhenoSimEngine(get_owlsim_api()) def get_mme_response(data, taxon: str = None): try: mme_request = mme_request_marshmallow.load(data) except ValidationError as err: return { 'error': { 'message': f'missing/invalid data {err}', 'code': 400 } }, 400 match_data = query_owlsim(mme_request, sim_engine, taxon=taxon)