Repository: biolink/biolink-model-toolkit

Issue:
add functionality to return biolink class for any curie 
slightly different than ```element_name = t.get_element_by_mapping('RO:0002410')```
instead of mapping via exact, narrow, close, etc. mappings, this feature would take a curie and return the most likely classes that would be instantiated for a curie of this kind.
@kevinschaper @kshefchek 

Discussion:

Patch:
diff --git a/bmt/toolkit.py b/bmt/toolkit.py
index 8d1e4c3..ce16174 100644
--- a/bmt/toolkit.py
+++ b/bmt/toolkit.py
@@ -12,6 +12,7 @@ from linkml_runtime.linkml_model.meta import (
 
 from bmt.toolkit_generator import ToolkitGenerator
 from bmt.utils import format_element, parse_name
+import logging
 
 Url = str
 Path = str
@@ -22,6 +23,8 @@ REMOTE_PATH = (
 RELATED_TO = "related to"
 CACHE_SIZE = 1024
 
+logger = logging.getLogger(__name__)
+
 
 class Toolkit(object):
     """
@@ -975,6 +978,42 @@ class Toolkit(object):
         """
         return "named thing" in self.get_ancestors(name, mixin)
 
+    @lru_cache(CACHE_SIZE)
+    def get_element_by_prefix(
+            self,
+            identifier: str
+    ) -> List[str]:
+        """
+        Get a Biolink Model element by prefix.
+        This method return the common ancestor of the set of elements referenced by uriorcurie.
+
+        Parameters
+        ----------
+        identifier: str
+            The identifier as a CURIE
+
+        Returns
+        -------
+        Optional[str]
+                The Biolink element corresponding to the given URI/CURIE as available via
+                the id_prefixes mapped to that element.
+
+        """
+        categories = []
+        if ":" in identifier:
+            id_components = identifier.split(":")
+            prefix = id_components[0]
+            elements = self.get_all_elements()
+            for category in elements:
+                element = self.get_element(category)
+                if hasattr(element, 'id_prefixes') and prefix in element.id_prefixes:
+                    categories.append(element.name)
+        print(categories)
+        if len(categories) == 0:
+            logger.warning("no biolink class found for the given curie: %s, try get_element_by_mapping?", identifier)
+
+        return categories
+
     @lru_cache(CACHE_SIZE)
     def get_element_by_mapping(
         self,
diff --git a/bmt/toolkit_generator.py b/bmt/toolkit_generator.py
index 6416557..53f8058 100644
--- a/bmt/toolkit_generator.py
+++ b/bmt/toolkit_generator.py
@@ -37,6 +37,7 @@ class ToolkitGenerator(Generator):
         self.narrow_mappings: Dict[str, Set[str]] = defaultdict(set)
         self.broad_mappings: Dict[str, Set[str]] = defaultdict(set)
         self.aliases: Dict[str, str] = dict()
+        self.id_prefixes: Dict[str, Set[str]] = defaultdict(set)
 
     def visit_element(self, element: Element, element_uri: Optional[str]) -> None:
         """
@@ -64,6 +65,8 @@ class ToolkitGenerator(Generator):
             self.narrow_mappings[self.namespaces.uri_for(curie)].add(element.name)
         for curie in element.broad_mappings:
             self.broad_mappings[self.namespaces.uri_for(curie)].add(element.name)
+        for id_prefix in element.id_prefixes:
+            self.id_prefixes[element.name].add(id_prefix)
         if element_uri:
             self.mappings[self.namespaces.uri_for(element_uri)].add(element.name)
         self.aliases.update({a: element.name for a in element.aliases})


Test patch:
diff --git a/tests/unit/test_toolkit.py b/tests/unit/test_toolkit.py
index a93d889..99af76a 100644
--- a/tests/unit/test_toolkit.py
+++ b/tests/unit/test_toolkit.py
@@ -36,10 +36,21 @@ def test_get_model_version(toolkit):
 
 
 def test_get_element_by_mapping(toolkit):
-    element_name = toolkit.get_element_by_mapping("RO:0002410")
+    element_name = toolkit.get_element_by_mapping("RO:0003303")
     assert element_name == "causes"
 
 
+def test_get_element_by_prefix(toolkit):
+    elements = toolkit.get_element_by_prefix("UBERON:1234")
+    assert "anatomical entity" in elements
+
+    elements = toolkit.get_element_by_prefix("GO:1234")
+    assert "molecular activity" in elements
+
+    elements = toolkit.get_element_by_prefix("TEST:1234")
+    assert "anatomical entity" not in elements
+
+
 def test_get_all_elements(toolkit):
     elements = toolkit.get_all_elements()
     assert NAMED_THING in elements