Skip to content

Commit

Permalink
feat: process ontology bridge terms
Browse files Browse the repository at this point in the history
  • Loading branch information
nayib-jose-gloria committed Oct 25, 2024
1 parent 732262e commit 68e60f4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 27 deletions.
10 changes: 10 additions & 0 deletions asset-schemas/all_ontology_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@
"type": "integer"
}
},
"bridge_terms": {
"type": "object",
"description": "Map of bridge terms that connect this ontology term to other ontologies.",
"patternProperties": {
"^[A-Za-z0-9]+$": {
"$ref": "ontology_term_id_schema.json#/definitions/supported_term_id"
}
},
"additionalProperties": false
},
"comments": {
"type": "array",
"items": {
Expand Down
30 changes: 13 additions & 17 deletions asset-schemas/ontology_info_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@
"patternProperties": {
"^[A-Za-z0-9]+$": {
"$ref": "#/definitions/ontologyEntry"
},
"FBbt": {
"$ref": "#/definitions/ontologyEntry"
},
"FBdv": {
"$ref": "#/definitions/ontologyEntry"
},
"ZFA": {
"$ref": "#/definitions/ontologyEntry"
}
},
"additionalProperties": false
Expand Down Expand Up @@ -60,15 +51,20 @@
"type": "string"
},
"description": "List of additional term id prefixes to extracted from the source ontology file."
},
"bridges": {
"type": "object",
"description": "ontology with mapping files from their terms to this ontology entry's terms.",
"patternProperties": {
"^[A-Za-z0-9]+$": {
"type": "string",
"format": "uri",
"description": "URI to file mapping between the ontology entry and this ontology"
}
},
"additionalProperties": false
}
},
"required": [
"version",
"source",
"filename"
],
"additionalProperties": false
}
}
}
}

12 changes: 10 additions & 2 deletions ontology-assets/ontology_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@
"FBbt": {
"version": "v2024-10-17",
"source": "https://github.com/FlyBase/drosophila-anatomy-developmental-ontology/releases/download",
"filename": "fbbt.owl"
"filename": "fbbt.owl",
"bridges": {
"CL": "https://github.com/obophenotype/uberon/raw/refs/heads/master/src/ontology/bridge/cl-bridge-to-fbbt.owl",
"UBERON": "https://github.com/obophenotype/uberon/raw/refs/heads/master/src/ontology/bridge/uberon-bridge-to-fbbt.owl"
}
},
"FBdv": {
"version": "v2024-10-17",
Expand All @@ -62,7 +66,11 @@
"filename": "zfa.owl",
"additional_ontologies": [
"ZFS"
]
],
"bridges": {
"CL": "https://github.com/obophenotype/uberon/raw/refs/heads/master/src/ontology/bridge/cl-bridge-to-zfa.owl",
"UBERON": "https://github.com/obophenotype/uberon/raw/refs/heads/master/src/ontology/bridge/cl-bridge-to-zfa.owl"
}
}
}
},
Expand Down
45 changes: 37 additions & 8 deletions tools/ontology-builder/src/all_ontology_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,29 @@ def _build_url(_ontology: str) -> str:
onto_ref_data = ontology_info[_ontology]
return f"{onto_ref_data['source']}/{onto_ref_data['version']}/{onto_ref_data['filename']}"

threads = []
for ontology, _ in ontology_info.items():
url = _build_url(ontology)
def _check_url(_ontology: str, _url: str) -> None:
try:
urllib.request.urlopen(url)
urllib.request.urlopen(_url)
except HTTPError as e:
raise Exception(f"{ontology} with pinned URL {url} returns status code {e.code}") from e
raise Exception(f"{_ontology} with pinned URL {_url} returns status code {e.code}") from e
except URLError as e:
raise Exception(f"{ontology} with pinned URL {url} fails due to {e.reason}") from e
raise Exception(f"{_ontology} with pinned URL {_url} fails due to {e.reason}") from e

threads = []
for ontology, info in ontology_info.items():
url = _build_url(ontology)
_check_url(ontology, url)

t = Thread(target=download, args=(ontology, url))
t.start()
threads.append(t)
if bridges := info.get("bridges"):
for bridge_ontology, bridge_url in bridges.items():
bridge_ontology = f"{ontology}_to_{bridge_ontology}"
_check_url(bridge_ontology, bridge_url)
t = Thread(target=download, args=(bridge_ontology, bridge_url))
t.start()
threads.append(t)

for t in threads:
t.join()
Expand Down Expand Up @@ -162,12 +172,28 @@ def _get_ancestors(onto_class: owlready2.entity.ThingClass, allowed_ontologies:
}


def _extract_ontology_term_metadata(onto: owlready2.entity.ThingClass, allowed_ontologies: list[str]) -> Dict[str, Any]:
def _extract_bridge_terms(onto_term: owlready2.entity.ThingClass, bridge_ontologies: Dict[str, str]) -> Dict[str, str]:
"""
Extract mapping of ontology term ID to equivalent term IDs in another ontology.
:param: onto_term: Ontology Term ID to find equivalent terms for
:param: bridge_ontologies: Map of ontologies to bridge file URIs to extract equivalent terms from
:return: Dict[str, str] map of bridged ontology term prefix to the equivalent term ID in that ontology for
onto_term, i.e. ZFA:0000001 -> {"UBERON": "UBERON:0000001", "CL": "CL:0000001",...}
"""
# TODO: implement
return {}


def _extract_ontology_term_metadata(
onto: owlready2.entity.ThingClass, allowed_ontologies: list[str], bridge_ontologies: Dict[str, str]
) -> Dict[str, Any]:
"""
Extract relevant metadata from ontology object and save into a dictionary following our JSON Schema
:param: onto: Ontology Object to Process
:param: allowed_ontologies: List of term prefixes to filter out terms that are not direct children from this ontology
:param: bridge_ontologies: Bridge files to map terms to equivalent terms in another ontology
:return: Dict[str, Any] map of ontology term IDs to pertinent metadata from ontology files
"""
term_dict: Dict[str, Any] = dict()
Expand All @@ -191,6 +217,8 @@ def _extract_ontology_term_metadata(onto: owlready2.entity.ThingClass, allowed_o
# no current use-case for NCBITaxon
term_dict[term_id]["ancestors"] = {} if onto.name == "NCBITaxon" else ancestors

term_dict[term_id]["bridge_terms"] = _extract_bridge_terms(onto_term, bridge_ontologies)

term_dict[term_id]["label"] = onto_term.label[0] if onto_term.label else ""

# optional description, if available
Expand Down Expand Up @@ -269,7 +297,8 @@ def _parse_ontologies(
output_file = os.path.join(output_path, get_ontology_file_name(onto.name, version))
logging.info(f"Processing {output_file}")
allowed_ontologies = [onto.name] + ontology_info[onto.name].get("additional_ontologies", [])
onto_dict = _extract_ontology_term_metadata(onto, allowed_ontologies)
bridge_ontologies = ontology_info[onto.name].get("bridges", [])
onto_dict = _extract_ontology_term_metadata(onto, allowed_ontologies, bridge_ontologies)

with gzip.GzipFile(output_file, mode="wb", mtime=0) as fp:
fp.write(json.dumps(onto_dict, indent=2).encode("utf-8"))
Expand Down

0 comments on commit 68e60f4

Please sign in to comment.