{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This notebook is used to find a network from a list of nodes in Translator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from TCT import name_resolver\n",
    "from TCT import node_normalizer\n",
    "from TCT import translator_metakg\n",
    "from TCT import translator_kpinfo\n",
    "from TCT import translator_query\n",
    "from TCT import TCT\n",
    "\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import requests\n",
    "import json\n",
    "import pandas as pd\n",
    "import  seaborn as sns\n",
    "import networkx as nx\n",
    "import numpy as np\n",
    "import ipycytoscape\n",
    "import yaml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_translator_resources():\n",
    "    \"\"\"\n",
    "    Load the necessary resources for the Translator.\n",
    "    \"\"\"\n",
    "    Translator_KP_info,APInames= translator_kpinfo.get_translator_kp_info()\n",
    "    metaKG = translator_metakg.get_KP_metadata(APInames) \n",
    "    APInames,metaKG = translator_metakg.add_plover_API(APInames, metaKG)\n",
    "    return  APInames, metaKG, Translator_KP_info\n",
    "\n",
    "\n",
    "def visualize_interaction_network(result_json):\n",
    "    \"\"\"\n",
    "    Visualize the interaction network from the result JSON.\n",
    "\n",
    "    Parameters:\n",
    "    result_json (dict): The result JSON containing subjects, objects, and predicates.\n",
    "    \n",
    "    \"\"\"\n",
    "    import pandas as pd\n",
    "    import networkx as nx\n",
    "    import ipycytoscape\n",
    "\n",
    "    subjects = []\n",
    "    objects = []\n",
    "    predicates = []\n",
    "\n",
    "    for k, v in result_json.items():\n",
    "        subjects.append(v['subject'])\n",
    "        objects.append(v['object'])\n",
    "        predicates.append(v['predicate'])\n",
    "\n",
    "    # Convert subject and object CURIEs to names using lookup\n",
    "    subject_names = []\n",
    "    object_names = []\n",
    "\n",
    "    # Use batch_lookup for all subjects and objects to minimize API calls\n",
    "    unique_nodes = set(subjects + objects)\n",
    "    node_info_dict = name_resolver.batch_lookup(list(unique_nodes))\n",
    "    print(node_info_dict)\n",
    "\n",
    "    for subj, obj in zip(subjects, objects):\n",
    "        subj_info = node_info_dict.get(subj)\n",
    "        obj_info = node_info_dict.get(obj)\n",
    "        subject_names.append(subj_info.name if subj_info and hasattr(subj_info, 'name') else subj)\n",
    "        object_names.append(obj_info.name if obj_info and hasattr(obj_info, 'name') else obj)\n",
    "\n",
    "\n",
    "    df = pd.DataFrame({\n",
    "        \"Subject\": subject_names,\n",
    "        \"Object\": object_names,\n",
    "        \"Predicate\": predicates,\n",
    "    })\n",
    "\n",
    "    print(df.head())\n",
    "    # merge predicates and sources\n",
    "    # Convert 'Sources' to a string representation\n",
    "    # Remove duplicate edges\n",
    "    df = df.drop_duplicates()\n",
    "\n",
    "    # Build networkx graph\n",
    "    G1 = nx.from_pandas_edgelist(df, source='Subject', target='Object', edge_attr=['Predicate'], create_using=nx.MultiGraph)\n",
    "\n",
    "    # Cytoscape style\n",
    "    graph_style = [\n",
    "        {'selector': 'node', 'style': {'background-color': 'lightblue', 'shape': 'ellipse', 'label': 'data(id)', 'font-size': '12px'}},\n",
    "        {'selector': 'edge', 'style': {'label': 'data(Predicate)', 'font-size': '10px', \"curve-style\": \"bezier\"}}\n",
    "    ]\n",
    "\n",
    "    cyto_graph = ipycytoscape.CytoscapeWidget()\n",
    "    cyto_graph.graph.add_graph_from_networkx(G1, directed=True)\n",
    "    cyto_graph.set_style(graph_style)\n",
    "    cyto_graph.set_layout(name='cose', nodeSpacing=80, edgeLengthVal=50)\n",
    "\n",
    "    display(cyto_graph)\n",
    "\n",
    "    return df\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "APInames, metaKG, Translator_KP_info= load_translator_resources()\n",
    "\n",
    "All_predicates = list(set(metaKG['Predicate']))\n",
    "All_categories = list((set(list(set(metaKG['Subject']))+list(set(metaKG['Object'])))))\n",
    "API_withMetaKG = list(set(metaKG['API']))\n",
    "\n",
    "    # generate a dictionary of API and its predicates\n",
    "API_predicates = {}\n",
    "for api in API_withMetaKG:\n",
    "    API_predicates[api] = list(set(metaKG[metaKG['API'] == api]['Predicate']))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "all relevant predicates in Translator:\n",
      "['biolink:has_member', 'biolink:transcribed_from', 'biolink:disrupts', 'biolink:is_sequence_variant_of', 'biolink:affects', 'biolink:part_of', 'biolink:interacts_with', 'biolink:directly_physically_interacts_with', 'biolink:composed_primarily_of', 'biolink:biomarker_for', 'biolink:causes', 'biolink:associated_with_resistance_to', 'biolink:increases_response_to', 'biolink:derives_from', 'biolink:similar_to', 'biolink:produces', 'biolink:in_complex_with', 'biolink:contraindicated_in', 'biolink:associated_with', 'biolink:occurs_together_in_literature_with', 'biolink:translates_to', 'biolink:has_input', 'biolink:derives_into', 'biolink:colocalizes_with', 'biolink:has_gene_product', 'biolink:affects_response_to', 'biolink:gene_associated_with_condition', 'biolink:associated_with_increased_likelihood_of', 'biolink:has_phenotype', 'biolink:coexists_with', 'biolink:regulates', 'biolink:GeneAffectsChemicalAssociation', 'biolink:positively_correlated_with', 'biolink:gene_product_of', 'biolink:overlaps', 'biolink:affected_by', 'biolink:response_affected_by', 'biolink:occurs_in', 'biolink:has_part', 'biolink:physically_interacts_with', 'biolink:related_to', 'biolink:produced_by', 'biolink:orthologous_to', 'biolink:chemically_similar_to', 'biolink:capable_of', 'biolink:close_match', 'biolink:has_participant', 'biolink:preventative_for_condition', 'biolink:homologous_to', 'biolink:physical_interacts_with', 'biolink:negatively_correlated_with', 'biolink:regulated_by', 'biolink:associated_with_sensitivity_to', 'biolink:correlated_with', 'biolink:located_in', 'biolink:decreases_response_to', 'biolink:target_for', 'biolink:acts_upstream_of_or_within', 'biolink:same_as', 'biolink:treats_or_applied_or_studied_to_treat', 'biolink:expressed_in', 'biolink:genetically_associated_with', 'biolink:coexpressed_with', 'biolink:genetically_interacts_with', 'biolink:subclass_of']\n",
      "all relevant APIs in Translator:\n",
      "['CATRAX BigGIM DrugResponse Performance Phase KP - TRAPI 1.5.0', 'Automat-monarchinitiative(Trapi v1.5.0)', 'Multiomics KP - TRAPI 1.5.0', 'Service Provider TRAPI', 'CATRAX Pharmacogenomics KP - TRAPI 1.5.0', 'Automat-cam-kp(Trapi v1.5.0)', 'Automat-robokop(Trapi v1.5.0)', 'Automat-pharos(Trapi v1.5.0)', 'Microbiome KP - TRAPI 1.5.0', 'MolePro', 'RTX KG2 - TRAPI 1.5.0', 'Automat-ehr-clinical-connections-kp(Trapi v1.5.0)', 'Automat-icees-kg(Trapi v1.5.0)', 'Connections Hypothesis Provider API', 'Text Mined Cooccurrence API', 'Automat-ehr-may-treat-kp(Trapi v1.5.0)', 'Automat-genome-alliance(Trapi v1.5.0)', 'SPOKE KP for TRAPI 1.5', 'imProving Agent for TRAPI 1.5', 'Automat-hetionet(Trapi v1.5.0)', 'BioThings Explorer (BTE) TRAPI']\n",
      "21\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['https://multiomics.rtx.ai:9990/BigGIM_DrugResponse_PerformancePhase/query',\n",
       " 'https://automat.transltr.io/monarch-kg/query/',\n",
       " 'https://multiomics.rtx.ai:9990/multiomics/query',\n",
       " 'https://bte.transltr.io/v1/team/Service%20Provider/query/',\n",
       " 'https://multiomics.rtx.ai:9990/PharmacogenomicsKG/query',\n",
       " 'https://automat.transltr.io/cam-kp/query/',\n",
       " 'https://automat.transltr.io/robokopkg/query/',\n",
       " 'https://automat.transltr.io/pharos/query/',\n",
       " 'https://multiomics.rtx.ai:9990/mbkp/query',\n",
       " 'https://molepro-trapi.transltr.io/molepro/trapi/v1.5/query/',\n",
       " 'https://kg2cploverdb.ci.transltr.io/kg2c/query',\n",
       " 'https://automat.renci.org/ehr-clinical-connections-kp/query/',\n",
       " 'https://automat.transltr.io/icees-kg/query/',\n",
       " 'https://chp-api.transltr.io/query/',\n",
       " 'https://cooccurrence.transltr.io/query/',\n",
       " 'https://automat.renci.org/ehr-may-treat-kp/query/',\n",
       " 'https://automat.transltr.io/genome-alliance/query/',\n",
       " 'https://spokekp.transltr.io/api/v1.5/query/',\n",
       " 'https://ia.transltr.io/api/v1.5/query/',\n",
       " 'https://automat.transltr.io/hetio/query/',\n",
       " 'https://bte.transltr.io/v1/query/']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# input_nodes\n",
    "input_list = ['NPM1', 'FLT3', 'NRAS', 'BCL2', 'WNT7B']\n",
    "input_info = name_resolver.batch_lookup(input_list)\n",
    "input_node1_list = [] # get the curie of the nodes in the input_info dictionary\n",
    "input_node1_list = [input_info[node].curie for node in input_list]\n",
    "input_node1_category = []\n",
    "for node in input_list:\n",
    "    if hasattr(input_info[node], 'types'):\n",
    "        input_node1_category = input_node1_category + input_info[node].types\n",
    "input_node1_category = list(set(input_node1_category))\n",
    "\n",
    "# query nodes\n",
    "input_node2_list = []\n",
    "input_node2_category = ['biolink:Gene', 'biolink:Protein', 'biolink:ChemicalSubstance', 'biolink:Drug', 'biolink:DiseaseOrPhenotypicFeature']\n",
    "\n",
    "sele_predicates = list(set(TCT.select_concept(sub_list=input_node1_category,obj_list=input_node2_category,metaKG=metaKG)))\n",
    "print(\"all relevant predicates in Translator:\")\n",
    "print(sele_predicates)\n",
    "\n",
    "\n",
    "# Get all APIs for the input node1 and node2, user can furter select the APIs among this list\n",
    "sele_APIs = TCT.select_API(sub_list=input_node1_category,obj_list=input_node2_category,metaKG=metaKG)\n",
    "print(\"all relevant APIs in Translator:\")\n",
    "print(sele_APIs)\n",
    "print(len(sele_APIs))\n",
    "\n",
    "#sele_APIs = ['Multiomics BigGIM-DrugResponse KP API']\n",
    "sele_APIs = sele_APIs\n",
    "# get API URLs : two options: filter by API names or filter by predicates\n",
    "API_URLs = TCT.get_Translator_API_URL(sele_APIs, \n",
    "                                      APInames)\n",
    "\n",
    "API_URLs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "query_json = TCT.format_query_json(input_node1_list,  # a list of identifiers for input node1\n",
    "                                   input_node2_list,  # it can be empty list if only want to query node1\n",
    "                                   input_node1_category,  # a list of categories of input node1\n",
    "                                   input_node2_category,  # a list of categories of input node2\n",
    "                                   sele_predicates) # a list of pre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "'Multiomics KP - TRAPI 1.5.0' generated an exception: argument of type 'NoneType' is not iterable\n",
      "Microbiome KP - TRAPI 1.5.0: Success!\n",
      "'MolePro' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'imProving Agent for TRAPI 1.5' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'Automat-icees-kg(Trapi v1.5.0)' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'SPOKE KP for TRAPI 1.5' generated an exception: argument of type 'NoneType' is not iterable\n",
      "Automat-genome-alliance(Trapi v1.5.0): Success!\n",
      "'Automat-ehr-may-treat-kp(Trapi v1.5.0)' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'Automat-ehr-clinical-connections-kp(Trapi v1.5.0)' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'Automat-monarchinitiative(Trapi v1.5.0)' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'Text Mined Cooccurrence API' generated an exception: argument of type 'NoneType' is not iterable\n",
      "'Connections Hypothesis Provider API' generated an exception: 'NoneType' object has no attribute 'get'\n",
      "CATRAX BigGIM DrugResponse Performance Phase KP - TRAPI 1.5.0: Success!\n",
      "Automat-cam-kp(Trapi v1.5.0): Success!\n",
      "Automat-pharos(Trapi v1.5.0): Success!\n",
      "CATRAX Pharmacogenomics KP - TRAPI 1.5.0: Success!\n",
      "Automat-hetionet(Trapi v1.5.0): Success!\n",
      "RTX KG2 - TRAPI 1.5.0: Success!\n",
      "Automat-robokop(Trapi v1.5.0): Success!\n",
      "Service Provider TRAPI: Success!\n",
      "BioThings Explorer (BTE) TRAPI: Success!\n"
     ]
    }
   ],
   "source": [
    "# Step 5: Query Translator APIs and parse results\n",
    "\n",
    "result = translator_query.parallel_api_query(query_json=query_json, \n",
    "                             select_APIs= sele_APIs, \n",
    "                             APInames=APInames,\n",
    "                             API_predicates=API_predicates,\n",
    "                             max_workers=len(sele_APIs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'NCBIGene:2322': TranslatorNode(curie='NCBIGene:100313282', label='MIR2322', types=['biolink:Gene', 'biolink:GeneOrGeneProduct', 'biolink:GenomicEntity', 'biolink:ChemicalEntityOrGeneOrGeneProduct', 'biolink:PhysicalEssence', 'biolink:OntologyClass', 'biolink:BiologicalEntity', 'biolink:ThingWithTaxon', 'biolink:NamedThing', 'biolink:Entity', 'biolink:PhysicalEssenceOrOccurrent', 'biolink:MacromolecularMachineMixin'], synonyms=None, curie_synonyms=None), 'NCBIGene:4893': TranslatorNode(curie='MESH:C568585', label='S-4893 compound', types=['biolink:ChemicalEntity', 'biolink:PhysicalEssence', 'biolink:ChemicalOrDrugOrTreatment', 'biolink:ChemicalEntityOrGeneOrGeneProduct', 'biolink:ChemicalEntityOrProteinOrPolypeptide', 'biolink:NamedThing', 'biolink:Entity', 'biolink:PhysicalEssenceOrOccurrent'], synonyms=None, curie_synonyms=None), 'NCBIGene:4869': TranslatorNode(curie='PUBCHEM.COMPOUND:676542', label='Cl-4869 peak 2', types=['biolink:SmallMolecule', 'biolink:MolecularEntity', 'biolink:ChemicalEntity', 'biolink:PhysicalEssence', 'biolink:ChemicalOrDrugOrTreatment', 'biolink:ChemicalEntityOrGeneOrGeneProduct', 'biolink:ChemicalEntityOrProteinOrPolypeptide', 'biolink:NamedThing', 'biolink:Entity', 'biolink:PhysicalEssenceOrOccurrent'], synonyms=None, curie_synonyms=None), 'NCBIGene:596': TranslatorNode(curie='UniProtKB:A0A4X1SN03', label='A0A4X1SN03_PIG Zinc finger protein 596 (trembl)', types=['biolink:Protein', 'biolink:GeneProductMixin', 'biolink:Polypeptide', 'biolink:ChemicalEntityOrGeneOrGeneProduct', 'biolink:ChemicalEntityOrProteinOrPolypeptide', 'biolink:BiologicalEntity', 'biolink:ThingWithTaxon', 'biolink:NamedThing', 'biolink:Entity', 'biolink:GeneOrGeneProduct', 'biolink:MacromolecularMachineMixin'], synonyms=None, curie_synonyms=None)}\n",
      "         Subject         Object                          Predicate\n",
      "0  NCBIGene:2322  NCBIGene:2322  biolink:physically_interacts_with\n",
      "1   NCBIGene:596   NCBIGene:596  biolink:physically_interacts_with\n",
      "2  NCBIGene:4869  NCBIGene:4869  biolink:physically_interacts_with\n",
      "3  NCBIGene:4893  NCBIGene:4893  biolink:physically_interacts_with\n",
      "4  NCBIGene:2322  NCBIGene:4893            biolink:associated_with\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b744b944a70c497c91db081fb98ef845",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "CytoscapeWidget(cytoscape_layout={'name': 'cose', 'nodeSpacing': 80, 'edgeLengthVal': 50}, cytoscape_style=[{'…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# select the recored in the result which is a dictionary if the subject and objects are both in input_node1_list\n",
    "result_filtered = {k: v for k, v in result.items() if isinstance(v, dict) and\n",
    "                   v.get('subject') in input_node1_list and\n",
    "                   v.get('object') in input_node1_list}\n",
    "\n",
    "len(result_filtered)\n",
    "result_df =visualize_interaction_network(result_filtered)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
