TEZv commited on
Commit
95d174d
·
verified ·
1 Parent(s): 80b55c7

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +496 -0
  2. 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> &nbsp;|&nbsp; 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
+ [![GitHub](https://img.shields.io/badge/GitHub-K--RnD--Lab--BIO--2026-orange)](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