Skip to content

Commit 649d52c

Browse files
authored
Merge pull request #319 from Knowledge-Graph-Hub/use-metpo-oxygen-tolerance-terms
Use BacDive/METPO mapping file in `kg_microbe/transform_utils/bacdive/bacdive.py`
2 parents 48fdb8c + 1190bbe commit 649d52c

2 files changed

Lines changed: 62 additions & 5 deletions

File tree

kg_microbe/transform_utils/bacdive/bacdive.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
)
181181
from kg_microbe.transform_utils.transform import Transform
182182
from kg_microbe.utils.dummy_tqdm import DummyTqdm
183+
from kg_microbe.utils.mapping_file_utils import load_oxygen_phenotype_mappings
183184
from kg_microbe.utils.oak_utils import get_label
184185
from kg_microbe.utils.pandas_utils import drop_duplicates
185186
from kg_microbe.utils.string_coding import remove_nextlines
@@ -205,6 +206,7 @@ def __init__(
205206
source_name = BACDIVE
206207
super().__init__(source_name, input_dir, output_dir)
207208
self.ncbi_impl = get_adapter(f"sqlite:{NCBITAXON_SOURCE}")
209+
self.oxygen_phenotype_mappings = load_oxygen_phenotype_mappings()
208210

209211
def _flatten_to_dicts(self, obj):
210212
if isinstance(obj, dict):
@@ -1358,15 +1360,25 @@ def run(self, data_file: Union[Optional[Path], Optional[str]] = None, show_statu
13581360
# e.g. ot_rec might look like {"@ref": 4562, "oxygen tolerance": "microaerophile"}
13591361
ot_label = ot_rec.get("oxygen tolerance", "").strip()
13601362
if ot_label:
1361-
# Create a node for this oxygen tolerance
1362-
# Category is typically "biolink:PhenotypicQuality"
1363-
# ID can be something like "oxygen:microaerophile"
1363+
# Check if we have a METPO mapping for this oxygen tolerance term
1364+
mapping = None
1365+
for map_key, map_value in self.oxygen_phenotype_mappings.items():
1366+
if map_key == ot_label:
1367+
mapping = map_value
1368+
break
1369+
if mapping:
1370+
# Use METPO term
1371+
ot_id = mapping['curie']
1372+
ot_display_label = mapping['label']
1373+
# print(f"DEBUG: Mapped '{ot_label}' -> {ot_id} ({ot_display_label})")
1374+
else:
1375+
# Raise exception if no mapping found
1376+
raise ValueError(f"No METPO mapping found for oxygen tolerance term: '{ot_label}'")
13641377

1365-
ot_id = f"oxygen:{ot_label.replace(' ', '_').lower()}"
13661378
node_writer.writerow([
13671379
ot_id,
13681380
PHENOTYPIC_CATEGORY,
1369-
ot_label
1381+
ot_display_label
13701382
] + [None]*(len(self.node_header) - 3))
13711383

13721384
# Now create an edge from each organism in species_with_strains
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""Utilities for handling mapping files from remote sources."""
2+
import csv
3+
from typing import Dict
4+
5+
import requests
6+
7+
# remote URL location in metpo GitHub repository for oxygen phenotype mappings file
8+
BACDIVE_OXYGEN_PHENOTYPE_MAPPINGS_URL = "https://raw.githubusercontent.com/berkeleybop/metpo/refs/heads/main/generated/bacdive_oxygen_phenotype_mappings.tsv"
9+
10+
11+
def load_oxygen_phenotype_mappings() -> Dict[str, Dict[str, str]]:
12+
"""
13+
Load METPO oxygen phenotype mappings file from remote location in metpo repository.
14+
15+
:return: Dictionary mapping BacDive labels to METPO curie and label information.
16+
Format: {bacdive_label: {'curie': metpo_curie, 'label': metpo_label}}
17+
:rtype: Dict[str, Dict[str, str]]
18+
:raises requests.exceptions.HTTPError: If unable to fetch from remote URL
19+
:raises ValueError: If the response content is empty or invalid
20+
"""
21+
mappings = {}
22+
23+
try:
24+
response = requests.get(BACDIVE_OXYGEN_PHENOTYPE_MAPPINGS_URL, timeout=30)
25+
response.raise_for_status()
26+
27+
if not response.text.strip():
28+
raise ValueError("The contents of the file at the remote URL are empty or invalid.")
29+
30+
reader = csv.DictReader(response.text.splitlines(), delimiter='\t')
31+
for row in reader:
32+
bacdive_label = row.get('?bacdive_label', '').strip().strip('"')
33+
metpo_curie = row.get('?metpo_curie', '').strip().strip('"')
34+
metpo_label = row.get('?metpo_label', '').strip().strip('"')
35+
36+
if bacdive_label and metpo_curie:
37+
mappings[bacdive_label] = {
38+
'curie': metpo_curie,
39+
'label': metpo_label
40+
}
41+
42+
return mappings
43+
44+
except requests.exceptions.HTTPError as e:
45+
raise requests.exceptions.HTTPError(f"Please ensure the remote URL is accessible: {e}") from e

0 commit comments

Comments
 (0)