!pip install git+https://github.com/biothings/biothings_explorer#egg=biothings_explorer

"""
Explanation: Introduction
This notebook demonstrates how BioThings Explorer can be used to execute queries having more than one intermediate nodes:
The query starts from drug "Anisindione", the two intermediate nodes with be *Gene and DiseaseOrPhenotypicFeature", the final output will be "PhenotypicFeature".
Background: BioThings Explorer can answer two classes of queries -- "EXPLAIN" and "PREDICT".  EXPLAIN queries are described in EXPLAIN_demo.ipynb, and PREDICT queries are described in PREDICT_demo.ipynb. Here, we describe PREDICT queries and how to use BioThings Explorer to execute them.  A more detailed overview of the BioThings Explorer systems is provided in these slides.
To experiment with an executable version of this notebook, load it in Google Colaboratory.
Step 0: Load BioThings Explorer modules
Install the biothings_explorer and biothings_schema packages, as described in this README.  This only needs to be done once (but including it here for compability with colab).
End of explanation
"""


from biothings_explorer.hint import Hint
from biothings_explorer.user_query_dispatcher import FindConnection
import nest_asyncio
nest_asyncio.apply()

"""
Explanation: Next, import the relevant modules:

Hint: Find corresponding bio-entity representation used in BioThings Explorer based on user input (could be any database IDs, symbols, names)
FindConnection: Find intermediate bio-entities which connects user specified input and output
End of explanation
"""


ht = Hint()
anisindione = ht.query("Anisindione")['ChemicalSubstance'][0]

anisindione

"""
Explanation: Step 1: Find representation of "Anisindione" in BTE
In this step, BioThings Explorer translates our query string "Anisindioine"  into BioThings objects, which contain mappings to many common identifiers.  Generally, the top result returned by the Hint module will be the correct item, but you should confirm that using the identifiers shown.
Search terms can correspond to any child of BiologicalEntity from the Biolink Model, including DiseaseOrPhenotypicFeature (e.g., "lupus"), ChemicalSubstance (e.g., "acetaminophen"), Gene (e.g., "CDK2"), BiologicalProcess (e.g., "T cell differentiation"), and Pathway (e.g., "Citric acid cycle").
End of explanation
"""


fc = FindConnection(input_obj=anisindione, 
                    output_obj='PhenotypicFeature', 
                    intermediate_nodes=['Gene', 'Disease'])

fc.connect(verbose=True)

df = fc.display_table_view()

df.head()

"""
Explanation: Step 2: Find phenotypes that are associated with Anisindione through Gene and DiseaseOrPhenotypicFeature as intermediate nodes
In this section, we find all paths in the knowledge graph that connect Anisindione to any entity that is a phenotypic feature.  To do that, we will use FindConnection.  This class is a convenient wrapper around two advanced functions for query path planning and query path execution. More advanced features for both query path planning and query path execution are in development and will be documented in the coming months.
End of explanation
"""


dfFilt = df.loc[df['output_name'].notnull()].query('pred1 == "physically_interacts_with" and pred2 == "prevents"')

dfFilt

"""
Explanation: The df object contains the full output from BioThings Explorer. Each row shows one path that joins the input node (ANISINDIONE) to an intermediate node (a gene or protein) to another intermediate node (a DisseaseOrPhenotypicFeature) to an ending node (a Phenotypic Feature). The data frame includes a set of columns with additional details on each node and edge (including human-readable labels, identifiers, and sources). Let's remove all examples where the output_name (the phenotype label) is None, and specifically focus on paths with specific mechanistic predicates target and causes.
End of explanation
"""


