Skip to content

Commit

Permalink
Merge pull request #29 from TheJacksonLaboratory/add_ancestor_descend…
Browse files Browse the repository at this point in the history
…ant_tests_on_graph

Add methods for testing ancestor/descendant relationships to `OntologyGraph`
  • Loading branch information
ielis authored May 26, 2023
2 parents 01ba82c + 7a961f8 commit 9bd5080
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 33 deletions.
108 changes: 75 additions & 33 deletions notebooks/Tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,50 @@
" print(f\"{term.identifier.value} - {term.name}\")"
]
},
{
"cell_type": "markdown",
"id": "c219878d-ae6e-4279-b7b7-993b4e2110dc",
"metadata": {},
"source": [
"## Term relationship tests\n",
"\n",
"We can check if a term is a *parent* or an *ancestor* of another term using the ontology graph:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "9f02ea88-694b-4d4a-a2cd-8e604d40cf18",
"metadata": {},
"outputs": [],
"source": [
"arachnodactyly = TermId.from_curie('HP:0001166')\n",
"abnormality_of_the_hand = TermId.from_curie('HP:0001155')\n",
"long_fingers = TermId.from_curie('HP:0100807')\n",
"\n",
"assert o.graph.is_parent_of(long_fingers, arachnodactyly)\n",
"assert o.graph.is_ancestor_of(abnormality_of_the_hand, arachnodactyly)"
]
},
{
"cell_type": "markdown",
"id": "5efc4a21-b115-4511-80fd-cf02d3afdc46",
"metadata": {},
"source": [
"Similarly, we can check if a term is a *child* or a *descendant* of another term:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "df6344dd-9b72-4d94-88aa-201a9578fc7b",
"metadata": {},
"outputs": [],
"source": [
"assert o.graph.is_child_of(arachnodactyly, long_fingers)\n",
"assert o.graph.is_descendant_of(arachnodactyly, long_fingers)"
]
},
{
"cell_type": "markdown",
"id": "a94bcf99-fb72-4b83-bc3d-805fd7a30cb6",
Expand All @@ -439,7 +483,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 14,
"id": "3b2f58cc-e008-4153-96b5-1abbd4db9e47",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -487,7 +531,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 15,
"id": "0e668a54-c146-47be-921e-72ab29ee7d28",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -531,7 +575,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 16,
"id": "b575229e-1c08-4d02-aaa3-012c9a8c80bd",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -571,7 +615,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 17,
"id": "654026c8-0e98-45ee-b245-0fa72f8498c3",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -616,7 +660,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 18,
"id": "215903d1-5c3f-4b0f-8fa0-486ef272f5a8",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -645,7 +689,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 19,
"id": "0b1e1b30-e70e-4ec9-89c9-5c702d24ea25",
"metadata": {},
"outputs": [
Expand All @@ -672,7 +716,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 20,
"id": "5c4bf517-3e4c-4444-9ada-8bdd9cdcbbbe",
"metadata": {
"tags": []
Expand All @@ -684,7 +728,7 @@
"HpoFrequency(identifier=HP:0040283, lower_bound=0.05, upper_bound=0.29)"
]
},
"execution_count": 18,
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -705,7 +749,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 21,
"id": "03e7bc93-a58e-422e-a9e1-b04f40956dfb",
"metadata": {
"tags": []
Expand All @@ -728,7 +772,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 22,
"id": "7daaab3e-6ead-4230-88d5-b8c080b3730b",
"metadata": {
"tags": []
Expand Down Expand Up @@ -759,7 +803,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 23,
"id": "d7bf2281-d8ed-4373-b094-ef7df0c60aa8",
"metadata": {
"tags": []
Expand Down Expand Up @@ -790,7 +834,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 24,
"id": "2ddccd09-43d8-448d-8df1-f55ae8eeb658",
"metadata": {
"tags": []
Expand Down Expand Up @@ -821,7 +865,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 25,
"id": "0c183a9c-802b-43a1-8bf9-b0e81e5a26f1",
"metadata": {
"tags": []
Expand Down Expand Up @@ -867,7 +911,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": 26,
"id": "9b5e5216-abde-4b8e-888b-fd12b43ce92e",
"metadata": {
"tags": []
Expand All @@ -879,7 +923,7 @@
"'Parsed 12429 diseases'"
]
},
"execution_count": 24,
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -905,7 +949,7 @@
},
{
"cell_type": "code",
"execution_count": 25,
"execution_count": 27,
"id": "b4303dc6-a653-4720-8a50-0600d655b679",
"metadata": {
"tags": []
Expand Down Expand Up @@ -933,7 +977,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 28,
"id": "45035d68-baad-4e69-ab51-5e9c9e0aad86",
"metadata": {
"tags": []
Expand Down Expand Up @@ -962,7 +1006,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 29,
"id": "e061b854-2218-4355-8a9f-d6ef9988f588",
"metadata": {
"tags": []
Expand Down Expand Up @@ -995,7 +1039,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 30,
"id": "2faad640-4765-49c5-9eba-535018782e5b",
"metadata": {
"tags": []
Expand Down Expand Up @@ -1046,7 +1090,7 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": 31,
"id": "fe09955e-9a7d-49dc-9cd7-e7db4b876af5",
"metadata": {
"tags": []
Expand All @@ -1068,7 +1112,7 @@
},
{
"cell_type": "code",
"execution_count": 30,
"execution_count": 32,
"id": "7ad52558-e398-413f-8d65-0e67d6099d42",
"metadata": {
"tags": []
Expand All @@ -1083,8 +1127,8 @@
}
],
"source": [
"ic_arachnodactyly = term_id2ic[arachnodactyly.identifier]\n",
"print(f'IC of {arachnodactyly.name}: {ic_arachnodactyly} nats')"
"ic_arachnodactyly = term_id2ic[arachnodactyly]\n",
"print(f'IC of Arachnodactyly: {ic_arachnodactyly} nats')"
]
},
{
Expand Down Expand Up @@ -1137,7 +1181,7 @@
},
{
"cell_type": "code",
"execution_count": 31,
"execution_count": 33,
"id": "deb939b7-847f-4b9f-a823-61ea8e9cbb1a",
"metadata": {
"tags": []
Expand All @@ -1149,7 +1193,7 @@
"{'annotated_items_version': '2023-04-05', 'ontology_version': '2023-04-06'}"
]
},
"execution_count": 31,
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1172,16 +1216,14 @@
},
{
"cell_type": "code",
"execution_count": 32,
"id": "4e4afd86-1c26-454e-a627-07b29eb00f01",
"metadata": {
"tags": []
},
"execution_count": 34,
"id": "6f4dec17-d7df-442a-b803-2aabe86ca1b4",
"metadata": {},
"outputs": [],
"source": [
"from hpotk.algorithm.similarity import precalculate_ic_mica_for_hpo_concept_pairs, SimilarityContainer\n",
"\n",
"#sc: SimilarityContainer = precalculate_ic_mica_for_hpo_concept_pairs(term_id2ic, o)"
"# sc: SimilarityContainer = precalculate_ic_mica_for_hpo_concept_pairs(term_id2ic, o)"
]
},
{
Expand All @@ -1196,7 +1238,7 @@
},
{
"cell_type": "code",
"execution_count": 33,
"execution_count": 35,
"id": "bea2ed63-59bc-4081-a9e8-d81ec6d06d80",
"metadata": {
"tags": []
Expand All @@ -1216,7 +1258,7 @@
},
{
"cell_type": "code",
"execution_count": 34,
"execution_count": 36,
"id": "0ade7bf4-7d4c-4f5d-b612-dd3f8d9e2c57",
"metadata": {
"tags": []
Expand Down
46 changes: 46 additions & 0 deletions src/hpotk/graph/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,52 @@ def is_leaf(self, node: NODE) -> bool:
return False
return True

def is_parent_of(self, sub: NODE, obj: NODE) -> bool:
"""
Return `True` if the subject `sub` is a parent of the object `obj`.
:param sub: a graph node.
:param obj: other graph node.
:return: `True` if the `sub` is a parent of the `obj`.
"""
return self._run_query(self.get_parents, sub, obj)

def is_ancestor_of(self, sub: NODE, obj: NODE) -> bool:
"""
Return `True` if the subject `sub` is an ancestor of the object `obj`.
:param sub: a graph node.
:param obj: other graph node.
:return: `True` if the `sub` is an ancestor of the `obj`.
"""
return self._run_query(self.get_ancestors, sub, obj)

def is_child_of(self, sub: NODE, obj: NODE) -> bool:
"""
Return `True` if the `sub` is a child of the `obj`.
:param sub: a graph node.
:param obj: other graph node.
:return: `True` if the `sub` is a child of the `obj`.
"""
return self._run_query(self.get_children, sub, obj)

def is_descendant_of(self, sub: NODE, obj: NODE) -> bool:
"""
Return `True` if the `sub` is a descendant of the `obj`.
:param sub: a graph node.
:param obj: other graph node.
:return: `True` if the `sub` is a descendant of the `obj`.
"""
return self._run_query(self.get_descendants, sub, obj)

@staticmethod
def _run_query(func: typing.Callable[[NODE], typing.Iterable[NODE]],
sub: NODE,
obj: NODE) -> bool:
return any(sub == term_id for term_id in func(obj))

@abc.abstractmethod
def __contains__(self, item: NODE) -> bool:
pass
Expand Down
Loading

0 comments on commit 9bd5080

Please sign in to comment.