###### Phenotype

lamindb provides access to the following public Phenotype ontologies
through bionty:

1. Human Phenotype

2. Phecodes

3. PATO

4. Mammalian Phenotype

Here we show how to access and search Phenotype ontologies to
standardize new data.

 import bionty as bt
 import pandas as pd

##### PublicOntology objects

Let us create a public ontology accessor with ".public" method, which
chooses a default public ontology source from "Source". It's a
PublicOntology object, which you can think about as a public registry:

 phenotypes = bt.Phenotype.public(organism="human")
 phenotypes

As for registries, you can export the ontology as a "DataFrame":

 df = phenotypes.to_dataframe()
 df.head()

Unlike registries, you can also export it as a Pronto object via
"public.ontology".

##### Look up terms

As for registries, terms can be looked up with auto-complete:

 lookup = phenotypes.lookup()

The "." accessor provides normalized terms (lower case, only contains
alphanumeric characters and underscores):

 lookup.eeg_with_persistent_abnormal_rhythmic_activity

To look up the exact original strings, convert the lookup object to
dict and use the "[]" accessor:

 lookup_dict = lookup.dict()
 lookup_dict["EEG with persistent abnormal rhythmic activity"]

By default, the "name" field is used to generate lookup keys. You can
specify another field to look up:

 lookup = phenotypes.lookup(phenotypes.ontology_id)

 lookup.hp_0000003

##### Search terms

Search behaves in the same way as it does for registries:

 phenotypes.search("dysplasia").head(3)

By default, search also covers synonyms and all other fields
containing strings:

 phenotypes.search("Congenital hip dysplasia").head(3)

Search specific field (by default, search is done on all fields
containing strings):

 phenotypes.search(
 "lack of development of speech and language",
 field=phenotypes.definition,
 ).head()

##### Standardize Phenotype identifiers

Let us generate a "DataFrame" that stores a number of Phenotype
identifiers, some of which corrupted:

 df_orig = pd.DataFrame(
 index=[
 "Specific learning disability",
 "Dystonia",
 "Cerebral hemorrhage",
 "Slurred speech",
 "This phenotype does not exist",
 ]
 )
 df_orig

We can check whether any of our values are validated against the
ontology reference:

 validated = phenotypes.validate(df_orig.index, phenotypes.name)
 df_orig.index[~validated]

##### Ontology source versions

For any given entity, we can choose from a number of versions:

 bt.Source.filter(entity="bionty.Phenotype").to_dataframe()

 # only lists the sources that are currently used
 bt.Source.filter(entity="bionty.Phenotype", currently_used=True).to_dataframe()

When instantiating a Bionty object, we can choose a source or version:

 source = bt.Source.filter(
 name="hp", organism="human"
 ).first()
 phenotypes= bt.Phenotype.public(source=source)
 phenotypes

The currently used ontologies can be displayed using:

 bt.Source.filter(currently_used=True).to_dataframe()