{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Hawksight-AI/semantica/blob/main/cookbook/use_cases/biomedical/01_Drug_Discovery_Pipeline.ipynb)\n",
    "\n",
    "# Drug Discovery Pipeline\n",
    "\n",
    "## Overview\n",
    "\n",
    "This notebook demonstrates a complete drug discovery pipeline: ingest drug and protein data from multiple sources (APIs, databases, feeds), extract compound and target entities, build drug-target knowledge graph, generate embeddings, perform similarity search, predict drug-target interactions, and identify targets.\n",
    "\n",
    "\n",
    "**Documentation**: [API Reference](https://semantica.readthedocs.io/use-cases/)\n",
    "\n",
    "## Installation\n",
    "\n",
    "Install Semantica from PyPI:\n",
    "\n",
    "```bash\n",
    "pip install semantica\n",
    "# Or with all optional dependencies:\n",
    "pip install semantica[all]\n",
    "```\n",
    "\n",
    "### Modules Used (20+)\n",
    "\n",
    "- **Ingestion**: FileIngestor, WebIngestor, FeedIngestor, StreamIngestor, DBIngestor, EmailIngestor, RepoIngestor, MCPIngestor\n",
    "- **Parsing**: JSONParser, StructuredDataParser, DocumentParser, MCPParser\n",
    "- **Extraction**: NERExtractor, RelationExtractor, TripleExtractor, SemanticAnalyzer\n",
    "- **KG**: GraphBuilder, GraphAnalyzer, CentralityCalculator, CommunityDetector\n",
    "- **Analytics**: ConnectivityAnalyzer, TemporalGraphQuery\n",
    "- **Embeddings**: EmbeddingGenerator, TextEmbedder\n",
    "- **Vector Store**: VectorStore, HybridSearch\n",
    "- **Reasoning**: InferenceEngine, RuleManager, ExplanationGenerator\n",
    "- **Ontology**: OntologyGenerator, OntologyValidator\n",
    "- **Export**: JSONExporter, RDFExporter, OWLExporter, ReportGenerator\n",
    "- **Visualization**: KGVisualizer, OntologyVisualizer, AnalyticsVisualizer\n",
    "\n",
    "### Pipeline\n",
    "\n",
    "**Drug/Protein Data Sources (APIs, DB, Feeds, MCP) → Parse → Extract Entities (compounds, targets, interactions) → Build Drug-Target KG → Generate Embeddings → Similarity Search → Predict Interactions → Target Identification → Generate Reports → Visualize**\n",
    "\n",
    "---\n",
    "\n",
    "## Step 1: Ingest Drug and Protein Data from Multiple Sources\n",
    "\n",
    "Ingest drug compound and protein target data from APIs, databases, and feeds.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from semantica.ingest import WebIngestor, DBIngestor, FeedIngestor, FileIngestor, MCPIngestor, ingest_mcp\n",
    "from semantica.parse import JSONParser, StructuredDataParser, DocumentParser, MCPParser\n",
    "from semantica.semantic_extract import NERExtractor, RelationExtractor, TripleExtractor, SemanticAnalyzer\n",
    "from semantica.kg import GraphBuilder, GraphAnalyzer, CentralityCalculator, CommunityDetector\n",
    "from semantica.kg import ConnectivityAnalyzer, TemporalGraphQuery\n",
    "from semantica.embeddings import EmbeddingGenerator, TextEmbedder\n",
    "from semantica.vector_store import VectorStore, HybridSearch\n",
    "from semantica.reasoning import InferenceEngine, RuleManager, ExplanationGenerator\n",
    "from semantica.ontology import OntologyGenerator, OntologyValidator\n",
    "from semantica.export import JSONExporter, RDFExporter, OWLExporter, ReportGenerator\n",
    "from semantica.visualization import KGVisualizer, OntologyVisualizer, AnalyticsVisualizer\n",
    "import tempfile\n",
    "import os\n",
    "import json\n",
    "from datetime import datetime, timedelta\n",
    "\n",
    "web_ingestor = WebIngestor()\n",
    "db_ingestor = DBIngestor()\n",
    "feed_ingestor = FeedIngestor()\n",
    "file_ingestor = FileIngestor()\n",
    "mcp_ingestor = MCPIngestor()\n",
    "\n",
    "json_parser = JSONParser()\n",
    "structured_parser = StructuredDataParser()\n",
    "document_parser = DocumentParser()\n",
    "mcp_parser = MCPParser()\n",
    "\n",
    "# Real drug APIs\n",
    "drug_apis = [\n",
    "    \"https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/2244/JSON\",  # PubChem API\n",
    "    \"https://www.ebi.ac.uk/chembl/api/data/molecule/CHEMBL25.json\",  # ChEMBL API\n",
    "    \"https://go.drugbank.com/releases/latest\"  # DrugBank API\n",
    "]\n",
    "\n",
    "# Real protein APIs\n",
    "protein_apis = [\n",
    "    \"https://www.uniprot.org/uniprot/P04637.json\",  # UniProt API\n",
    "    \"https://www.rcsb.org/pdb/json/descriptors/1A2B\"  # PDB API\n",
    "]\n",
    "\n",
    "# Real interaction databases\n",
    "interaction_databases = [\n",
    "    \"STRING\",\n",
    "    \"BioGRID\"\n",
    "]\n",
    "\n",
    "# Real database connection for compound libraries\n",
    "db_connection_string = \"postgresql://user:password@localhost:5432/drug_discovery_db\"\n",
    "db_query = \"SELECT compound_id, target_protein, interaction_type, binding_affinity, mechanism FROM drug_target_interactions WHERE binding_affinity < 100 LIMIT 1000\"\n",
    "\n",
    "temp_dir = tempfile.mkdtemp()\n",
    "\n",
    "# Sample drug-target data for local ingestion\n",
    "drug_data_file = os.path.join(temp_dir, \"drug_targets.json\")\n",
    "drug_data = [\n",
    "    {\n",
    "        \"compound_id\": \"CID2244\",\n",
    "        \"compound_name\": \"Aspirin\",\n",
    "        \"target_protein\": \"PTGS1\",\n",
    "        \"target_name\": \"Prostaglandin G/H synthase 1\",\n",
    "        \"interaction_type\": \"inhibitor\",\n",
    "        \"binding_affinity\": 5.2,\n",
    "        \"mechanism\": \"Irreversible inhibition\",\n",
    "        \"pathway\": \"Arachidonic acid metabolism\",\n",
    "        \"timestamp\": (datetime.now() - timedelta(days=1)).isoformat()\n",
    "    },\n",
    "    {\n",
    "        \"compound_id\": \"CID1983\",\n",
    "        \"compound_name\": \"Ibuprofen\",\n",
    "        \"target_protein\": \"PTGS2\",\n",
    "        \"target_name\": \"Prostaglandin G/H synthase 2\",\n",
    "        \"interaction_type\": \"inhibitor\",\n",
    "        \"binding_affinity\": 8.5,\n",
    "        \"mechanism\": \"Reversible inhibition\",\n",
    "        \"pathway\": \"Arachidonic acid metabolism\",\n",
    "        \"timestamp\": (datetime.now() - timedelta(days=2)).isoformat()\n",
    "    },\n",
    "    {\n",
    "        \"compound_id\": \"CID1983\",\n",
    "        \"compound_name\": \"Ibuprofen\",\n",
    "        \"target_protein\": \"PTGS1\",\n",
    "        \"target_name\": \"Prostaglandin G/H synthase 1\",\n",
    "        \"interaction_type\": \"inhibitor\",\n",
    "        \"binding_affinity\": 12.3,\n",
    "        \"mechanism\": \"Reversible inhibition\",\n",
    "        \"pathway\": \"Arachidonic acid metabolism\",\n",
    "        \"timestamp\": (datetime.now() - timedelta(days=2)).isoformat()\n",
    "    },\n",
    "    {\n",
    "        \"compound_id\": \"CID60823\",\n",
    "        \"compound_name\": \"Atorvastatin\",\n",
    "        \"target_protein\": \"HMGCR\",\n",
    "        \"target_name\": \"3-hydroxy-3-methylglutaryl-coenzyme A reductase\",\n",
    "        \"interaction_type\": \"inhibitor\",\n",
    "        \"binding_affinity\": 0.8,\n",
    "        \"mechanism\": \"Competitive inhibition\",\n",
    "        \"pathway\": \"Cholesterol biosynthesis\",\n",
    "        \"timestamp\": (datetime.now() - timedelta(days=3)).isoformat()\n",
    "    },\n",
    "    {\n",
    "        \"compound_id\": \"CID54686970\",\n",
    "        \"compound_name\": \"Metformin\",\n",
    "        \"target_protein\": \"PRKAA1\",\n",
    "        \"target_name\": \"5'-AMP-activated protein kinase catalytic subunit alpha-1\",\n",
    "        \"interaction_type\": \"activator\",\n",
    "        \"binding_affinity\": 15.0,\n",
    "        \"mechanism\": \"Allosteric activation\",\n",
    "        \"pathway\": \"AMPK signaling\",\n",
    "        \"timestamp\": (datetime.now() - timedelta(days=4)).isoformat()\n",
    "    }\n",
    "]\n",
    "\n",
    "with open(drug_data_file, 'w') as f:\n",
    "    json.dump(drug_data, f, indent=2)\n",
    "\n",
    "# Ingest from local file\n",
    "file_data = file_ingestor.ingest_file(drug_data_file)\n",
    "parsed_drug = structured_parser.parse_json(json.dumps(drug_data))\n",
    "\n",
    "# Ingest from drug APIs (example with public API)\n",
    "web_content = web_ingestor.ingest_url(drug_apis[0])  # PubChem API\n",
    "if web_content:\n",
    "    print(f\"  Ingested drug API: {drug_apis[0]}\")\n",
    "\n",
    "# Database ingestion pattern\n",
    "db_data = db_ingestor.export_table(\n",
    "    connection_string=db_connection_string,\n",
    "    table_name=\"drug_target_interactions\",\n",
    "    limit=1000\n",
    ")\n",
    "print(f\"  Query pattern: {db_query}\")\n",
    "\n",
    "# Optional: Ingest from MCP server\n",
    "# Users can bring their own drug/protein database MCP server via URL\n",
    "mcp_drug_data = []\n",
    "# Connect to biomedical database MCP server via URL\n",
    "# Example: http://localhost:8000/mcp or https://api.example.com/biomedical-mcp\n",
    "biomedical_mcp_url = \"http://localhost:8000/mcp\"  # Replace with your MCP server URL\n",
    "\n",
    "mcp_ingestor.connect(\n",
    "    \"biomedical_mcp_server\",\n",
    "    url=biomedical_mcp_url,\n",
    "    headers={\n",
    "        \"Authorization\": \"Bearer your_token\",\n",
    "        \"X-API-Key\": \"your_api_key\"\n",
    "    } if \"api.example.com\" in biomedical_mcp_url else {}\n",
    ")\n",
    "\n",
    "# Ingest drug-target interactions from MCP server\n",
    "mcp_data = mcp_ingestor.ingest_resources(\n",
    "    \"biomedical_mcp_server\",\n",
    "    resource_uris=[\"resource://drugs/interactions\", \"resource://proteins/targets\"]\n",
    ")\n",
    "mcp_drug_data.extend(mcp_data)\n",
    "print(f\"  Ingested {len(mcp_data)} MCP resources\")\n",
    "\n",
    "# Or use tool-based ingestion to query drug interactions\n",
    "tool_data = mcp_ingestor.ingest_tool_output(\n",
    "    \"biomedical_mcp_server\",\n",
    "    tool_name=\"query_drug_interactions\",\n",
    "    arguments={\n",
    "        \"compound_id\": \"CID2244\",\n",
    "        \"target_protein\": \"PTGS1\"\n",
    "    }\n",
    ")\n",
    "if tool_data:\n",
    "    mcp_drug_data.append(tool_data)\n",
    "    print(f\"  Retrieved tool data\")\n",
    "\n",
    "# Parse MCP responses and merge with existing drug data\n",
    "for mcp_item in mcp_drug_data:\n",
    "    parsed_mcp = mcp_parser.parse_response(mcp_item, response_type=\"json\")\n",
    "    if isinstance(parsed_mcp, dict):\n",
    "        if \"drug_targets\" in parsed_mcp or \"interactions\" in parsed_mcp:\n",
    "            # Merge drug-target interactions from MCP\n",
    "            mcp_interactions = parsed_mcp.get(\"drug_targets\", parsed_mcp.get(\"interactions\", []))\n",
    "            drug_data.extend(mcp_interactions)\n",
    "        elif \"compound_id\" in parsed_mcp:\n",
    "            # Single drug-target interaction\n",
    "            drug_data.append(parsed_mcp)\n",
    "        print(f\"  Parsed MCP item\")\n",
    "\n",
    "mcp_ingestor.disconnect(\"biomedical_mcp_server\")\n",
    "print(f\"  Disconnected from MCP server\")\n",
    "\n",
    "print(f\"\\n📊 Ingestion Summary:\")\n",
    "print(f\"  Local drug-target interactions: {len(drug_data)}\")\n",
    "print(f\"  Database records: {len(db_data.get('data', [])) if db_data else 0}\")\n",
    "print(f\"  Drug APIs: {len(drug_apis)}\")\n",
    "print(f\"  Protein APIs: {len(protein_apis)}\")\n",
    "print(f\"  MCP server sources: {len(mcp_drug_data)}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 2: Extract Drug and Target Entities\n",
    "\n",
    "Extract compounds, targets, and interactions from the ingested data.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ner_extractor = NERExtractor()\n",
    "relation_extractor = RelationExtractor()\n",
    "triple_extractor = TripleExtractor()\n",
    "semantic_analyzer = SemanticAnalyzer()\n",
    "\n",
    "all_drug_texts = []\n",
    "all_interactions = []\n",
    "\n",
    "# Process parsed drug data\n",
    "if parsed_drug and isinstance(parsed_drug, dict):\n",
    "    interactions = parsed_drug.get(\"data\", drug_data)\n",
    "    for interaction in interactions:\n",
    "        all_interactions.append(interaction)\n",
    "        interaction_text = f\"Compound {interaction.get('compound_name', '')} {interaction.get('interaction_type', '')} target {interaction.get('target_name', '')} with binding affinity {interaction.get('binding_affinity', 0)}\"\n",
    "        all_drug_texts.append(interaction_text)\n",
    "\n",
    "# Extract entities\n",
    "all_entities = []\n",
    "all_relationships = []\n",
    "all_triples = []\n",
    "\n",
    "for text in all_drug_texts:\n",
    "    entities = ner_extractor.extract(text)\n",
    "    all_entities.extend(entities)\n",
    "    \n",
    "    relationships = relation_extractor.extract(text, entities)\n",
    "    all_relationships.extend(relationships)\n",
    "    \n",
    "    triples = triple_extractor.extract(text)\n",
    "    all_triples.extend(triples)\n",
    "\n",
    "# Build structured entity list\n",
    "compound_entities = []\n",
    "target_entities = []\n",
    "interaction_entities = []\n",
    "\n",
    "unique_compounds = {}\n",
    "unique_targets = {}\n",
    "\n",
    "for interaction in all_interactions:\n",
    "    compound_id = interaction.get(\"compound_id\", \"\")\n",
    "    compound_name = interaction.get(\"compound_name\", \"\")\n",
    "    \n",
    "    if compound_id and compound_id not in unique_compounds:\n",
    "        compound_entity = {\n",
    "            \"id\": compound_id,\n",
    "            \"type\": \"Compound\",\n",
    "            \"properties\": {\n",
    "                \"compound_id\": compound_id,\n",
    "                \"name\": compound_name,\n",
    "                \"pathway\": interaction.get(\"pathway\", \"\")\n",
    "            }\n",
    "        }\n",
    "        compound_entities.append(compound_entity)\n",
    "        unique_compounds[compound_id] = compound_entity\n",
    "    \n",
    "    target_id = interaction.get(\"target_protein\", \"\")\n",
    "    target_name = interaction.get(\"target_name\", \"\")\n",
    "    \n",
    "    if target_id and target_id not in unique_targets:\n",
    "        target_entity = {\n",
    "            \"id\": target_id,\n",
    "            \"type\": \"Target\",\n",
    "            \"properties\": {\n",
    "                \"protein_id\": target_id,\n",
    "                \"name\": target_name,\n",
    "                \"pathway\": interaction.get(\"pathway\", \"\")\n",
    "            }\n",
    "        }\n",
    "        target_entities.append(target_entity)\n",
    "        unique_targets[target_id] = target_entity\n",
    "    \n",
    "    interaction_entity = {\n",
    "        \"id\": f\"{compound_id}_{target_id}\",\n",
    "        \"type\": \"Interaction\",\n",
    "        \"properties\": {\n",
    "            \"compound\": compound_id,\n",
    "            \"target\": target_id,\n",
    "            \"interaction_type\": interaction.get(\"interaction_type\", \"\"),\n",
    "            \"binding_affinity\": interaction.get(\"binding_affinity\", 0),\n",
    "            \"mechanism\": interaction.get(\"mechanism\", \"\"),\n",
    "            \"timestamp\": interaction.get(\"timestamp\", \"\")\n",
    "        }\n",
    "    }\n",
    "    interaction_entities.append(interaction_entity)\n",
    "\n",
    "print(f\"Extracted {len(compound_entities)} unique compounds\")\n",
    "print(f\"Extracted {len(target_entities)} unique targets\")\n",
    "print(f\"Extracted {len(interaction_entities)} interactions\")\n",
    "print(f\"Extracted {len(all_relationships)} relationships\")\n",
    "print(f\"Extracted {len(all_triples)} triples\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 3: Build Drug-Target Knowledge Graph\n",
    "\n",
    "Build a knowledge graph from extracted drug-target entities and relationships.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "builder = GraphBuilder()\n",
    "\n",
    "# Add all entities\n",
    "for compound in compound_entities:\n",
    "    builder.add_entity(\n",
    "        entity_id=compound[\"id\"],\n",
    "        entity_type=compound[\"type\"],\n",
    "        properties=compound.get(\"properties\", {})\n",
    "    )\n",
    "\n",
    "for target in target_entities:\n",
    "    builder.add_entity(\n",
    "        entity_id=target[\"id\"],\n",
    "        entity_type=target[\"type\"],\n",
    "        properties=target.get(\"properties\", {})\n",
    "    )\n",
    "\n",
    "for interaction in interaction_entities:\n",
    "    builder.add_entity(\n",
    "        entity_id=interaction[\"id\"],\n",
    "        entity_type=interaction[\"type\"],\n",
    "        properties=interaction.get(\"properties\", {})\n",
    "    )\n",
    "\n",
    "# Add relationships\n",
    "relationships = []\n",
    "for interaction in interaction_entities:\n",
    "    compound_id = interaction[\"properties\"].get(\"compound\", \"\")\n",
    "    target_id = interaction[\"properties\"].get(\"target\", \"\")\n",
    "    interaction_id = interaction[\"id\"]\n",
    "    interaction_type = interaction[\"properties\"].get(\"interaction_type\", \"\")\n",
    "    binding_affinity = interaction[\"properties\"].get(\"binding_affinity\", 0)\n",
    "    \n",
    "    # Compound-Target relationship\n",
    "    builder.add_relationship(\n",
    "        source_id=compound_id,\n",
    "        target_id=target_id,\n",
    "        relationship_type=interaction_type,\n",
    "        properties={\n",
    "            \"binding_affinity\": binding_affinity,\n",
    "            \"mechanism\": interaction[\"properties\"].get(\"mechanism\", \"\")\n",
    "        }\n",
    "    )\n",
    "    \n",
    "    # Interaction relationships\n",
    "    builder.add_relationship(\n",
    "        source_id=compound_id,\n",
    "        target_id=interaction_id,\n",
    "        relationship_type=\"has_interaction\",\n",
    "        properties={}\n",
    "    )\n",
    "    builder.add_relationship(\n",
    "        source_id=interaction_id,\n",
    "        target_id=target_id,\n",
    "        relationship_type=\"targets\",\n",
    "        properties={}\n",
    "    )\n",
    "    \n",
    "    relationships.append({\n",
    "        \"source\": compound_id,\n",
    "        \"target\": target_id,\n",
    "        \"type\": interaction_type,\n",
    "        \"binding_affinity\": binding_affinity\n",
    "    })\n",
    "\n",
    "knowledge_graph = builder.build()\n",
    "\n",
    "print(f\"Built knowledge graph with {len(knowledge_graph.nodes)} nodes\")\n",
    "print(f\"Built knowledge graph with {len(knowledge_graph.edges)} edges\")\n",
    "print(f\"Added {len(relationships)} drug-target relationships\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 4: Generate Embeddings and Setup Vector Store\n",
    "\n",
    "Generate embeddings from compound and target descriptions and setup vector store for similarity search.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "embedding_generator = EmbeddingGenerator()\n",
    "text_embedder = TextEmbedder()\n",
    "vector_store = VectorStore()\n",
    "hybrid_search = HybridSearch(vector_store, knowledge_graph)\n",
    "\n",
    "# Generate embeddings for compounds\n",
    "compound_texts = []\n",
    "compound_metadata = []\n",
    "for compound in compound_entities:\n",
    "    compound_text = f\"{compound['properties'].get('name', '')} pathway {compound['properties'].get('pathway', '')}\"\n",
    "    compound_texts.append(compound_text)\n",
    "    compound_metadata.append({\n",
    "        \"id\": compound[\"id\"],\n",
    "        \"type\": \"compound\",\n",
    "        \"name\": compound[\"properties\"].get(\"name\", \"\")\n",
    "    })\n",
    "\n",
    "# Generate embeddings for targets\n",
    "target_texts = []\n",
    "target_metadata = []\n",
    "for target in target_entities:\n",
    "    target_text = f\"{target['properties'].get('name', '')} pathway {target['properties'].get('pathway', '')}\"\n",
    "    target_texts.append(target_text)\n",
    "    target_metadata.append({\n",
    "        \"id\": target[\"id\"],\n",
    "        \"type\": \"target\",\n",
    "        \"name\": target[\"properties\"].get(\"name\", \"\")\n",
    "    })\n",
    "\n",
    "# Generate embeddings\n",
    "all_texts = compound_texts + target_texts\n",
    "all_metadata = compound_metadata + target_metadata\n",
    "\n",
    "embeddings = []\n",
    "for text in all_texts:\n",
    "    embedding = text_embedder.embed(text)\n",
    "    embeddings.append(embedding)\n",
    "\n",
    "# Store in vector store\n",
    "vector_store.store_vectors(embeddings, all_metadata)\n",
    "\n",
    "print(f\"Generated {len(embeddings)} embeddings\")\n",
    "print(f\"Stored {len(compound_texts)} compound embeddings\")\n",
    "print(f\"Stored {len(target_texts)} target embeddings\")\n",
    "print(f\"Vector store ready for similarity search\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 5: Predict Drug-Target Interactions\n",
    "\n",
    "Use hybrid search and inference to predict drug-target interactions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "graph_analyzer = GraphAnalyzer()\n",
    "centrality_calculator = CentralityCalculator()\n",
    "community_detector = CommunityDetector()\n",
    "connectivity_analyzer = ConnectivityAnalyzer()\n",
    "temporal_query = TemporalGraphQuery(knowledge_graph)\n",
    "inference_engine = InferenceEngine()\n",
    "rule_manager = RuleManager()\n",
    "\n",
    "# Compute graph metrics\n",
    "graph_metrics = graph_analyzer.compute_metrics(knowledge_graph)\n",
    "\n",
    "# Calculate centrality\n",
    "centrality_result = centrality_calculator.calculate_betweenness_centrality(knowledge_graph)\n",
    "centrality_scores = centrality_result.get('centrality', {})\n",
    "top_central_targets = sorted(centrality_scores.items(), key=lambda x: x[1], reverse=True)[:10]\n",
    "\n",
    "# Detect communities\n",
    "communities_result = community_detector.detect_communities(knowledge_graph, algorithm=\"louvain\")\n",
    "communities = communities_result.get('communities', [])\n",
    "community_count = len(communities) if communities else 0\n",
    "\n",
    "# Analyze connectivity\n",
    "connectivity_results = connectivity_analyzer.analyze_connectivity(knowledge_graph)\n",
    "\n",
    "# Define interaction prediction rules\n",
    "prediction_rules = [\n",
    "    {\n",
    "        \"name\": \"high_affinity_interaction\",\n",
    "        \"condition\": \"binding_affinity < 10\",\n",
    "        \"action\": \"predict_strong_interaction\"\n",
    "    },\n",
    "    {\n",
    "        \"name\": \"inhibitor_interaction\",\n",
    "        \"condition\": \"interaction_type == 'inhibitor' AND binding_affinity < 5\",\n",
    "        \"action\": \"predict_potent_inhibitor\"\n",
    "    },\n",
    "    {\n",
    "        \"name\": \"target_identification\",\n",
    "        \"condition\": \"multiple_compounds_target_same_protein\",\n",
    "        \"action\": \"identify_druggable_target\"\n",
    "    }\n",
    "]\n",
    "\n",
    "for rule in prediction_rules:\n",
    "    rule_manager.add_rule(rule[\"name\"], rule[\"condition\"], rule[\"action\"])\n",
    "\n",
    "# Predict interactions using similarity search\n",
    "query_compound = \"Aspirin\"\n",
    "query_embedding = text_embedder.embed(query_compound)\n",
    "\n",
    "# Hybrid search\n",
    "search_results = hybrid_search.search(\n",
    "    query_embedding=query_embedding,\n",
    "    query_text=query_compound,\n",
    "    k=5,\n",
    "    use_graph_expansion=True\n",
    ")\n",
    "\n",
    "# Predict interactions\n",
    "predicted_interactions = []\n",
    "for compound in compound_entities:\n",
    "    compound_id = compound[\"id\"]\n",
    "    compound_name = compound[\"properties\"].get(\"name\", \"\")\n",
    "    \n",
    "    # Find interactions for this compound\n",
    "    compound_interactions = [r for r in relationships if r[\"source\"] == compound_id]\n",
    "    \n",
    "    # Calculate interaction score\n",
    "    interaction_score = 0\n",
    "    for interaction in compound_interactions:\n",
    "        binding_affinity = interaction.get(\"binding_affinity\", 100)\n",
    "        if binding_affinity < 10:\n",
    "            interaction_score += 3\n",
    "        elif binding_affinity < 50:\n",
    "            interaction_score += 2\n",
    "        else:\n",
    "            interaction_score += 1\n",
    "    \n",
    "    predicted_interactions.append({\n",
    "        \"compound\": compound_name,\n",
    "        \"compound_id\": compound_id,\n",
    "        \"interaction_count\": len(compound_interactions),\n",
    "        \"interaction_score\": interaction_score,\n",
    "        \"targets\": [r[\"target\"] for r in compound_interactions]\n",
    "    })\n",
    "\n",
    "# Identify druggable targets\n",
    "target_interaction_counts = {}\n",
    "for rel in relationships:\n",
    "    target = rel[\"target\"]\n",
    "    target_interaction_counts[target] = target_interaction_counts.get(target, 0) + 1\n",
    "\n",
    "druggable_targets = []\n",
    "for target_id, count in target_interaction_counts.items():\n",
    "    if count >= 2:\n",
    "        target_name = next((t[\"properties\"].get(\"name\", target_id) for t in target_entities if t[\"id\"] == target_id), target_id)\n",
    "        druggable_targets.append({\n",
    "            \"target\": target_name,\n",
    "            \"target_id\": target_id,\n",
    "            \"compound_count\": count,\n",
    "            \"description\": f\"Target {target_name} is targeted by {count} compounds, indicating druggability\"\n",
    "        })\n",
    "\n",
    "print(f\"Analyzed {len(compound_entities)} compounds\")\n",
    "print(f\"Found {community_count} target communities\")\n",
    "print(f\"Identified {len(druggable_targets)} druggable targets\")\n",
    "print(f\"\\nTop 5 Central Targets:\")\n",
    "for i, (target_id, centrality) in enumerate(top_central_targets[:5], 1):\n",
    "    target_name = next((t[\"properties\"].get(\"name\", target_id) for t in target_entities if t[\"id\"] == target_id), target_id)\n",
    "    print(f\"  {i}. {target_name} (centrality: {centrality:.3f})\")\n",
    "print(f\"\\nPredicted Interactions:\")\n",
    "for pred in sorted(predicted_interactions, key=lambda x: x[\"interaction_score\"], reverse=True)[:5]:\n",
    "    print(f\"  - {pred['compound']}: {pred['interaction_count']} interactions, Score: {pred['interaction_score']}\")\n",
    "print(f\"\\nDruggable Targets:\")\n",
    "for target in druggable_targets[:5]:\n",
    "    print(f\"  - {target['target']}: {target['compound_count']} compounds\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ontology_generator = OntologyGenerator()\n",
    "ontology_validator = OntologyValidator()\n",
    "json_exporter = JSONExporter()\n",
    "rdf_exporter = RDFExporter()\n",
    "owl_exporter = OWLExporter()\n",
    "report_generator = ReportGenerator()\n",
    "\n",
    "# Generate drug discovery ontology\n",
    "drug_ontology = ontology_generator.generate_ontology(\n",
    "    {\"entities\": compound_entities + target_entities + interaction_entities, \n",
    "     \"relationships\": relationships},\n",
    "    name=\"DrugDiscoveryOntology\",\n",
    "    entities=compound_entities + target_entities + interaction_entities,\n",
    "    relationships=relationships\n",
    ")\n",
    "\n",
    "# Validate ontology\n",
    "validation_result = ontology_validator.validate_ontology(drug_ontology)\n",
    "\n",
    "# Export knowledge graph\n",
    "kg_json = json_exporter.export(knowledge_graph, output_path=os.path.join(temp_dir, \"drug_target_kg.json\"))\n",
    "kg_rdf = rdf_exporter.export(knowledge_graph, output_path=os.path.join(temp_dir, \"drug_target_kg.rdf\"))\n",
    "\n",
    "# Export ontology\n",
    "ontology_owl = owl_exporter.export(drug_ontology, output_path=os.path.join(temp_dir, \"drug_ontology.owl\"))\n",
    "\n",
    "# Generate report\n",
    "report_content = f\"\"\"\n",
    "# Drug Discovery Pipeline Report\n",
    "\n",
    "## Executive Summary\n",
    "- Total Compounds Analyzed: {len(compound_entities)}\n",
    "- Total Targets: {len(target_entities)}\n",
    "- Total Interactions: {len(interaction_entities)}\n",
    "- Druggable Targets Identified: {len(druggable_targets)}\n",
    "- High-Affinity Interactions: {len([r for r in relationships if r.get('binding_affinity', 100) < 10])}\n",
    "\n",
    "## Top Druggable Targets\n",
    "\"\"\"\n",
    "for i, target in enumerate(druggable_targets[:10], 1):\n",
    "    report_content += f\"\"\"\n",
    "{i}. {target['target']}\n",
    "   - Compound Count: {target['compound_count']}\n",
    "   - Description: {target['description']}\n",
    "\"\"\"\n",
    "\n",
    "report_content += f\"\"\"\n",
    "## Predicted Interactions\n",
    "\"\"\"\n",
    "for pred in sorted(predicted_interactions, key=lambda x: x[\"interaction_score\"], reverse=True)[:10]:\n",
    "    report_content += f\"\"\"\n",
    "### {pred['compound']}\n",
    "- Interaction Count: {pred['interaction_count']}\n",
    "- Interaction Score: {pred['interaction_score']}\n",
    "- Targets: {', '.join(pred['targets'][:5])}\n",
    "\"\"\"\n",
    "\n",
    "report_path = os.path.join(temp_dir, \"drug_discovery_report.md\")\n",
    "with open(report_path, 'w') as f:\n",
    "    f.write(report_content)\n",
    "\n",
    "print(f\"Generated drug discovery ontology with {len(drug_ontology.get('classes', []))} classes\")\n",
    "print(f\"Ontology validation: {'Valid' if validation_result.valid else 'Invalid'}\")\n",
    "print(f\"  Errors: {len(validation_result.errors)}\")\n",
    "print(f\"  Warnings: {len(validation_result.warnings)}\")\n",
    "print(f\"Exported knowledge graph to JSON and RDF\")\n",
    "print(f\"Exported ontology to OWL\")\n",
    "print(f\"Generated discovery report: {report_path}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 7: Visualize Drug-Target Network\n",
    "\n",
    "Visualize the drug-target knowledge graph, ontology, and analytics.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "kg_visualizer = KGVisualizer()\n",
    "ontology_visualizer = OntologyVisualizer()\n",
    "analytics_visualizer = AnalyticsVisualizer()\n",
    "\n",
    "# Visualize knowledge graph\n",
    "kg_viz = kg_visualizer.visualize(\n",
    "    knowledge_graph,\n",
    "    layout=\"force_directed\",\n",
    "    highlight_nodes=[t[\"id\"] for t in druggable_targets[:5]],\n",
    "    node_size_by=\"centrality\"\n",
    ")\n",
    "\n",
    "# Visualize ontology\n",
    "ontology_viz = ontology_visualizer.visualize(\n",
    "    drug_ontology,\n",
    "    layout=\"hierarchical\"\n",
    ")\n",
    "\n",
    "# Visualize analytics\n",
    "analytics_viz = analytics_visualizer.visualize(\n",
    "    knowledge_graph,\n",
    "    metrics={\n",
    "        \"centrality\": dict(top_central_targets[:10]),\n",
    "        \"communities\": communities,\n",
    "        \"connectivity\": connectivity_results,\n",
    "        \"interaction_scores\": {p[\"compound_id\"]: p[\"interaction_score\"] for p in predicted_interactions}\n",
    "    }\n",
    ")\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
