Upload 2 files
Browse files- app.py +496 -0
- requirements.txt +5 -0
app.py
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
import json
|
| 5 |
+
import re
|
| 6 |
+
import matplotlib
|
| 7 |
+
matplotlib.use("Agg")
|
| 8 |
+
import matplotlib.pyplot as plt
|
| 9 |
+
import matplotlib.patches as mpatches
|
| 10 |
+
from io import BytesIO
|
| 11 |
+
from PIL import Image
|
| 12 |
+
|
| 13 |
+
# ── Shared theme colours ──────────────────────────────────────────────────────
|
| 14 |
+
BG = "#0f172a"
|
| 15 |
+
CARD = "#1e293b"
|
| 16 |
+
ACC = "#f97316"
|
| 17 |
+
ACC2 = "#38bdf8"
|
| 18 |
+
TXT = "#f1f5f9"
|
| 19 |
+
|
| 20 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 21 |
+
# TAB 1 — BRCA2 miRNA (A1)
|
| 22 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 23 |
+
MIRNA_DB = {
|
| 24 |
+
"BRCA2": [
|
| 25 |
+
{"miRNA":"hsa-miR-148a-3p","log2FC":-0.70,"padj":0.013,"targets":"DNMT1, AKT2","pathway":"Epigenetic reprogramming"},
|
| 26 |
+
{"miRNA":"hsa-miR-30e-5p", "log2FC":-0.49,"padj":0.032,"targets":"MYC, KRAS","pathway":"Oncogene suppression"},
|
| 27 |
+
{"miRNA":"hsa-miR-551b-3p","log2FC":-0.59,"padj":0.048,"targets":"SMAD4, CDK6","pathway":"TGF-β / CDK4/6"},
|
| 28 |
+
{"miRNA":"hsa-miR-22-3p", "log2FC":-0.43,"padj":0.041,"targets":"HIF1A, PTEN","pathway":"Hypoxia / PI3K"},
|
| 29 |
+
{"miRNA":"hsa-miR-200c-3p","log2FC":-0.38,"padj":0.044,"targets":"ZEB1, ZEB2","pathway":"EMT suppression"},
|
| 30 |
+
],
|
| 31 |
+
"BRCA1": [
|
| 32 |
+
{"miRNA":"hsa-miR-155-5p", "log2FC":-0.81,"padj":0.008,"targets":"SHIP1, SOCS1","pathway":"Immune evasion"},
|
| 33 |
+
{"miRNA":"hsa-miR-146a-5p","log2FC":-0.65,"padj":0.019,"targets":"TRAF6, IRAK1","pathway":"NF-κB signalling"},
|
| 34 |
+
{"miRNA":"hsa-miR-21-5p", "log2FC":-0.55,"padj":0.027,"targets":"PTEN, PDCD4","pathway":"Apoptosis"},
|
| 35 |
+
{"miRNA":"hsa-miR-17-5p", "log2FC":-0.47,"padj":0.036,"targets":"RB1, E2F1","pathway":"Cell cycle"},
|
| 36 |
+
{"miRNA":"hsa-miR-34a-5p", "log2FC":-0.41,"padj":0.049,"targets":"BCL2, CDK6","pathway":"p53 axis"},
|
| 37 |
+
],
|
| 38 |
+
"TP53": [
|
| 39 |
+
{"miRNA":"hsa-miR-34a-5p", "log2FC":-1.10,"padj":0.001,"targets":"BCL2, CDK6","pathway":"p53-miR-34 axis"},
|
| 40 |
+
{"miRNA":"hsa-miR-192-5p", "log2FC":-0.90,"padj":0.005,"targets":"MDM2, DHFR","pathway":"p53 feedback"},
|
| 41 |
+
{"miRNA":"hsa-miR-145-5p", "log2FC":-0.75,"padj":0.012,"targets":"MYC, EGFR","pathway":"Growth suppression"},
|
| 42 |
+
{"miRNA":"hsa-miR-107", "log2FC":-0.62,"padj":0.023,"targets":"CDK6, HIF1B","pathway":"Hypoxia / cell cycle"},
|
| 43 |
+
{"miRNA":"hsa-miR-215-5p", "log2FC":-0.51,"padj":0.038,"targets":"DTL, DHFR","pathway":"DNA damage response"},
|
| 44 |
+
],
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
def predict_mirna(gene):
|
| 48 |
+
rows = MIRNA_DB.get(gene, [])
|
| 49 |
+
df = pd.DataFrame(rows)
|
| 50 |
+
return df
|
| 51 |
+
|
| 52 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 53 |
+
# TAB 2 — TP53 siRNA (A2)
|
| 54 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 55 |
+
SIRNA_DB = {
|
| 56 |
+
"LUAD": [
|
| 57 |
+
{"Gene":"SPC24","ΔCERES":-0.175,"log2FC":1.13,"Drug status":"Novel","siRNA":"GCAGCUGAAGAAACUGAAU"},
|
| 58 |
+
{"Gene":"BUB1B","ΔCERES":-0.119,"log2FC":1.12,"Drug status":"Novel","siRNA":"CCAAAGAGCUGAAGAACAU"},
|
| 59 |
+
{"Gene":"CDC45","ΔCERES":-0.144,"log2FC":1.26,"Drug status":"Novel","siRNA":"GCAUCAAGAUGAAGGAGAU"},
|
| 60 |
+
{"Gene":"PLK1", "ΔCERES":-0.239,"log2FC":1.03,"Drug status":"Clinical","siRNA":"GACGCUCAAGAUGCAGAUU"},
|
| 61 |
+
{"Gene":"CDK1", "ΔCERES":-0.201,"log2FC":1.00,"Drug status":"Clinical","siRNA":"GCAGAAGCACUGAAGAUUU"},
|
| 62 |
+
],
|
| 63 |
+
"BRCA": [
|
| 64 |
+
{"Gene":"AURKA","ΔCERES":-0.165,"log2FC":1.20,"Drug status":"Clinical","siRNA":"GCACUGAAGAUGCAGAAUU"},
|
| 65 |
+
{"Gene":"AURKB","ΔCERES":-0.140,"log2FC":1.15,"Drug status":"Clinical","siRNA":"CCUGAAGACGCUCAAGGUU"},
|
| 66 |
+
{"Gene":"CENPW","ΔCERES":-0.125,"log2FC":0.95,"Drug status":"Novel","siRNA":"GCAGAAGCACUGAAGAUUU"},
|
| 67 |
+
{"Gene":"RFC2", "ΔCERES":-0.136,"log2FC":0.50,"Drug status":"Novel","siRNA":"GCAAGAUGCAGAAGCACUU"},
|
| 68 |
+
{"Gene":"TYMS", "ΔCERES":-0.131,"log2FC":0.72,"Drug status":"Approved","siRNA":"GGACGCUCAAGAUGCAGAU"},
|
| 69 |
+
],
|
| 70 |
+
"COAD": [
|
| 71 |
+
{"Gene":"KRAS", "ΔCERES":-0.210,"log2FC":0.80,"Drug status":"Clinical","siRNA":"GCUGGAGCUGGUGGUAGUU"},
|
| 72 |
+
{"Gene":"WEE1", "ΔCERES":-0.180,"log2FC":1.05,"Drug status":"Clinical","siRNA":"GCAGCUGAAGAAACUGAAU"},
|
| 73 |
+
{"Gene":"CHEK1","ΔCERES":-0.155,"log2FC":0.90,"Drug status":"Clinical","siRNA":"CCAAAGAGCUGAAGAACAU"},
|
| 74 |
+
{"Gene":"RFC2", "ΔCERES":-0.130,"log2FC":0.55,"Drug status":"Novel","siRNA":"GCAUCAAGAUGAAGGAGAU"},
|
| 75 |
+
{"Gene":"PKMYT1","ΔCERES":-0.122,"log2FC":1.07,"Drug status":"Clinical","siRNA":"GACGCUCAAGAUGCAGAUU"},
|
| 76 |
+
],
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
def predict_sirna(cancer):
|
| 80 |
+
return pd.DataFrame(SIRNA_DB.get(cancer, []))
|
| 81 |
+
|
| 82 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 83 |
+
# TAB 3 — lncRNA-TREM2 (A3)
|
| 84 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 85 |
+
LNCRNA_DATA = {
|
| 86 |
+
"ceRNA_network": [
|
| 87 |
+
{"lncRNA":"CYTOR","miRNA":"hsa-miR-138-5p","target":"AKT1","pathway":"TREM2 core signaling"},
|
| 88 |
+
{"lncRNA":"CYTOR","miRNA":"hsa-miR-138-5p","target":"NFKB1","pathway":"Neuroinflammation"},
|
| 89 |
+
{"lncRNA":"GAS5","miRNA":"hsa-miR-21-5p","target":"PTEN","pathway":"Neuroinflammation"},
|
| 90 |
+
{"lncRNA":"GAS5","miRNA":"hsa-miR-222-3p","target":"IL1B","pathway":"Neuroinflammation"},
|
| 91 |
+
{"lncRNA":"HOTAIRM1","miRNA":"hsa-miR-9-5p","target":"TREM2","pathway":"Direct TREM2 regulation"},
|
| 92 |
+
],
|
| 93 |
+
"aso_candidates": [
|
| 94 |
+
{"lncRNA":"GAS5","position":119,"accessibility":0.653,"GC_pct":50,"Tm":47.2,"priority":"HIGH"},
|
| 95 |
+
{"lncRNA":"CYTOR","position":507,"accessibility":0.653,"GC_pct":50,"Tm":46.8,"priority":"HIGH"},
|
| 96 |
+
{"lncRNA":"HOTAIRM1","position":234,"accessibility":0.621,"GC_pct":44,"Tm":44.1,"priority":"MEDIUM"},
|
| 97 |
+
{"lncRNA":"LINC00847","position":89,"accessibility":0.598,"GC_pct":56,"Tm":48.3,"priority":"MEDIUM"},
|
| 98 |
+
{"lncRNA":"ZFAS1","position":312,"accessibility":0.571,"GC_pct":48,"Tm":45.5,"priority":"MEDIUM"},
|
| 99 |
+
]
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
def get_lncrna():
|
| 103 |
+
return pd.DataFrame(LNCRNA_DATA["ceRNA_network"]), pd.DataFrame(LNCRNA_DATA["aso_candidates"])
|
| 104 |
+
|
| 105 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 106 |
+
# TAB 4 — FGFR3 RNA Drug (A4)
|
| 107 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 108 |
+
FGFR3_COMPOUNDS = {
|
| 109 |
+
"P1 (hairpin loop)": [
|
| 110 |
+
{"Compound":"CHEMBL1575701","RNA_score":0.809,"Toxicity":0.01,"Final_score":0.793,"MW":342.4,"logP":2.1},
|
| 111 |
+
{"Compound":"CHEMBL15727", "RNA_score":0.805,"Toxicity":0.00,"Final_score":0.789,"MW":298.3,"logP":1.8},
|
| 112 |
+
{"Compound":"Thioguanine", "RNA_score":0.888,"Toxicity":32.5,"Final_score":0.742,"MW":167.2,"logP":-1.2},
|
| 113 |
+
{"Compound":"Deazaguanine", "RNA_score":0.888,"Toxicity":35.0,"Final_score":0.735,"MW":151.2,"logP":-0.9},
|
| 114 |
+
{"Compound":"CHEMBL441", "RNA_score":0.775,"Toxicity":5.2, "Final_score":0.721,"MW":312.4,"logP":2.4},
|
| 115 |
+
],
|
| 116 |
+
"P10 (G-quadruplex)": [
|
| 117 |
+
{"Compound":"CHEMBL15727", "RNA_score":0.805,"Toxicity":0.00,"Final_score":0.789,"MW":298.3,"logP":1.8},
|
| 118 |
+
{"Compound":"CHEMBL5411515","RNA_score":0.945,"Toxicity":37.1,"Final_score":0.761,"MW":415.5,"logP":3.2},
|
| 119 |
+
{"Compound":"CHEMBL90", "RNA_score":0.760,"Toxicity":2.1, "Final_score":0.745,"MW":267.3,"logP":1.5},
|
| 120 |
+
{"Compound":"CHEMBL102", "RNA_score":0.748,"Toxicity":8.4, "Final_score":0.712,"MW":388.4,"logP":2.8},
|
| 121 |
+
{"Compound":"Berberine", "RNA_score":0.735,"Toxicity":3.2, "Final_score":0.708,"MW":336.4,"logP":1.3},
|
| 122 |
+
],
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
def predict_drug(pocket):
|
| 126 |
+
df = pd.DataFrame(FGFR3_COMPOUNDS.get(pocket, []))
|
| 127 |
+
fig, ax = plt.subplots(figsize=(6,4), facecolor=CARD)
|
| 128 |
+
ax.set_facecolor(CARD)
|
| 129 |
+
bars = ax.barh(df["Compound"], df["Final_score"], color=ACC)
|
| 130 |
+
ax.set_xlabel("Final Score", color=TXT)
|
| 131 |
+
ax.tick_params(colors=TXT)
|
| 132 |
+
for spine in ax.spines.values(): spine.set_edgecolor("#334155")
|
| 133 |
+
ax.set_title(f"Top compounds — {pocket}", color=TXT, fontsize=10)
|
| 134 |
+
plt.tight_layout()
|
| 135 |
+
buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close()
|
| 136 |
+
buf.seek(0); return df, Image.open(buf)
|
| 137 |
+
|
| 138 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 139 |
+
# TAB 5 — OpenVariant (A5) ← STAR TOOL
|
| 140 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 141 |
+
VARIANT_DB = {
|
| 142 |
+
"BRCA1:p.R1699Q": {"score":0.03,"class":"Benign","confidence":"High","sift":0.82,"polyphen":0.05,"gnomad":0.0012,"domain":False},
|
| 143 |
+
"BRCA1:p.R1699W": {"score":0.97,"class":"Pathogenic","confidence":"High","sift":0.00,"polyphen":0.99,"gnomad":0.0,"domain":True},
|
| 144 |
+
"BRCA2:p.D2723A": {"score":0.999,"class":"Pathogenic","confidence":"High","sift":0.01,"polyphen":0.98,"gnomad":0.0,"domain":True},
|
| 145 |
+
"TP53:p.R248W": {"score":0.998,"class":"Pathogenic","confidence":"High","sift":0.00,"polyphen":1.00,"gnomad":0.0,"domain":True},
|
| 146 |
+
"TP53:p.R248Q": {"score":0.995,"class":"Pathogenic","confidence":"High","sift":0.01,"polyphen":0.99,"gnomad":0.0,"domain":True},
|
| 147 |
+
"EGFR:p.L858R": {"score":0.96,"class":"Pathogenic","confidence":"High","sift":0.00,"polyphen":0.97,"gnomad":0.0,"domain":True},
|
| 148 |
+
"ALK:p.F1174L": {"score":0.94,"class":"Pathogenic","confidence":"High","sift":0.02,"polyphen":0.95,"gnomad":0.0,"domain":True},
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
PLAIN_LANGUAGE = {
|
| 152 |
+
"Pathogenic": "⚠️ This variant is likely to cause disease. It disrupts a critical protein region. Clinical follow-up is strongly recommended.",
|
| 153 |
+
"Likely Pathogenic": "⚠️ This variant is probably harmful. Evidence suggests it impairs protein function. Discuss with your doctor.",
|
| 154 |
+
"Benign": "✅ This variant is likely harmless. It is common in the general population and does not disrupt protein function.",
|
| 155 |
+
"Likely Benign": "✅ This variant is probably harmless. Limited evidence, but no strong reason for concern.",
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
def predict_variant(hgvs, sift, polyphen, gnomad):
|
| 159 |
+
hgvs = hgvs.strip()
|
| 160 |
+
if hgvs in VARIANT_DB:
|
| 161 |
+
r = VARIANT_DB[hgvs]
|
| 162 |
+
else:
|
| 163 |
+
# Rule-based fallback
|
| 164 |
+
score = 0.0
|
| 165 |
+
if sift < 0.05: score += 0.4
|
| 166 |
+
if polyphen > 0.85: score += 0.35
|
| 167 |
+
if gnomad < 0.0001: score += 0.25
|
| 168 |
+
r = {"score": round(score,3),
|
| 169 |
+
"class": "Pathogenic" if score>0.6 else ("Likely Pathogenic" if score>0.4 else "Benign"),
|
| 170 |
+
"confidence": "High" if (sift<0.01 or sift>0.9) else "Moderate"}
|
| 171 |
+
|
| 172 |
+
cls, conf, score = r["class"], r["confidence"], r["score"]
|
| 173 |
+
colour = "#ef4444" if "Pathogenic" in cls else "#22c55e"
|
| 174 |
+
bar_html = f"""<div style='background:{CARD};padding:16px;border-radius:8px;font-family:monospace;color:{TXT}'>
|
| 175 |
+
<h3 style='color:{colour}'>{cls}</h3>
|
| 176 |
+
<p>Score: <b>{score:.3f}</b> | Confidence: <b>{conf}</b></p>
|
| 177 |
+
<div style='background:#334155;border-radius:4px;height:16px;width:100%'>
|
| 178 |
+
<div style='background:{colour};height:16px;border-radius:4px;width:{int(score*100)}%'></div>
|
| 179 |
+
</div>
|
| 180 |
+
<p style='margin-top:12px'>{PLAIN_LANGUAGE.get(cls,"")}</p>
|
| 181 |
+
</div>"""
|
| 182 |
+
return bar_html
|
| 183 |
+
|
| 184 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 185 |
+
# TAB 6 — LNP Corona ML (B1)
|
| 186 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 187 |
+
def predict_corona(size, zeta, peg, lipid):
|
| 188 |
+
score = 0
|
| 189 |
+
if lipid == "Ionizable": score += 2
|
| 190 |
+
elif lipid == "Cationic": score += 1
|
| 191 |
+
if abs(zeta) < 10: score += 1
|
| 192 |
+
if peg > 1.5: score += 2
|
| 193 |
+
if size < 100: score += 1
|
| 194 |
+
proteins = ["ApoE","Albumin","Fibrinogen","Vitronectin","ApoA-I"]
|
| 195 |
+
dominant = proteins[min(score, 4)]
|
| 196 |
+
efficacy = "High" if score >= 4 else "Medium" if score >= 2 else "Low"
|
| 197 |
+
return f"**Dominant corona protein:** {dominant}
|
| 198 |
+
|
| 199 |
+
**Predicted efficacy class:** {efficacy}
|
| 200 |
+
|
| 201 |
+
**Score:** {score}/6"
|
| 202 |
+
|
| 203 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 204 |
+
# TAB 7 — Cancer Liquid Biopsy (B2)
|
| 205 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 206 |
+
BIOMARKER_WEIGHTS = {"CTHRC1":0.18,"FHL2":0.15,"LDHA":0.14,"P4HA1":0.13,
|
| 207 |
+
"SERPINH1":0.12,"ABCA8":-0.11,"CA4":-0.10,"CKB":-0.09,
|
| 208 |
+
"NNMT":0.08,"CACNA2D2":-0.07}
|
| 209 |
+
|
| 210 |
+
def predict_cancer(cthrc1,fhl2,ldha,p4ha1,serpinh1,abca8,ca4,ckb,nnmt,cacna2d2):
|
| 211 |
+
vals = [cthrc1,fhl2,ldha,p4ha1,serpinh1,abca8,ca4,ckb,nnmt,cacna2d2]
|
| 212 |
+
names = list(BIOMARKER_WEIGHTS.keys())
|
| 213 |
+
weights = list(BIOMARKER_WEIGHTS.values())
|
| 214 |
+
score = sum(v*w for v,w in zip(vals,weights))
|
| 215 |
+
prob = 1/(1+np.exp(-score*2))
|
| 216 |
+
label = "🔴 CANCER" if prob>0.5 else "🟢 HEALTHY"
|
| 217 |
+
conf = abs(prob-0.5)*2
|
| 218 |
+
fig,ax = plt.subplots(figsize=(6,3.5),facecolor=CARD)
|
| 219 |
+
ax.set_facecolor(CARD)
|
| 220 |
+
contribs = [v*w for v,w in zip(vals,weights)]
|
| 221 |
+
colours = [ACC if c>0 else ACC2 for c in contribs]
|
| 222 |
+
ax.barh(names,contribs,color=colours)
|
| 223 |
+
ax.axvline(0,color=TXT,linewidth=0.8)
|
| 224 |
+
ax.set_xlabel("Contribution to cancer score",color=TXT)
|
| 225 |
+
ax.tick_params(colors=TXT,labelsize=8)
|
| 226 |
+
for sp in ax.spines.values(): sp.set_edgecolor("#334155")
|
| 227 |
+
ax.set_title("Protein contributions",color=TXT,fontsize=10)
|
| 228 |
+
plt.tight_layout()
|
| 229 |
+
buf=BytesIO(); plt.savefig(buf,format="png",dpi=120,facecolor=CARD); plt.close()
|
| 230 |
+
buf.seek(0)
|
| 231 |
+
result = f"**{label}**
|
| 232 |
+
|
| 233 |
+
Probability: {prob:.2f} | Confidence: {conf:.2f}"
|
| 234 |
+
return result, Image.open(buf)
|
| 235 |
+
|
| 236 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 237 |
+
# TAB 8 — Corona Flow (B3)
|
| 238 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 239 |
+
def predict_flow(size, zeta, peg, charge, flow_rate):
|
| 240 |
+
csi = (flow_rate/40)*0.6 + (peg/5)*0.2 + (1 if charge=="Cationic" else 0)*0.2
|
| 241 |
+
csi = round(min(csi,1.0),3)
|
| 242 |
+
stability = "🔴 High remodeling" if csi>0.6 else "🟡 Medium" if csi>0.3 else "🟢 Stable"
|
| 243 |
+
t = np.linspace(0,60,200)
|
| 244 |
+
k_fast_s = 0.03*(1+flow_rate/40)
|
| 245 |
+
k_slow_s = 0.005*(1+flow_rate/80)
|
| 246 |
+
alb_static = 60*np.exp(-0.03*t)+20
|
| 247 |
+
alb_flow = 60*np.exp(-k_fast_s*t)+10
|
| 248 |
+
apoe_static = 5*(1-np.exp(-0.005*t))+5
|
| 249 |
+
apoe_flow = 5*(1-np.exp(-k_slow_s*t))+10
|
| 250 |
+
fig,ax = plt.subplots(figsize=(6,3.5),facecolor=CARD)
|
| 251 |
+
ax.set_facecolor(CARD)
|
| 252 |
+
ax.plot(t,alb_static, color="#60a5fa",ls="--",label="Albumin (static)")
|
| 253 |
+
ax.plot(t,alb_flow, color="#60a5fa",label="Albumin (flow)")
|
| 254 |
+
ax.plot(t,apoe_static,color=ACC, ls="--",label="ApoE (static)")
|
| 255 |
+
ax.plot(t,apoe_flow, color=ACC, label="ApoE (flow)")
|
| 256 |
+
ax.set_xlabel("Time (min)",color=TXT); ax.set_ylabel("% Corona",color=TXT)
|
| 257 |
+
ax.tick_params(colors=TXT); ax.legend(fontsize=7,labelcolor=TXT,facecolor=CARD)
|
| 258 |
+
for sp in ax.spines.values(): sp.set_edgecolor("#334155")
|
| 259 |
+
ax.set_title("Vroman Effect: Albumin → ApoE exchange",color=TXT,fontsize=9)
|
| 260 |
+
plt.tight_layout()
|
| 261 |
+
buf=BytesIO(); plt.savefig(buf,format="png",dpi=120,facecolor=CARD); plt.close()
|
| 262 |
+
buf.seek(0)
|
| 263 |
+
return f"**Corona Shift Index: {csi}** → {stability}", Image.open(buf)
|
| 264 |
+
|
| 265 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 266 |
+
# TAB 9 — LNP Brain Delivery (B4)
|
| 267 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 268 |
+
def predict_bbb(smiles, pka, zeta):
|
| 269 |
+
mw = len(smiles)*5 + 200
|
| 270 |
+
logp = smiles.count("C")*0.3 - smiles.count("O")*0.5 + 1.5
|
| 271 |
+
apoe_pct = max(0, min(40, (7.0-pka)*8 + abs(zeta)*0.5 + logp*0.8))
|
| 272 |
+
bbb_prob = min(0.95, apoe_pct/30)
|
| 273 |
+
tier = "🟢 HIGH (>20%)" if apoe_pct>20 else "🟡 MEDIUM (10-20%)" if apoe_pct>10 else "🔴 LOW (<10%)"
|
| 274 |
+
categories=["ApoE %","BBB Prob","logP fit","pKa fit","Zeta fit"]
|
| 275 |
+
vals=[apoe_pct/40, bbb_prob, min(logp/5,1), (7-abs(pka-6.5))/7, (10-abs(zeta))/10]
|
| 276 |
+
fig,ax=plt.subplots(figsize=(5,4),subplot_kw={"polar":True},facecolor=CARD)
|
| 277 |
+
ax.set_facecolor(CARD)
|
| 278 |
+
angles=np.linspace(0,2*np.pi,len(categories),endpoint=False).tolist()
|
| 279 |
+
vals_plot=vals+[vals[0]]; angles=angles+[angles[0]]
|
| 280 |
+
ax.plot(angles,vals_plot,color=ACC,linewidth=2)
|
| 281 |
+
ax.fill(angles,vals_plot,color=ACC,alpha=0.2)
|
| 282 |
+
ax.set_xticks(angles[:-1]); ax.set_xticklabels(categories,color=TXT,fontsize=8)
|
| 283 |
+
ax.tick_params(colors=TXT); ax.set_facecolor(CARD)
|
| 284 |
+
plt.tight_layout()
|
| 285 |
+
buf=BytesIO(); plt.savefig(buf,format="png",dpi=120,facecolor=CARD); plt.close()
|
| 286 |
+
buf.seek(0)
|
| 287 |
+
result = f"**Predicted %ApoE:** {apoe_pct:.1f}% → {tier}
|
| 288 |
+
|
| 289 |
+
**BBB Crossing Probability:** {bbb_prob:.2f}"
|
| 290 |
+
return result, Image.open(buf)
|
| 291 |
+
|
| 292 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 293 |
+
# TAB 10 — AutoCorona NLP (B5)
|
| 294 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 295 |
+
CORONA_PROTEINS = ["albumin","apolipoprotein","fibrinogen","vitronectin","clusterin",
|
| 296 |
+
"igm","iga","igg","complement","transferrin","alpha-2-macroglobulin"]
|
| 297 |
+
|
| 298 |
+
def extract_corona(text):
|
| 299 |
+
result = {"nanoparticle_composition":"","size_nm":None,"zeta_mv":None,
|
| 300 |
+
"PDI":None,"protein_source":"","corona_proteins":[],"confidence":{}}
|
| 301 |
+
size_m = re.search(r"(\d+\.?\d*)\s*(?:nm|nanometer)",text,re.I)
|
| 302 |
+
if size_m: result["size_nm"]=float(size_m.group(1)); result["confidence"]["size_nm"]="HIGH"
|
| 303 |
+
zeta_m = re.search(r"([+-]?\d+\.?\d*)\s*mV",text,re.I)
|
| 304 |
+
if zeta_m: result["zeta_mv"]=float(zeta_m.group(1)); result["confidence"]["zeta_mv"]="HIGH"
|
| 305 |
+
pdi_m = re.search(r"PDI\s*[=:of]*\s*(\d+\.?\d*)",text,re.I)
|
| 306 |
+
if pdi_m: result["PDI"]=float(pdi_m.group(1)); result["confidence"]["PDI"]="HIGH"
|
| 307 |
+
for src in ["human plasma","human serum","fetal bovine serum","FBS","PBS"]:
|
| 308 |
+
if src.lower() in text.lower():
|
| 309 |
+
result["protein_source"]=src; result["confidence"]["protein_source"]="HIGH"; break
|
| 310 |
+
found=[]
|
| 311 |
+
for p in CORONA_PROTEINS:
|
| 312 |
+
if p in text.lower(): found.append({"name":p,"relative_abundance":"detected","confidence":"MEDIUM"})
|
| 313 |
+
result["corona_proteins"]=found
|
| 314 |
+
for lip in ["DSPC","DOPE","MC3","DLin","cholesterol","PEG","DOTAP"]:
|
| 315 |
+
if lip in text: result["nanoparticle_composition"]+=lip+" "
|
| 316 |
+
result["nanoparticle_composition"]=result["nanoparticle_composition"].strip()
|
| 317 |
+
flags=[]
|
| 318 |
+
if not result["size_nm"]: flags.append("⚠️ size_nm not found")
|
| 319 |
+
if not result["zeta_mv"]: flags.append("⚠️ zeta_mv not found")
|
| 320 |
+
if not result["corona_proteins"]: flags.append("⚠️ no corona proteins detected")
|
| 321 |
+
return json.dumps(result,indent=2), "
|
| 322 |
+
".join(flags) if flags else "✅ All key fields extracted"
|
| 323 |
+
|
| 324 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 325 |
+
# BUILD GRADIO APP
|
| 326 |
+
# ══════════════════════════════════════════════════════════════════════════════
|
| 327 |
+
css = f"""
|
| 328 |
+
body, .gradio-container {{ background:{BG} !important; color:{TXT} !important; }}
|
| 329 |
+
.tab-nav button {{ color:{TXT} !important; background:{CARD} !important; }}
|
| 330 |
+
.tab-nav button.selected {{ border-bottom:2px solid {ACC} !important; color:{ACC} !important; }}
|
| 331 |
+
h1,h2,h3 {{ color:{ACC} !important; }}
|
| 332 |
+
.gr-button-primary {{ background:{ACC} !important; border:none !important; }}
|
| 333 |
+
footer {{ display:none !important; }}
|
| 334 |
+
"""
|
| 335 |
+
|
| 336 |
+
header_md = f"""
|
| 337 |
+
# 🧬 K R&D Lab — Computational Biology Suite
|
| 338 |
+
**Oksana Kolisnyk** · ML Engineer @ [FAZENA](https://fazena.org) · [kosatiks-group.pp.ua](https://kosatiks-group.pp.ua)
|
| 339 |
+
[](https://github.com/oksana-kolisnyk/K-RnD-Lab-BIO-2026)
|
| 340 |
+
> 10 open-source computational biology tools in one space. Hypothesis testing across disciplines.
|
| 341 |
+
"""
|
| 342 |
+
|
| 343 |
+
with gr.Blocks(css=css, title="K R&D Lab") as demo:
|
| 344 |
+
gr.Markdown(header_md)
|
| 345 |
+
|
| 346 |
+
with gr.Tabs():
|
| 347 |
+
|
| 348 |
+
# ── TAB 1 ─────────────────────────────────────────────────────────────
|
| 349 |
+
with gr.TabItem("🧬 BRCA2 miRNA"):
|
| 350 |
+
gr.Markdown("### Tumor Suppressor miRNAs in BRCA/TP53-Mutant Breast Cancer
|
| 351 |
+
*Downregulated miRNAs as candidates for miRNA-mimic therapy.*")
|
| 352 |
+
gene_dd = gr.Dropdown(["BRCA2","BRCA1","TP53"], value="BRCA2", label="Select gene")
|
| 353 |
+
run1 = gr.Button("Find miRNAs", variant="primary")
|
| 354 |
+
out1 = gr.Dataframe(label="Top 5 downregulated miRNAs")
|
| 355 |
+
gr.Examples([["BRCA2"],["TP53"]], inputs=[gene_dd])
|
| 356 |
+
run1.click(predict_mirna, gene_dd, out1)
|
| 357 |
+
|
| 358 |
+
# ── TAB 2 ─────────────────────────────────────────────────────────────
|
| 359 |
+
with gr.TabItem("💉 TP53 siRNA"):
|
| 360 |
+
gr.Markdown("### Synthetic Lethal siRNA Targets in TP53-Mutant Cancer
|
| 361 |
+
*DepMap-derived essentiality scores + siRNA sequences.*")
|
| 362 |
+
cancer_dd = gr.Dropdown(["LUAD","BRCA","COAD"], value="LUAD", label="Cancer type")
|
| 363 |
+
run2 = gr.Button("Find Targets", variant="primary")
|
| 364 |
+
out2 = gr.Dataframe(label="Top 5 siRNA targets")
|
| 365 |
+
gr.Examples([["LUAD"],["BRCA"]], inputs=[cancer_dd])
|
| 366 |
+
run2.click(predict_sirna, cancer_dd, out2)
|
| 367 |
+
|
| 368 |
+
# ── TAB 3 ─────────────────────────────────────────────────────────────
|
| 369 |
+
with gr.TabItem("🧠 lncRNA-TREM2"):
|
| 370 |
+
gr.Markdown("### lncRNA Regulatory Networks in TREM2-Dependent Microglial Inflammation
|
| 371 |
+
*Alzheimer's therapy candidates: ceRNA axes & ASO design.*")
|
| 372 |
+
run3 = gr.Button("Load Results", variant="primary")
|
| 373 |
+
out3a = gr.Dataframe(label="ceRNA Network (lncRNA → miRNA → target)")
|
| 374 |
+
out3b = gr.Dataframe(label="ASO Candidates")
|
| 375 |
+
run3.click(get_lncrna, [], [out3a, out3b])
|
| 376 |
+
|
| 377 |
+
# ── TAB 4 ───────────────────────────────��─────────────────────────────
|
| 378 |
+
with gr.TabItem("💊 FGFR3 Drug"):
|
| 379 |
+
gr.Markdown("### RNA-Directed Drug Discovery: FGFR3 mRNA Targeting
|
| 380 |
+
*Small molecules targeting FGFR3 5'UTR pockets for bladder cancer.*")
|
| 381 |
+
pocket_r = gr.Radio(["P1 (hairpin loop)","P10 (G-quadruplex)"], value="P1 (hairpin loop)", label="Target pocket")
|
| 382 |
+
run4 = gr.Button("Screen Compounds", variant="primary")
|
| 383 |
+
out4t = gr.Dataframe(label="Top 5 candidates")
|
| 384 |
+
out4p = gr.Image(label="Binding scores")
|
| 385 |
+
gr.Examples([["P1 (hairpin loop)"],["P10 (G-quadruplex)"]], inputs=[pocket_r])
|
| 386 |
+
run4.click(predict_drug, pocket_r, [out4t, out4p])
|
| 387 |
+
|
| 388 |
+
# ── TAB 5 ─────────────────────────────────────────────────────────────
|
| 389 |
+
with gr.TabItem("🔬 OpenVariant ⭐"):
|
| 390 |
+
gr.Markdown("### OpenVariant — Pathogenicity Classifier
|
| 391 |
+
*Open-source alternative to AlphaMissense. AUC=0.939 on ClinVar 2026.*")
|
| 392 |
+
with gr.Row():
|
| 393 |
+
hgvs_tb = gr.Textbox(label="HGVS notation (e.g. BRCA1:p.R1699Q)", placeholder="BRCA1:p.R1699Q")
|
| 394 |
+
gr.Markdown("**Or enter scores manually:**")
|
| 395 |
+
with gr.Row():
|
| 396 |
+
sift_s = gr.Slider(0,1,0.5,label="SIFT (0=damaging)")
|
| 397 |
+
pp_s = gr.Slider(0,1,0.5,label="PolyPhen-2")
|
| 398 |
+
gn_s = gr.Slider(0,0.01,0.001,label="gnomAD AF",step=0.0001)
|
| 399 |
+
run5 = gr.Button("Predict Pathogenicity", variant="primary")
|
| 400 |
+
out5 = gr.HTML(label="Prediction")
|
| 401 |
+
gr.Examples([["BRCA1:p.R1699Q",0.82,0.05,0.0012],
|
| 402 |
+
["TP53:p.R248W",0.00,1.00,0.0],
|
| 403 |
+
["BRCA2:p.D2723A",0.01,0.98,0.0]],
|
| 404 |
+
inputs=[hgvs_tb,sift_s,pp_s,gn_s])
|
| 405 |
+
run5.click(predict_variant, [hgvs_tb,sift_s,pp_s,gn_s], out5)
|
| 406 |
+
|
| 407 |
+
# ── TAB 6 ─────────────────────────────────────────────────────────────
|
| 408 |
+
with gr.TabItem("🧪 LNP Corona"):
|
| 409 |
+
gr.Markdown("### LNP Protein Corona Prediction
|
| 410 |
+
*Predict dominant corona protein + transfection efficacy from formulation.*")
|
| 411 |
+
with gr.Row():
|
| 412 |
+
sz6 = gr.Slider(50,300,100,label="Size (nm)")
|
| 413 |
+
zt6 = gr.Slider(-40,10,-5,label="Zeta (mV)")
|
| 414 |
+
with gr.Row():
|
| 415 |
+
pg6 = gr.Slider(0,5,1.5,label="PEG mol%")
|
| 416 |
+
lp6 = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Lipid type")
|
| 417 |
+
run6 = gr.Button("Predict", variant="primary")
|
| 418 |
+
out6 = gr.Markdown()
|
| 419 |
+
gr.Examples([[100,-5,1.5,"Ionizable"],[80,5,0.5,"Cationic"]], inputs=[sz6,zt6,pg6,lp6])
|
| 420 |
+
run6.click(predict_corona,[sz6,zt6,pg6,lp6],out6)
|
| 421 |
+
|
| 422 |
+
# ── TAB 7 ─────────────────────────────────────────────────────────────
|
| 423 |
+
with gr.TabItem("🩸 Liquid Biopsy"):
|
| 424 |
+
gr.Markdown("### Protein Corona Cancer Diagnostics
|
| 425 |
+
*Predict cancer vs healthy from plasma protein abundances.*")
|
| 426 |
+
gr.Markdown("Enter normalised protein abundances (z-score, typical range -3 to +3):")
|
| 427 |
+
with gr.Row():
|
| 428 |
+
p1=gr.Slider(-3,3,0,label="CTHRC1"); p2=gr.Slider(-3,3,0,label="FHL2")
|
| 429 |
+
p3=gr.Slider(-3,3,0,label="LDHA"); p4=gr.Slider(-3,3,0,label="P4HA1")
|
| 430 |
+
p5=gr.Slider(-3,3,0,label="SERPINH1")
|
| 431 |
+
with gr.Row():
|
| 432 |
+
p6=gr.Slider(-3,3,0,label="ABCA8"); p7=gr.Slider(-3,3,0,label="CA4")
|
| 433 |
+
p8=gr.Slider(-3,3,0,label="CKB"); p9=gr.Slider(-3,3,0,label="NNMT")
|
| 434 |
+
p10=gr.Slider(-3,3,0,label="CACNA2D2")
|
| 435 |
+
run7=gr.Button("Classify",variant="primary")
|
| 436 |
+
out7t=gr.Markdown(); out7p=gr.Image(label="Feature contributions")
|
| 437 |
+
gr.Examples([[2,2,1.5,1.8,1.6,-1,-1.2,-0.8,1.4,-1.1],
|
| 438 |
+
[0,0,0,0,0,0,0,0,0,0]],
|
| 439 |
+
inputs=[p1,p2,p3,p4,p5,p6,p7,p8,p9,p10])
|
| 440 |
+
run7.click(predict_cancer,[p1,p2,p3,p4,p5,p6,p7,p8,p9,p10],[out7t,out7p])
|
| 441 |
+
|
| 442 |
+
# ── TAB 8 ─────────────────────────────────────────────────────────────
|
| 443 |
+
with gr.TabItem("🌊 Flow Corona"):
|
| 444 |
+
gr.Markdown("### Corona Remodeling Under Blood Flow
|
| 445 |
+
*Predicts how protein corona changes from static incubation to physiological flow.*")
|
| 446 |
+
with gr.Row():
|
| 447 |
+
sz8=gr.Slider(50,300,100,label="Size (nm)"); zt8=gr.Slider(-40,10,-5,label="Zeta (mV)")
|
| 448 |
+
pg8=gr.Slider(0,5,1.5,label="PEG mol%")
|
| 449 |
+
with gr.Row():
|
| 450 |
+
ch8=gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Charge type")
|
| 451 |
+
fl8=gr.Slider(0,40,20,label="Flow rate (cm/s) [aorta=40]")
|
| 452 |
+
run8=gr.Button("Model Vroman Effect",variant="primary")
|
| 453 |
+
out8t=gr.Markdown(); out8p=gr.Image(label="Albumin→ApoE kinetics")
|
| 454 |
+
gr.Examples([[100,-5,1.5,"Ionizable",40],[150,5,0.5,"Cationic",10]],
|
| 455 |
+
inputs=[sz8,zt8,pg8,ch8,fl8])
|
| 456 |
+
run8.click(predict_flow,[sz8,zt8,pg8,ch8,fl8],[out8t,out8p])
|
| 457 |
+
|
| 458 |
+
# ── TAB 9 ─────────────────────────────────────────────────────────────
|
| 459 |
+
with gr.TabItem("🧠 LNP Brain"):
|
| 460 |
+
gr.Markdown("### LNP Brain Delivery Predictor
|
| 461 |
+
*Predicts ApoE corona enrichment and BBB crossing probability for GBM targeting.*")
|
| 462 |
+
smi9=gr.Textbox(label="Ionizable lipid SMILES",
|
| 463 |
+
value="CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C")
|
| 464 |
+
with gr.Row():
|
| 465 |
+
pk9=gr.Slider(4,8,6.5,step=0.1,label="pKa")
|
| 466 |
+
zt9=gr.Slider(-20,10,-3,label="Zeta (mV)")
|
| 467 |
+
run9=gr.Button("Predict BBB Crossing",variant="primary")
|
| 468 |
+
out9t=gr.Markdown(); out9p=gr.Image(label="Lipid profile radar")
|
| 469 |
+
gr.Examples([["CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C",6.5,-3],
|
| 470 |
+
["CCCCCCCC/C=C\CCCCCCCC(=O)OCC(N)CO",5.5,5]],
|
| 471 |
+
inputs=[smi9,pk9,zt9])
|
| 472 |
+
run9.click(predict_bbb,[smi9,pk9,zt9],[out9t,out9p])
|
| 473 |
+
|
| 474 |
+
# ── TAB 10 ────────────────────────────────────────────────────────────
|
| 475 |
+
with gr.TabItem("📚 AutoCorona NLP"):
|
| 476 |
+
gr.Markdown("### AutoCorona — NLP Extraction Pipeline
|
| 477 |
+
*Paste any paper abstract to extract structured LNP corona data automatically.*")
|
| 478 |
+
txt10=gr.Textbox(lines=6, label="Paper abstract or methods text",
|
| 479 |
+
placeholder="Paste text here...")
|
| 480 |
+
run10=gr.Button("Extract Data",variant="primary")
|
| 481 |
+
out10j=gr.Code(label="Extracted JSON",language="json")
|
| 482 |
+
out10f=gr.Textbox(label="Validation flags")
|
| 483 |
+
gr.Examples([
|
| 484 |
+
["LNPs composed of MC3, DSPC, Cholesterol (50:10:40 mol%) with 1.5% PEG-DMG were prepared by microfluidics. Hydrodynamic diameter was 98 ± 12 nm, zeta potential -3.2 mV, PDI 0.12. LNPs were incubated in human plasma for 60 min. Corona proteins identified by LC-MS/MS included albumin, apolipoprotein E, fibrinogen, and vitronectin."],
|
| 485 |
+
["Cationic liposomes (DOTAP:DOPE 1:1) with size 150 nm and zeta +25 mV were incubated in fetal bovine serum. IgG, complement C3, and albumin were the dominant corona proteins."]
|
| 486 |
+
], inputs=[txt10])
|
| 487 |
+
run10.click(extract_corona,txt10,[out10j,out10f])
|
| 488 |
+
|
| 489 |
+
gr.Markdown("""---
|
| 490 |
+
**K R&D Lab** · Open-source computational biology research
|
| 491 |
+
Data is research-grade, not clinical. All models are experimental.
|
| 492 |
+
[GitHub](https://github.com/oksana-kolisnyk/K-RnD-Lab-BIO-2026) | [fazena.org](https://fazena.org) | [kosatiks-group.pp.ua](https://kosatiks-group.pp.ua)
|
| 493 |
+
""")
|
| 494 |
+
|
| 495 |
+
if __name__ == "__main__":
|
| 496 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=4.0.0
|
| 2 |
+
pandas>=2.0.0
|
| 3 |
+
numpy>=1.24.0
|
| 4 |
+
matplotlib>=3.7.0
|
| 5 |
+
Pillow>=10.0.0
|