from typing import Dict, List, Optional, Type
from pydantic import BaseModel
import pyhpo
class _Similarity(BaseModel):
dispatch: Dict['str', 'SimilarityBase'] = {}
kind = 'omim'
method = 'graphic'
def __call__(
self,
term1: 'pyhpo.HPOTerm',
term2: 'pyhpo.HPOTerm',
kind: Optional[str] = '',
method: Optional[str] = ''
) -> float:
kind = kind or self.kind
method = method or self.method
try:
similarity = self.dispatch[method]
except KeyError as err:
raise RuntimeError(
f'Unknown method {method} to calculate similarity'
) from err
dependencies: List[float] = [
self(term1, term2, kind, dep) for dep in similarity.dependencies
]
return similarity(term1, term2, kind, dependencies)
def register(
self,
name: str,
similarity_class: Type['SimilarityBase']
) -> None:
self.dispatch[name] = similarity_class()
[docs]class SimilarityBase:
"""
Base class to use for custom similarity calculations.
Custom implementation must inherit from
:class:`pyhpo.similarity.base.SimilarityBase` and provide a
``__call__`` method with the same signature as
:func:`pyhpo.similarity.base.SimilarityBase.__call__`
You can also provide a list of ``dependencies`` of other
similarity methods that should be called beforehand. Results
of these calls will be passed as ``dependencies`` parameter to
the ``__call__`` method.
"""
dependencies: List[str] = []
[docs] def __call__(
self,
term1: 'pyhpo.HPOTerm',
term2: 'pyhpo.HPOTerm',
kind: str,
dependencies: List[float]
) -> float:
"""
This method does the actual calculation of the similarity.
This method must be provided in all custom similarity classes
Parameters
----------
term1:
One of the two terms to compare
term2:
The other of the two terms to compare
kind:
This can be an extra parameter, ususally ``omim`` or ``gene``
to specify which annotations to consider for similarity
depdencies:
A list of other calculation-results that should be calculated
beforehand. This is not needed at all, but helpful if your
implementation builds on an already existing similarity
calculation.
"""
raise NotImplementedError(
'A similarity class requires a __call__ function'
)
SimScore = _Similarity()