Skip to content

Commit

Permalink
Merge branch 'main' into default-synonym-type-none
Browse files Browse the repository at this point in the history
  • Loading branch information
cthoyt committed Jan 5, 2025
2 parents cc635a9 + 91a86b8 commit 5082f6b
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 33 deletions.
4 changes: 1 addition & 3 deletions src/pyobo/obographs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import bioregistry
import curies
from bioontologies.obograph import (
OBO_SYNONYM_TO_OIO,
OIO_TO_REFERENCE,
Definition,
Edge,
Graph,
Expand Down Expand Up @@ -94,7 +92,7 @@ def _get_class_node(term: Term) -> Node:
synonyms = [
Synonym.from_parsed(
name=synonym.name,
predicate=OIO_TO_REFERENCE[OBO_SYNONYM_TO_OIO[synonym.specificity]],
predicate=synonym.predicate,
synonym_type=_rewire(synonym.type) if synonym.type else None,
references=[_rewire(x) for x in synonym.provenance],
)
Expand Down
2 changes: 1 addition & 1 deletion src/pyobo/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ def _extract_synonym(

return Synonym(
name=name,
specificity=specificity or "EXACT",
specificity=specificity,
type=synonym_typedef.reference if synonym_typedef else None,
provenance=provenance,
annotations=annotations,
Expand Down
7 changes: 4 additions & 3 deletions src/pyobo/reader_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
from __future__ import annotations

import logging
import typing as t
from collections import Counter
from collections.abc import Mapping

from curies import ReferenceTuple
from curies import vocabulary as v

from pyobo.struct import SynonymSpecificities, SynonymSpecificity
from pyobo.struct.reference import _parse_identifier
from pyobo.struct.struct import Reference, SynonymTypeDef, _synonym_typedef_warn

Expand All @@ -17,9 +18,9 @@
TARGET_URI_WARNINGS: Counter[tuple[str, str]] = Counter()


def _chomp_specificity(s: str) -> tuple[SynonymSpecificity | None, str]:
def _chomp_specificity(s: str) -> tuple[v.SynonymScope | None, str]:
s = s.strip()
for _specificity in SynonymSpecificities:
for _specificity in t.get_args(v.SynonymScope):
if s.startswith(_specificity):
return _specificity, s[len(_specificity) :].strip()
return None, s
Expand Down
6 changes: 1 addition & 5 deletions src/pyobo/sources/conso.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,13 @@ def iter_terms() -> Iterable[Term]:
synonyms_df["reference"] = synonyms_df["reference"].map(
lambda s: [Reference.from_curie_or_uri(s)] if pd.notna(s) and s != "?" else [],
)
synonyms_df["specificity"] = synonyms_df["specificity"].map(
lambda s: "EXACT" if pd.isna(s) or s == "?" else s
)

synonyms = multidict(
(
identifier,
Synonym(
name=synonym,
provenance=provenance,
specificity=specificity,
specificity=None if pd.isna(specificity) or specificity == "?" else specificity,
),
)
for identifier, synonym, provenance, specificity in synonyms_df.values
Expand Down
4 changes: 0 additions & 4 deletions src/pyobo/struct/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
from .struct import (
Obo,
Synonym,
SynonymSpecificities,
SynonymSpecificity,
SynonymTypeDef,
Term,
int_identifier_sort_key,
Expand Down Expand Up @@ -38,8 +36,6 @@
"Reference",
"Referenced",
"Synonym",
"SynonymSpecificities",
"SynonymSpecificity",
"SynonymTypeDef",
"Term",
"TypeDef",
Expand Down
26 changes: 15 additions & 11 deletions src/pyobo/struct/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@

import bioregistry
import click
import curies
import networkx as nx
import pandas as pd
from curies import ReferenceTuple
from curies import vocabulary as v
from more_click import force_option, verbose_option
from pydantic import BaseModel
from tqdm.auto import tqdm
Expand Down Expand Up @@ -75,8 +77,6 @@
"Obo",
"ReferenceHint",
"Synonym",
"SynonymSpecificities",
"SynonymSpecificity",
"SynonymTypeDef",
"Term",
"abbreviation",
Expand All @@ -87,8 +87,7 @@

logger = logging.getLogger(__name__)

SynonymSpecificity = Literal["EXACT", "NARROW", "BROAD", "RELATED"]
SynonymSpecificities: Sequence[SynonymSpecificity] = ("EXACT", "NARROW", "BROAD", "RELATED")
DEFAULT_SPECIFICITY: v.SynonymScope = "EXACT"

#: Columns in the SSSOM dataframe
SSSOM_DF_COLUMNS = [
Expand All @@ -111,7 +110,7 @@ class Synonym:
name: str

#: The specificity of the synonym
specificity: SynonymSpecificity = "EXACT"
specificity: v.SynonymScope | None = None

#: The type of synonym. Must be defined in OBO document!
type: Reference | None = None
Expand All @@ -126,8 +125,13 @@ def __lt__(self, other: Synonym) -> bool:
"""Sort lexically by name."""
return self._sort_key() < other._sort_key()

def _sort_key(self) -> tuple[str, str, str]:
return self.name, self.specificity, self.type.curie if self.type else ""
def _sort_key(self) -> tuple[str, v.SynonymScope, Reference]:
return self.name, self.specificity or DEFAULT_SPECIFICITY, self.type.curie if self.type else ""

@property
def predicate(self) -> curies.NamedReference:
"""Get the specificity reference."""
return v.synonym_scopes[self.specificity or DEFAULT_SPECIFICITY]

def to_obo(
self,
Expand All @@ -147,7 +151,7 @@ def _fp(
_synonym_typedef_warn(ontology_prefix, self.type, synonym_typedefs)
# TODO inherit specificity from typedef?
# TODO validation of specificity against typedef
x = f'"{self._escape(self.name)}" {self.specificity}'
x = f'"{self._escape(self.name)}" {self.specificity or DEFAULT_SPECIFICITY}'
if self.type is not None:
x = f"{x} {reference_escape(self.type, ontology_prefix=ontology_prefix)}"
return f"{x} [{comma_separate_references(self.provenance)}]"
Expand All @@ -162,7 +166,7 @@ class SynonymTypeDef(Referenced):
"""A type definition for synonyms in OBO."""

reference: Reference
specificity: SynonymSpecificity | None = None
specificity: v.SynonymScope | None = None

def __hash__(self) -> int:
# have to re-define hash because of the @dataclass
Expand Down Expand Up @@ -353,7 +357,7 @@ def append_synonym(
synonym: str | Synonym,
*,
type: Reference | Referenced | None = None,
specificity: SynonymSpecificity | None = None,
specificity: v.SynonymScope | None = None,
provenance: list[Reference] | None = None,
) -> None:
"""Add a synonym."""
Expand All @@ -363,7 +367,7 @@ def append_synonym(
synonym = Synonym(
synonym,
type=type,
specificity=specificity or "EXACT",
specificity=specificity,
provenance=provenance or [],
)
self.synonyms.append(synonym)
Expand Down
8 changes: 4 additions & 4 deletions tests/test_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ def test_extract_synonym(self):
(
Synonym(
name="LTEC I",
specificity="EXACT",
specificity=None,
provenance=[Reference(prefix="orphanet", identifier="93938")],
),
'"LTEC I" [Orphanet:93938]',
),
(
Synonym(name="LTEC I", specificity="EXACT"),
Synonym(name="LTEC I", specificity=None),
'"LTEC I" []',
),
(
Expand All @@ -156,11 +156,11 @@ def test_extract_synonym(self):
'"HAdV-A" BROAD omo:0003012 []',
),
(
Synonym(name="HAdV-A", specificity="EXACT", type=acronym.reference),
Synonym(name="HAdV-A", specificity=None, type=acronym.reference),
'"HAdV-A" OMO:0003012 []',
),
(
Synonym(name="HAdV-A", specificity="EXACT", type=acronym.reference),
Synonym(name="HAdV-A", specificity=None, type=acronym.reference),
'"HAdV-A" omo:0003012 []',
),
]:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ def test_synonym_minimal(self) -> None:
self.assertEqual(1, len(term.synonyms))
synonym = term.synonyms[0]
self.assertEqual("LTEC I", synonym.name)
self.assertEqual("EXACT", synonym.specificity)
self.assertIsNone(synonym.specificity)
self.assertIsNone(synonym.type)
self.assertEqual([], synonym.provenance)

Expand Down Expand Up @@ -658,7 +658,7 @@ def test_synonym_with_type(self) -> None:
self.assertEqual(1, len(term.synonyms))
synonym = term.synonyms[0]
self.assertEqual("LTEC I", synonym.name)
self.assertEqual("EXACT", synonym.specificity)
self.assertIsNone(synonym.specificity)
self.assertEqual(Reference(prefix="omo", identifier="1234567"), synonym.type)
self.assertEqual([], synonym.provenance)

Expand Down

0 comments on commit 5082f6b

Please sign in to comment.