TEZv commited on
Commit
f5c64e5
·
verified ·
1 Parent(s): 65be990

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -1015
app.py CHANGED
@@ -9,1021 +9,25 @@ from io import BytesIO
9
  from PIL import Image
10
  from datetime import datetime
11
  from pathlib import Path
12
- import os
13
 
14
- # Вимкнення телеметрії Gradio (щоб уникнути непотрібних запитів)
15
- os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- # Кольори (ваші)
18
- BG = "#0f172a"
19
- CARD = "#1e293b"
20
- ACC = "#f97316"
21
- ACC2 = "#38bdf8"
22
- TXT = "#f1f5f9"
23
- GRN = "#22c55e"
24
- RED = "#ef4444"
25
- DIM = "#8e9bae"
26
- BORDER = "#334155"
27
-
28
- LOG_PATH = Path("/tmp/lab_journal.csv")
29
-
30
- # ---------- Логування ----------
31
- def log_entry(tab, inputs, result, note=""):
32
- try:
33
- write_header = not LOG_PATH.exists()
34
- with open(LOG_PATH, "a", newline="", encoding="utf-8") as f:
35
- w = csv.DictWriter(f, fieldnames=["timestamp","tab","inputs","result","note"])
36
- if write_header: w.writeheader()
37
- w.writerow({"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M"),
38
- "tab": tab, "inputs": str(inputs),
39
- "result": str(result)[:200], "note": note})
40
- except Exception: pass
41
-
42
- def load_journal():
43
- try:
44
- if not LOG_PATH.exists():
45
- return pd.DataFrame(columns=["timestamp","tab","inputs","result","note"])
46
- return pd.read_csv(LOG_PATH)
47
- except Exception:
48
- return pd.DataFrame(columns=["timestamp","tab","inputs","result","note"])
49
-
50
- def save_note(note, tab, last_result):
51
- log_entry(tab, "", last_result, note)
52
- return "✅ Saved!", load_journal()
53
-
54
- # ---------- Бази даних (ваші) ----------
55
- MIRNA_DB = {
56
- "BRCA2": [
57
- {"miRNA":"hsa-miR-148a-3p","log2FC":-0.70,"padj":0.013,"targets":"DNMT1, AKT2","pathway":"Epigenetic reprogramming"},
58
- {"miRNA":"hsa-miR-30e-5p","log2FC":-0.49,"padj":0.032,"targets":"MYC, KRAS","pathway":"Oncogene suppression"},
59
- {"miRNA":"hsa-miR-551b-3p","log2FC":-0.59,"padj":0.048,"targets":"SMAD4, CDK6","pathway":"TGF-beta / CDK4/6"},
60
- {"miRNA":"hsa-miR-22-3p","log2FC":-0.43,"padj":0.041,"targets":"HIF1A, PTEN","pathway":"Hypoxia / PI3K"},
61
- {"miRNA":"hsa-miR-200c-3p","log2FC":-0.38,"padj":0.044,"targets":"ZEB1, ZEB2","pathway":"EMT suppression"},
62
- ],
63
- "BRCA1": [
64
- {"miRNA":"hsa-miR-155-5p","log2FC":-0.81,"padj":0.008,"targets":"SHIP1, SOCS1","pathway":"Immune evasion"},
65
- {"miRNA":"hsa-miR-146a-5p","log2FC":-0.65,"padj":0.019,"targets":"TRAF6, IRAK1","pathway":"NF-kB signalling"},
66
- {"miRNA":"hsa-miR-21-5p","log2FC":-0.55,"padj":0.027,"targets":"PTEN, PDCD4","pathway":"Apoptosis"},
67
- {"miRNA":"hsa-miR-17-5p","log2FC":-0.47,"padj":0.036,"targets":"RB1, E2F1","pathway":"Cell cycle"},
68
- {"miRNA":"hsa-miR-34a-5p","log2FC":-0.41,"padj":0.049,"targets":"BCL2, CDK6","pathway":"p53 axis"},
69
- ],
70
- "TP53": [
71
- {"miRNA":"hsa-miR-34a-5p","log2FC":-1.10,"padj":0.001,"targets":"BCL2, CDK6","pathway":"p53-miR-34 axis"},
72
- {"miRNA":"hsa-miR-192-5p","log2FC":-0.90,"padj":0.005,"targets":"MDM2, DHFR","pathway":"p53 feedback"},
73
- {"miRNA":"hsa-miR-145-5p","log2FC":-0.75,"padj":0.012,"targets":"MYC, EGFR","pathway":"Growth suppression"},
74
- {"miRNA":"hsa-miR-107","log2FC":-0.62,"padj":0.023,"targets":"CDK6, HIF1B","pathway":"Hypoxia / cell cycle"},
75
- {"miRNA":"hsa-miR-215-5p","log2FC":-0.51,"padj":0.038,"targets":"DTL, DHFR","pathway":"DNA damage response"},
76
- ],
77
- }
78
-
79
- SIRNA_DB = {
80
- "LUAD": [
81
- {"Gene":"SPC24","dCERES":-0.175,"log2FC":1.13,"Drug_status":"Novel","siRNA":"GCAGCUGAAGAAACUGAAU"},
82
- {"Gene":"BUB1B","dCERES":-0.119,"log2FC":1.12,"Drug_status":"Novel","siRNA":"CCAAAGAGCUGAAGAACAU"},
83
- {"Gene":"CDC45","dCERES":-0.144,"log2FC":1.26,"Drug_status":"Novel","siRNA":"GCAUCAAGAUGAAGGAGAU"},
84
- {"Gene":"PLK1","dCERES":-0.239,"log2FC":1.03,"Drug_status":"Clinical","siRNA":"GACGCUCAAGAUGCAGAUU"},
85
- {"Gene":"CDK1","dCERES":-0.201,"log2FC":1.00,"Drug_status":"Clinical","siRNA":"GCAGAAGCACUGAAGAUUU"},
86
- ],
87
- "BRCA": [
88
- {"Gene":"AURKA","dCERES":-0.165,"log2FC":1.20,"Drug_status":"Clinical","siRNA":"GCACUGAAGAUGCAGAAUU"},
89
- {"Gene":"AURKB","dCERES":-0.140,"log2FC":1.15,"Drug_status":"Clinical","siRNA":"CCUGAAGACGCUCAAGGUU"},
90
- {"Gene":"CENPW","dCERES":-0.125,"log2FC":0.95,"Drug_status":"Novel","siRNA":"GCAGAAGCACUGAAGAUUU"},
91
- {"Gene":"RFC2","dCERES":-0.136,"log2FC":0.50,"Drug_status":"Novel","siRNA":"GCAAGAUGCAGAAGCACUU"},
92
- {"Gene":"TYMS","dCERES":-0.131,"log2FC":0.72,"Drug_status":"Approved","siRNA":"GGACGCUCAAGAUGCAGAU"},
93
- ],
94
- "COAD": [
95
- {"Gene":"KRAS","dCERES":-0.210,"log2FC":0.80,"Drug_status":"Clinical","siRNA":"GCUGGAGCUGGUGGUAGUU"},
96
- {"Gene":"WEE1","dCERES":-0.180,"log2FC":1.05,"Drug_status":"Clinical","siRNA":"GCAGCUGAAGAAACUGAAU"},
97
- {"Gene":"CHEK1","dCERES":-0.155,"log2FC":0.90,"Drug_status":"Clinical","siRNA":"CCAAAGAGCUGAAGAACAU"},
98
- {"Gene":"RFC2","dCERES":-0.130,"log2FC":0.55,"Drug_status":"Novel","siRNA":"GCAUCAAGAUGAAGGAGAU"},
99
- {"Gene":"PKMYT1","dCERES":-0.122,"log2FC":1.07,"Drug_status":"Clinical","siRNA":"GACGCUCAAGAUGCAGAUU"},
100
- ],
101
- }
102
-
103
- CERNA = [
104
- {"lncRNA":"CYTOR","miRNA":"hsa-miR-138-5p","target":"AKT1","pathway":"TREM2 core signaling"},
105
- {"lncRNA":"CYTOR","miRNA":"hsa-miR-138-5p","target":"NFKB1","pathway":"Neuroinflammation"},
106
- {"lncRNA":"GAS5","miRNA":"hsa-miR-21-5p","target":"PTEN","pathway":"Neuroinflammation"},
107
- {"lncRNA":"GAS5","miRNA":"hsa-miR-222-3p","target":"IL1B","pathway":"Neuroinflammation"},
108
- {"lncRNA":"HOTAIRM1","miRNA":"hsa-miR-9-5p","target":"TREM2","pathway":"Direct TREM2 regulation"},
109
- ]
110
-
111
- ASO = [
112
- {"lncRNA":"GAS5","position":119,"accessibility":0.653,"GC_pct":50,"Tm":47.2,"priority":"HIGH"},
113
- {"lncRNA":"CYTOR","position":507,"accessibility":0.653,"GC_pct":50,"Tm":46.8,"priority":"HIGH"},
114
- {"lncRNA":"HOTAIRM1","position":234,"accessibility":0.621,"GC_pct":44,"Tm":44.1,"priority":"MEDIUM"},
115
- {"lncRNA":"LINC00847","position":89,"accessibility":0.598,"GC_pct":56,"Tm":48.3,"priority":"MEDIUM"},
116
- {"lncRNA":"ZFAS1","position":312,"accessibility":0.571,"GC_pct":48,"Tm":45.5,"priority":"MEDIUM"},
117
- ]
118
-
119
- FGFR3 = {
120
- "P1 (hairpin loop)": [
121
- {"Compound":"CHEMBL1575701","RNA_score":0.809,"Toxicity":0.01,"Final_score":0.793},
122
- {"Compound":"CHEMBL15727","RNA_score":0.805,"Toxicity":0.00,"Final_score":0.789},
123
- {"Compound":"Thioguanine","RNA_score":0.888,"Toxicity":32.5,"Final_score":0.742},
124
- {"Compound":"Deazaguanine","RNA_score":0.888,"Toxicity":35.0,"Final_score":0.735},
125
- {"Compound":"CHEMBL441","RNA_score":0.775,"Toxicity":5.2,"Final_score":0.721},
126
- ],
127
- "P10 (G-quadruplex)": [
128
- {"Compound":"CHEMBL15727","RNA_score":0.805,"Toxicity":0.00,"Final_score":0.789},
129
- {"Compound":"CHEMBL5411515","RNA_score":0.945,"Toxicity":37.1,"Final_score":0.761},
130
- {"Compound":"CHEMBL90","RNA_score":0.760,"Toxicity":2.1,"Final_score":0.745},
131
- {"Compound":"CHEMBL102","RNA_score":0.748,"Toxicity":8.4,"Final_score":0.712},
132
- {"Compound":"Berberine","RNA_score":0.735,"Toxicity":3.2,"Final_score":0.708},
133
- ],
134
- }
135
-
136
- VARIANT_DB = {
137
- "BRCA1:p.R1699Q": {"score":0.03,"cls":"Benign","conf":"High"},
138
- "BRCA1:p.R1699W": {"score":0.97,"cls":"Pathogenic","conf":"High"},
139
- "BRCA2:p.D2723A": {"score":0.999,"cls":"Pathogenic","conf":"High"},
140
- "TP53:p.R248W": {"score":0.998,"cls":"Pathogenic","conf":"High"},
141
- "TP53:p.R248Q": {"score":0.995,"cls":"Pathogenic","conf":"High"},
142
- "EGFR:p.L858R": {"score":0.96,"cls":"Pathogenic","conf":"High"},
143
- "ALK:p.F1174L": {"score":0.94,"cls":"Pathogenic","conf":"High"},
144
- }
145
-
146
- PLAIN = {
147
- "Pathogenic": "This variant is likely to cause disease. Clinical follow-up is strongly recommended.",
148
- "Likely Pathogenic": "This variant is probably harmful. Discuss with your doctor.",
149
- "Benign": "This variant is likely harmless. Common in the general population.",
150
- "Likely Benign": "This variant is probably harmless. No strong reason for concern.",
151
- }
152
-
153
- BM_W = {
154
- "CTHRC1":0.18,"FHL2":0.15,"LDHA":0.14,"P4HA1":0.13,
155
- "SERPINH1":0.12,"ABCA8":-0.11,"CA4":-0.10,"CKB":-0.09,
156
- "NNMT":0.08,"CACNA2D2":-0.07
157
- }
158
-
159
- PROTEINS = ["albumin","apolipoprotein","fibrinogen","vitronectin",
160
- "clusterin","igm","iga","igg","complement","transferrin",
161
- "alpha-2-macroglobulin"]
162
-
163
- # ---------- Дані для рідкісних раків ----------
164
- DIPG_VARIANTS = [
165
- {"Variant":"H3K27M (H3F3A)","Freq_pct":78,"Pathway":"PRC2 inhibition → global H3K27me3 loss","Drug_status":"ONC201 (clinical)","Circadian_gene":"BMAL1 suppressed"},
166
- {"Variant":"ACVR1 p.R206H","Freq_pct":21,"Pathway":"BMP/SMAD hyperactivation","Drug_status":"LDN-193189 (preclinical)","Circadian_gene":"PER1 disrupted"},
167
- {"Variant":"PIK3CA p.H1047R","Freq_pct":15,"Pathway":"PI3K/AKT/mTOR","Drug_status":"Copanlisib (clinical)","Circadian_gene":"CRY1 altered"},
168
- {"Variant":"TP53 p.R248W","Freq_pct":14,"Pathway":"DNA damage response loss","Drug_status":"APR-246 (clinical)","Circadian_gene":"p53-CLOCK axis"},
169
- {"Variant":"PDGFRA amp","Freq_pct":13,"Pathway":"RTK/RAS signalling","Drug_status":"Avapritinib (clinical)","Circadian_gene":"REV-ERB altered"},
170
- ]
171
-
172
- DIPG_CSF_LNP = [
173
- {"Formulation":"MC3-DSPC-Chol-PEG","Size_nm":92,"Zeta_mV":-4.1,"CSF_protein":"Beta2-microglobulin","ApoE_pct":12.4,"BBB_est":0.41,"Priority":"HIGH"},
174
- {"Formulation":"DLin-KC2-DSPE-PEG","Size_nm":87,"Zeta_mV":-3.8,"CSF_protein":"Cystatin C","ApoE_pct":14.1,"BBB_est":0.47,"Priority":"HIGH"},
175
- {"Formulation":"C12-200-DOPE-PEG","Size_nm":103,"Zeta_mV":-5.2,"CSF_protein":"Albumin (low)","ApoE_pct":9.8,"BBB_est":0.33,"Priority":"MEDIUM"},
176
- {"Formulation":"DODAP-DSPC-Chol","Size_nm":118,"Zeta_mV":-2.1,"CSF_protein":"Transferrin","ApoE_pct":7.2,"BBB_est":0.24,"Priority":"LOW"},
177
- ]
178
-
179
- UVM_VARIANTS = [
180
- {"Variant":"GNAQ p.Q209L","Freq_pct":46,"Pathway":"PLCβ → PKC → MAPK","Drug_status":"Darovasertib (clinical)","m6A_writer":"METTL3 upregulated"},
181
- {"Variant":"GNA11 p.Q209L","Freq_pct":32,"Pathway":"PLCβ → PKC → MAPK","Drug_status":"Darovasertib (clinical)","m6A_writer":"WTAP upregulated"},
182
- {"Variant":"BAP1 loss","Freq_pct":47,"Pathway":"Chromatin remodeling → metastasis","Drug_status":"No approved (HDAC trials)","m6A_writer":"FTO overexpressed"},
183
- {"Variant":"SF3B1 p.R625H","Freq_pct":19,"Pathway":"Splicing alteration → neoepitopes","Drug_status":"H3B-8800 (clinical)","m6A_writer":"METTL14 altered"},
184
- {"Variant":"EIF1AX p.A113_splice","Freq_pct":14,"Pathway":"Translation initiation","Drug_status":"Novel — no drug","m6A_writer":"YTHDF2 suppressed"},
185
- ]
186
-
187
- UVM_VITREOUS_LNP = [
188
- {"Formulation":"SM-102-DSPC-Chol-PEG","Vitreal_protein":"Hyaluronan-binding","Size_nm":95,"Zeta_mV":-3.2,"Retention_h":18,"Priority":"HIGH"},
189
- {"Formulation":"Lipid-H-DOPE-PEG","Vitreal_protein":"Vitronectin dominant","Size_nm":88,"Zeta_mV":-4.0,"Retention_h":22,"Priority":"HIGH"},
190
- {"Formulation":"DOTAP-DSPC-PEG","Vitreal_protein":"Albumin wash-out","Size_nm":112,"Zeta_mV":+2.1,"Retention_h":6,"Priority":"LOW"},
191
- {"Formulation":"MC3-DPPC-Chol","Vitreal_protein":"Clusterin-rich","Size_nm":101,"Zeta_mV":-2.8,"Retention_h":14,"Priority":"MEDIUM"},
192
- ]
193
-
194
- PAML_VARIANTS = [
195
- {"Variant":"FLT3-ITD","Freq_pct":25,"Pathway":"RTK constitutive activation → JAK/STAT","Drug_status":"Midostaurin (approved)","Ferroptosis":"GPX4 suppressed"},
196
- {"Variant":"NPM1 c.860_863dupTCAG","Freq_pct":30,"Pathway":"Nuclear export deregulation","Drug_status":"APR-548 combo (clinical)","Ferroptosis":"SLC7A11 upregulated"},
197
- {"Variant":"DNMT3A p.R882H","Freq_pct":18,"Pathway":"Epigenetic dysregulation","Drug_status":"Azacitidine (approved)","Ferroptosis":"ACSL4 altered"},
198
- {"Variant":"CEBPA biallelic","Freq_pct":8,"Pathway":"Myeloid differentiation block","Drug_status":"Novel target","Ferroptosis":"NRF2 pathway"},
199
- {"Variant":"IDH1/2 mutation","Freq_pct":15,"Pathway":"2-HG oncometabolite → TET2 inhibition","Drug_status":"Enasidenib (approved)","Ferroptosis":"Iron metabolism disrupted"},
200
- ]
201
-
202
- PAML_BM_LNP = [
203
- {"Formulation":"ALC-0315-DSPC-Chol-PEG","BM_protein":"ApoE + Clusterin","Size_nm":98,"Zeta_mV":-3.5,"Marrow_uptake_pct":34,"Priority":"HIGH"},
204
- {"Formulation":"MC3-DOPE-Chol-PEG","BM_protein":"Fibronectin dominant","Size_nm":105,"Zeta_mV":-4.2,"Marrow_uptake_pct":28,"Priority":"HIGH"},
205
- {"Formulation":"DLin-MC3-DPPC","BM_protein":"Vitronectin-rich","Size_nm":91,"Zeta_mV":-2.9,"Marrow_uptake_pct":19,"Priority":"MEDIUM"},
206
- {"Formulation":"Cationic-DOTAP-Chol","BM_protein":"Opsonin-heavy","Size_nm":132,"Zeta_mV":+8.1,"Marrow_uptake_pct":8,"Priority":"LOW"},
207
- ]
208
-
209
- # ---------- Функції логіки (ваші, без змін) ----------
210
- def predict_mirna(gene):
211
- df = pd.DataFrame(MIRNA_DB.get(gene, []))
212
- log_entry("S1-B | S1-R2 | miRNA", gene, f"{len(df)} miRNAs")
213
- return df
214
-
215
- def predict_sirna(cancer):
216
- df = pd.DataFrame(SIRNA_DB.get(cancer, []))
217
- log_entry("S1-B | S1-R3 | siRNA", cancer, f"{len(df)} targets")
218
- return df
219
-
220
- def get_lncrna():
221
- log_entry("S1-B | S1-R4 | lncRNA", "load", "ceRNA+ASO")
222
- return pd.DataFrame(CERNA), pd.DataFrame(ASO)
223
-
224
- def predict_drug(pocket):
225
- df = pd.DataFrame(FGFR3.get(pocket, []))
226
- fig, ax = plt.subplots(figsize=(6, 4), facecolor=CARD)
227
- ax.set_facecolor(CARD)
228
- ax.barh(df["Compound"], df["Final_score"], color=ACC)
229
- ax.set_xlabel("Final Score", color=TXT); ax.tick_params(colors=TXT)
230
- for sp in ax.spines.values(): sp.set_edgecolor(BORDER)
231
- ax.set_title(f"Top compounds — {pocket}", color=TXT, fontsize=10)
232
- plt.tight_layout()
233
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
234
- log_entry("S1-C | S1-R5 | Drug", pocket, f"Top: {df.iloc[0]['Compound'] if len(df) else 'none'}")
235
- return df, Image.open(buf)
236
-
237
- def predict_variant(hgvs, sift, polyphen, gnomad):
238
- hgvs = hgvs.strip()
239
- if hgvs in VARIANT_DB:
240
- r = VARIANT_DB[hgvs]; cls, conf, score = r["cls"], r["conf"], r["score"]
241
- else:
242
- score = 0.0
243
- if sift < 0.05: score += 0.4
244
- if polyphen > 0.85: score += 0.35
245
- if gnomad < 0.0001: score += 0.25
246
- score = round(score, 3)
247
- cls = "Pathogenic" if score > 0.6 else "Likely Pathogenic" if score > 0.4 else "Benign"
248
- conf = "High" if (sift < 0.01 or sift > 0.9) else "Moderate"
249
- colour = RED if "Pathogenic" in cls else GRN
250
- icon = "⚠️ WARNING" if "Pathogenic" in cls else "✅ OK"
251
- log_entry("S1-A | S1-R1 | OpenVariant", hgvs or f"SIFT={sift}", f"{cls} score={score}")
252
- return (
253
- f"<div style=\'background:{CARD};padding:16px;border-radius:8px;font-family:sans-serif;color:{TXT}\'>"
254
- f"<p style=\'font-size:11px;color:{DIM};margin:0 0 8px\'>S1-A · PHYLO-GENOMICS · S1-R1</p>"
255
- f"<h3 style=\'color:{colour};margin:0 0 8px\'>{icon} {cls}</h3>"
256
- f"<p>Score: <b>{score:.3f}</b> &nbsp;|&nbsp; Confidence: <b>{conf}</b></p>"
257
- f"<div style=\'background:{BORDER};border-radius:4px;height:14px\'>"
258
- f"<div style=\'background:{colour};height:14px;border-radius:4px;width:{int(score*100)}%\'></div></div>"
259
- f"<p style=\'margin-top:12px\'>{PLAIN.get(cls,'')}</p>"
260
- f"<p style=\'font-size:11px;color:{DIM}\'>Research only. Not clinical advice.</p></div>"
261
- )
262
-
263
- def predict_corona(size, zeta, peg, lipid):
264
- score = 0
265
- if lipid == "Ionizable": score += 2
266
- elif lipid == "Cationic": score += 1
267
- if abs(zeta) < 10: score += 1
268
- if peg > 1.5: score += 2
269
- if size < 100: score += 1
270
- dominant = ["ApoE","Albumin","Fibrinogen","Vitronectin","ApoA-I"][min(score, 4)]
271
- efficacy = "High" if score >= 4 else "Medium" if score >= 2 else "Low"
272
- log_entry("S1-D | S1-R6 | Corona", f"size={size},peg={peg}", f"dominant={dominant}")
273
- return f"**Dominant corona protein:** {dominant}\n\n**Predicted efficacy:** {efficacy}\n\n**Score:** {score}/6"
274
-
275
- def predict_cancer(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10):
276
- vals = [c1,c2,c3,c4,c5,c6,c7,c8,c9,c10]
277
- names, weights = list(BM_W.keys()), list(BM_W.values())
278
- raw = sum(v*w for v,w in zip(vals, weights))
279
- prob = 1 / (1 + np.exp(-raw * 2))
280
- label = "CANCER" if prob > 0.5 else "HEALTHY"
281
- colour = RED if prob > 0.5 else GRN
282
- contribs = [v*w for v,w in zip(vals, weights)]
283
- fig, ax = plt.subplots(figsize=(6, 3.5), facecolor=CARD)
284
- ax.set_facecolor(CARD)
285
- ax.barh(names, contribs, color=[ACC if c > 0 else ACC2 for c in contribs])
286
- ax.axvline(0, color=TXT, linewidth=0.8)
287
- ax.set_xlabel("Contribution to cancer score", color=TXT)
288
- ax.tick_params(colors=TXT, labelsize=8)
289
- for sp in ax.spines.values(): sp.set_edgecolor(BORDER)
290
- ax.set_title("Protein contributions", color=TXT, fontsize=10)
291
- plt.tight_layout()
292
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
293
- log_entry("S1-E | S1-R9 | LiquidBiopsy", f"CTHRC1={c1},FHL2={c2}", f"{label} {prob:.2f}")
294
- return (
295
- f"<div style=\'background:{CARD};padding:14px;border-radius:8px;font-family:sans-serif;\'>"
296
- f"<p style=\'font-size:11px;color:{DIM};margin:0 0 6px\'>S1-E · PHYLO-BIOMARKERS · S1-R9</p>"
297
- f"<span style=\'color:{colour};font-size:24px;font-weight:bold\'>{label}</span><br>"
298
- f"<span style=\'color:{TXT};font-size:14px\'>Probability: {prob:.2f}</span></div>"
299
- ), Image.open(buf)
300
-
301
- def predict_flow(size, zeta, peg, charge, flow_rate):
302
- csi = round(min((flow_rate/40)*0.6 + (peg/5)*0.2 + (1 if charge=="Cationic" else 0)*0.2, 1.0), 3)
303
- stability = "High remodeling" if csi > 0.6 else "Medium" if csi > 0.3 else "Stable"
304
- t = np.linspace(0, 60, 200)
305
- kf, ks = 0.03*(1+flow_rate/40), 0.038*(1+flow_rate/40)
306
- fig, ax = plt.subplots(figsize=(6, 3.5), facecolor=CARD)
307
- ax.set_facecolor(CARD)
308
- ax.plot(t, 60*np.exp(-0.03*t)+20, color="#60a5fa", ls="--", label="Albumin (static)")
309
- ax.plot(t, 60*np.exp(-kf*t)+10, color="#60a5fa", label="Albumin (flow)")
310
- ax.plot(t, 14*(1-np.exp(-0.038*t))+5, color=ACC, ls="--", label="ApoE (static)")
311
- ax.plot(t, 20*(1-np.exp(-ks*t))+5, color=ACC, label="ApoE (flow)")
312
- ax.set_xlabel("Time (min)", color=TXT); ax.set_ylabel("% Corona", color=TXT)
313
- ax.tick_params(colors=TXT); ax.legend(fontsize=7, labelcolor=TXT, facecolor=CARD)
314
- for sp in ax.spines.values(): sp.set_edgecolor(BORDER)
315
- ax.set_title("Vroman Effect — flow vs static", color=TXT, fontsize=9)
316
- plt.tight_layout()
317
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
318
- log_entry("S1-D | S1-R7 | FlowCorona", f"flow={flow_rate}", f"CSI={csi}")
319
- return f"**Corona Shift Index: {csi}** — {stability}", Image.open(buf)
320
-
321
- def predict_bbb(smiles, pka, zeta):
322
- logp = smiles.count("C")*0.3 - smiles.count("O")*0.5 + 1.5
323
- apoe_pct = max(0, min(40, (7.0-pka)*8 + abs(zeta)*0.5 + logp*0.8))
324
- bbb_prob = min(0.95, apoe_pct/30)
325
- tier = "HIGH (>20%)" if apoe_pct > 20 else "MEDIUM (10-20%)" if apoe_pct > 10 else "LOW (<10%)"
326
- cats = ["ApoE%","BBB","logP","pKa fit","Zeta"]
327
- vals = [apoe_pct/40, bbb_prob, min(logp/5,1), (7-abs(pka-6.5))/7, (10-abs(zeta))/10]
328
- angles = np.linspace(0, 2*np.pi, len(cats), endpoint=False).tolist()
329
- v2, a2 = vals+[vals[0]], angles+[angles[0]]
330
- fig, ax = plt.subplots(figsize=(5, 4), subplot_kw={"polar":True}, facecolor=CARD)
331
- ax.set_facecolor(CARD)
332
- ax.plot(a2, v2, color=ACC, linewidth=2); ax.fill(a2, v2, color=ACC, alpha=0.2)
333
- ax.set_xticks(angles); ax.set_xticklabels(cats, color=TXT, fontsize=8)
334
- ax.tick_params(colors=TXT)
335
- plt.tight_layout()
336
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
337
- log_entry("S1-D | S1-R8 | LNPBrain", f"pka={pka},zeta={zeta}", f"ApoE={apoe_pct:.1f}%")
338
- return f"**Predicted ApoE:** {apoe_pct:.1f}% — {tier}\n\n**BBB Probability:** {bbb_prob:.2f}", Image.open(buf)
339
-
340
- def extract_corona(text):
341
- out = {"nanoparticle_composition":"","size_nm":None,"zeta_mv":None,"PDI":None,
342
- "protein_source":"","corona_proteins":[],"confidence":{}}
343
- for pat, key in [(r"(\d+\.?\d*)\s*(?:nm|nanometer)","size_nm"),
344
- (r"([+-]?\d+\.?\d*)\s*mV","zeta_mv"),
345
- (r"PDI\s*[=:of]*\s*(\d+\.?\d*)","PDI")]:
346
- m = re.search(pat, text, re.I)
347
- if m: out[key] = float(m.group(1)); out["confidence"][key] = "HIGH"
348
- for src in ["human plasma","human serum","fetal bovine serum","FBS","PBS"]:
349
- if src.lower() in text.lower():
350
- out["protein_source"] = src; out["confidence"]["protein_source"] = "HIGH"; break
351
- out["corona_proteins"] = [{"name":p,"confidence":"MEDIUM"} for p in PROTEINS if p in text.lower()]
352
- for lip in ["DSPC","DOPE","MC3","DLin","cholesterol","PEG","DOTAP"]:
353
- if lip in text: out["nanoparticle_composition"] += lip + " "
354
- out["nanoparticle_composition"] = out["nanoparticle_composition"].strip()
355
- flags = []
356
- if not out["size_nm"]: flags.append("size_nm not found")
357
- if not out["zeta_mv"]: flags.append("zeta_mv not found")
358
- if not out["corona_proteins"]: flags.append("no proteins detected")
359
- summary = "All key fields extracted" if not flags else " | ".join(flags)
360
- log_entry("S1-D | S1-R10 | NLP", text[:80], f"proteins={len(out['corona_proteins'])}")
361
- return json.dumps(out, indent=2), summary
362
-
363
- # ---------- Функції для рідкісних раків ----------
364
- def dipg_variants(sort_by):
365
- df = pd.DataFrame(DIPG_VARIANTS).sort_values(
366
- "Freq_pct" if sort_by == "Frequency" else "Drug_status", ascending=False)
367
- log_entry("S1-F | S1-R12b | DIPG-variants", sort_by, f"{len(df)} variants")
368
- return df
369
-
370
- def dipg_csf(peg, size):
371
- df = pd.DataFrame(DIPG_CSF_LNP)
372
- df["Score"] = df["ApoE_pct"]/40 + df["BBB_est"] - abs(df["Size_nm"]-size)/200
373
- df = df.sort_values("Score", ascending=False)
374
- fig, ax = plt.subplots(figsize=(6, 3), facecolor=CARD)
375
- ax.set_facecolor(CARD)
376
- colors = [GRN if p=="HIGH" else ACC if p=="MEDIUM" else RED for p in df["Priority"]]
377
- ax.barh(df["Formulation"], df["ApoE_pct"], color=colors)
378
- ax.set_xlabel("ApoE% in CSF corona", color=TXT)
379
- ax.tick_params(colors=TXT, labelsize=8)
380
- for sp in ax.spines.values(): sp.set_edgecolor(BORDER)
381
- ax.set_title("DIPG — CSF LNP formulations (ApoE%)", color=TXT, fontsize=9)
382
- plt.tight_layout()
383
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
384
- log_entry("S1-F | S1-R12b | DIPG-CSF", f"peg={peg},size={size}", "formulation ranking")
385
- return df[["Formulation","Size_nm","Zeta_mV","ApoE_pct","BBB_est","Priority"]], Image.open(buf)
386
-
387
- def uvm_variants():
388
- df = pd.DataFrame(UVM_VARIANTS)
389
- log_entry("S1-F | S1-R12c | UVM-variants", "load", f"{len(df)} variants")
390
- return df
391
-
392
- def uvm_vitreous():
393
- df = pd.DataFrame(UVM_VITREOUS_LNP)
394
- fig, ax = plt.subplots(figsize=(6, 3), facecolor=CARD)
395
- ax.set_facecolor(CARD)
396
- colors = [GRN if p=="HIGH" else ACC if p=="MEDIUM" else RED for p in df["Priority"]]
397
- ax.barh(df["Formulation"], df["Retention_h"], color=colors)
398
- ax.set_xlabel("Vitreous retention (hours)", color=TXT)
399
- ax.tick_params(colors=TXT, labelsize=8)
400
- for sp in ax.spines.values(): sp.set_edgecolor(BORDER)
401
- ax.set_title("UVM — LNP retention in vitreous humor", color=TXT, fontsize=9)
402
- plt.tight_layout()
403
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
404
- log_entry("S1-F | S1-R12c | UVM-vitreous", "load", "vitreous LNP ranking")
405
- return df, Image.open(buf)
406
-
407
- def paml_ferroptosis(variant):
408
- row = next((r for r in PAML_VARIANTS if variant in r["Variant"]), PAML_VARIANTS[0])
409
- score = 0
410
- ferr_map = {"GPX4 suppressed": 0.85, "SLC7A11 upregulated": 0.72,
411
- "ACSL4 altered": 0.61, "NRF2 pathway": 0.55, "Iron metabolism disrupted": 0.78}
412
- ferr_score = ferr_map.get(row["Ferroptosis"], 0.5)
413
- cats = ["Ferroptosis\nsensitivity", "Drug\navailable", "BM niche\ncoverage", "Data\nmaturity", "Target\nnovelty"]
414
- has_drug = 0.9 if row["Drug_status"] not in ["Novel target"] else 0.3
415
- vals = [ferr_score, has_drug, 0.6, 0.55, 1-has_drug+0.2]
416
- angles = np.linspace(0, 2*np.pi, len(cats), endpoint=False).tolist()
417
- v2, a2 = vals+[vals[0]], angles+[angles[0]]
418
- fig, ax = plt.subplots(figsize=(5, 4), subplot_kw={"polar":True}, facecolor=CARD)
419
- ax.set_facecolor(CARD)
420
- ax.plot(a2, v2, color=ACC2, linewidth=2); ax.fill(a2, v2, color=ACC2, alpha=0.2)
421
- ax.set_xticks(angles); ax.set_xticklabels(cats, color=TXT, fontsize=8)
422
- ax.tick_params(colors=TXT)
423
- ax.set_title(f"pAML · {row['Variant'][:20]}", color=TXT, fontsize=9)
424
- plt.tight_layout()
425
- buf = BytesIO(); plt.savefig(buf, format="png", dpi=120, facecolor=CARD); plt.close(); buf.seek(0)
426
- log_entry("S1-F | S1-R12d | pAML-ferroptosis", variant, f"ferr={ferr_score:.2f}")
427
- _v = row["Variant"]
428
- _p = row["Pathway"]
429
- _d = row["Drug_status"]
430
- _f = row["Ferroptosis"]
431
- _fs = f"{ferr_score:.2f}"
432
- summary = (
433
- f"<div style='background:{CARD};padding:14px;border-radius:8px;font-family:sans-serif;'>"
434
- f"<p style='color:{DIM};font-size:11px;margin:0 0 6px'>S1-F · PHYLO-RARE · S1-R12d · pAML</p>"
435
- f"<b style='color:{ACC2};font-size:15px'>{_v}</b><br>"
436
- f"<p style='color:{TXT};margin:6px 0'><b>Pathway:</b> {_p}</p>"
437
- f"<p style='color:{TXT};margin:0'><b>Drug:</b> {_d}</p>"
438
- f"<p style='color:{TXT};margin:6px 0'><b>Ferroptosis link:</b> {_f}</p>"
439
- f"<p style='color:{TXT}'><b>Ferroptosis sensitivity score:</b> "
440
- f"<span style='color:{ACC};font-size:18px'>{_fs}</span></p>"
441
- f"<p style='font-size:11px;color:{DIM}'>Research only. Not clinical advice.</p></div>"
442
- )
443
- return summary, Image.open(buf)
444
-
445
- # ---------- Хелпери для UI ----------
446
- def section_header(code, name, tagline, projects_html):
447
- return (
448
- f"<div style='background:{BG};border:1px solid {BORDER};padding:14px 18px;"
449
- f"border-radius:8px;margin-bottom:12px;'>"
450
- f"<div style='display:flex;align-items:baseline;gap:10px;'>"
451
- f"<span style='color:{ACC2};font-size:16px;font-weight:700'>{code}</span>"
452
- f"<span style='color:{TXT};font-size:14px;font-weight:600'>{name}</span>"
453
- f"<span style='color:{DIM};font-size:12px'>{tagline}</span></div>"
454
- f"<div style='margin-top:8px;font-size:12px;color:{DIM}'>{projects_html}</div>"
455
- f"</div>"
456
- )
457
-
458
- def proj_badge(code, title, metric=""):
459
- m = (f"<span style='background:#0f2a3f;color:{ACC2};padding:1px 7px;border-radius:3px;"
460
- f"font-size:10px;margin-left:6px'>{metric}</span>") if metric else ""
461
- return (
462
- f"<div style='background:{CARD};border-left:3px solid {ACC};"
463
- f"padding:8px 12px;border-radius:0 6px 6px 0;margin-bottom:8px;'>"
464
- f"<span style='color:{DIM};font-size:11px'>{code}</span>{m}<br>"
465
- f"<span style='color:{TXT};font-size:14px;font-weight:600'>{title}</span>"
466
- f"</div>"
467
- )
468
-
469
- # ---------- CSS ----------
470
- css = f"""
471
- body, .gradio-container {{ background: {BG} !important; color: {TXT} !important; }}
472
-
473
- /* OUTER tab bar — PHYLO categories */
474
- .outer-tabs .tab-nav button {{
475
- color: {TXT} !important;
476
- background: {CARD} !important;
477
- font-size: 13px !important;
478
- font-weight: 600 !important;
479
- padding: 8px 16px !important;
480
- border-radius: 6px 6px 0 0 !important;
481
- }}
482
- .outer-tabs .tab-nav button.selected {{
483
- border-bottom: 3px solid {ACC} !important;
484
- color: {ACC} !important;
485
- background: {BG} !important;
486
- }}
487
-
488
- /* INNER sub-tab bar — R1, R2, etc. */
489
- .inner-tabs .tab-nav button {{
490
- color: {DIM} !important;
491
- background: {BG} !important;
492
- font-size: 12px !important;
493
- font-weight: 500 !important;
494
- padding: 5px 12px !important;
495
- border-radius: 4px 4px 0 0 !important;
496
- border: 1px solid {BORDER} !important;
497
- border-bottom: none !important;
498
- margin-right: 3px !important;
499
- }}
500
- .inner-tabs .tab-nav button.selected {{
501
- color: {ACC2} !important;
502
- background: {CARD} !important;
503
- border-color: {ACC2} !important;
504
- border-bottom: none !important;
505
- }}
506
- .inner-tabs > .tabitem {{
507
- background: {CARD} !important;
508
- border: 1px solid {BORDER} !important;
509
- border-radius: 0 6px 6px 6px !important;
510
- padding: 14px !important;
511
- }}
512
-
513
- /* Третій рівень вкладок (a, b) */
514
- .sub-sub-tabs .tab-nav button {{
515
- color: {DIM} !important;
516
- background: {CARD} !important;
517
- font-size: 11px !important;
518
- padding: 3px 8px !important;
519
- border-radius: 3px 3px 0 0 !important;
520
- }}
521
- .sub-sub-tabs .tab-nav button.selected {{
522
- color: {ACC} !important;
523
- background: {BG} !important;
524
- }}
525
-
526
- h1, h2, h3 {{ color: {ACC} !important; }}
527
- .gr-button-primary {{ background: {ACC} !important; border: none !important; }}
528
- footer {{ display: none !important; }}
529
- """
530
-
531
- # ---------- MAP HTML ----------
532
- MAP_HTML = f"""
533
- <div style="background:{CARD};padding:22px;border-radius:8px;font-family:monospace;
534
- font-size:13px;line-height:2.0;color:{TXT}">
535
-
536
- <span style="color:{ACC};font-size:16px;font-weight:bold">K R&D Lab · S1 Biomedical</span>
537
- <span style="color:{DIM};font-size:11px;margin-left:12px">Science Sphere — sub-direction 1</span>
538
- <br><br>
539
-
540
- <span style="color:{ACC2};font-weight:600">S1-A · PHYLO-GENOMICS</span>
541
- <span style="color:{DIM}"> — What breaks in DNA</span><br>
542
- &nbsp;&nbsp;&nbsp;├─ <b>S1-A · R1a</b> &nbsp;OpenVariant
543
- <span style="color:{GRN}"> AUC=0.939 ✅</span><br>
544
- &nbsp;&nbsp;&nbsp;├─ <b>S1-A · R1b</b> Somatic classifier
545
- <span style="color:#f59e0b"> 🔶 In progress</span><br>
546
- &nbsp;&nbsp;&nbsp;└─ <b>S1-A · R2a</b> Rare variants (DIPG · UVM)
547
- <span style="color:{DIM}"> 🔴 Planned</span><br><br>
548
-
549
- <span style="color:{ACC2};font-weight:600">S1-B · PHYLO-RNA</span>
550
- <span style="color:{DIM}"> — How to silence it via RNA</span><br>
551
- &nbsp;&nbsp;&nbsp;├─ <b>S1-B · R1a</b> &nbsp;miRNA silencing (BRCA2)
552
- <span style="color:{GRN}"> ✅</span><br>
553
- &nbsp;&nbsp;&nbsp;├─ <b>S1-B · R2a</b> &nbsp;siRNA synthetic lethal (LUAD · BRCA · COAD)
554
- <span style="color:{GRN}"> ✅</span><br>
555
- &nbsp;&nbsp;&nbsp;├─ <b>S1-B · R3a</b> &nbsp;lncRNA-TREM2 ceRNA network
556
- <span style="color:{GRN}"> ✅</span><br>
557
- &nbsp;&nbsp;&nbsp;└─ <b>S1-B · R3b</b> ASO designer
558
- <span style="color:{GRN}"> ✅</span><br><br>
559
-
560
- <span style="color:{ACC2};font-weight:600">S1-C · PHYLO-DRUG</span>
561
- <span style="color:{DIM}"> — Which molecule treats it</span><br>
562
- &nbsp;&nbsp;&nbsp;├─ <b>S1-C · R1a</b> &nbsp;FGFR3 RNA-directed compounds
563
- <span style="color:{GRN}"> ✅</span><br>
564
- &nbsp;&nbsp;&nbsp;├─ <b>S1-C · R1b</b> Synthetic lethal drug mapping
565
- <span style="color:#f59e0b"> 🔶</span><br>
566
- &nbsp;&nbsp;&nbsp;└─ <b>S1-C · R2a</b> m6A × Ferroptosis × Circadian ⭐
567
- <span style="color:{DIM}"> 🔴 Frontier</span><br><br>
568
-
569
- <span style="color:{ACC2};font-weight:600">S1-D · PHYLO-LNP</span>
570
- <span style="color:{DIM}"> — How to deliver the drug</span><br>
571
- &nbsp;&nbsp;&nbsp;├─ <b>S1-D · R1a</b> &nbsp;LNP corona (serum)
572
- <span style="color:{GRN}"> AUC=0.791 ✅</span><br>
573
- &nbsp;&nbsp;&nbsp;├─ <b>S1-D · R2a</b> &nbsp;Flow corona — Vroman effect
574
- <span style="color:{GRN}"> ✅</span><br>
575
- &nbsp;&nbsp;&nbsp;├─ <b>S1-D · R3a</b> &nbsp;LNP brain / BBB / ApoE
576
- <span style="color:{GRN}"> ✅</span><br>
577
- &nbsp;&nbsp;&nbsp;├─ <b>S1-D · R4a</b> AutoCorona NLP
578
- <span style="color:{GRN}"> F1=0.71 ✅</span><br>
579
- &nbsp;&nbsp;&nbsp;└─ <b>S1-D · R5a</b> CSF · Vitreous · Bone Marrow ⭐
580
- <span style="color:{DIM}"> 🔴 0 prior studies</span><br><br>
581
-
582
- <span style="color:{ACC2};font-weight:600">S1-E · PHYLO-BIOMARKERS</span>
583
- <span style="color:{DIM}"> — Detect without biopsy</span><br>
584
- &nbsp;&nbsp;&nbsp;├─ <b>S1-E · R1a</b> &nbsp;Liquid Biopsy classifier
585
- <span style="color:{GRN}"> AUC=0.992* ✅</span><br>
586
- &nbsp;&nbsp;&nbsp;└─ <b>S1-E · R1b</b> Protein panel validator
587
- <span style="color:#f59e0b"> 🔶</span><br><br>
588
-
589
- <span style="color:{ACC2};font-weight:600">S1-F · PHYLO-RARE</span>
590
- <span style="color:{DIM}"> — Where almost nobody has looked yet (&lt;300 cases/yr)</span><br>
591
- &nbsp;&nbsp;&nbsp;├─ <b>S1-F · R1a</b> DIPG toolkit (H3K27M + CSF LNP + Circadian)
592
- <span style="color:#f59e0b"> 🔶 In development</span><br>
593
- &nbsp;&nbsp;&nbsp;├─ <b>S1-F · R2a</b> UVM toolkit (GNAQ/GNA11 + vitreous + m6A)
594
- <span style="color:#f59e0b"> 🔶 In development</span><br>
595
- &nbsp;&nbsp;&nbsp;└─ <b>S1-F · R3a</b> pAML toolkit (FLT3-ITD + BM niche + ferroptosis)
596
- <span style="color:#f59e0b"> 🔶 In development</span><br><br>
597
-
598
- <span style="color:{DIM};font-size:11px">
599
- ✅ Active in this demo &nbsp;·&nbsp; 🔶 In progress &nbsp;·&nbsp; 🔴 Planned / Frontier<br>
600
- ⭐ gap research (0–1 prior studies globally) &nbsp;·&nbsp; * tissue proxy, plasma validation pending
601
- </span>
602
- </div>
603
- """
604
-
605
- # ---------- ПОБУДОВА UI ----------
606
- with gr.Blocks(css=css, title="K R&D Lab · S1 Biomedical") as demo:
607
- gr.Markdown(
608
- "# 🔬 K R&D Lab · Science Sphere — S1 Biomedical\n"
609
- "**Oksana Kolisnyk** · [KOSATIKS GROUP](https://kosatiks-group.pp.ua) &nbsp;|&nbsp; "
610
- "[GitHub](https://github.com/K-RnD-Lab) &nbsp; "
611
- "[HuggingFace](https://huggingface.co/K-RnD-Lab) &nbsp;|&nbsp; "
612
- "*Research only. Not clinical advice.*"
613
- )
614
-
615
- # Основний рівень вкладок (категорії)
616
- with gr.Tabs(elem_classes="outer-tabs") as outer_tabs:
617
- # 1. Карта лабораторії
618
- with gr.TabItem("🗺️ Lab Map"):
619
- gr.HTML(MAP_HTML)
620
-
621
- # 2. S1-A · PHYLO-GENOMICS
622
- with gr.TabItem("🧬 PHYLO-GENOMICS"):
623
- gr.HTML(section_header(
624
- "S1-A", "PHYLO-GENOMICS", "— What breaks in DNA",
625
- "R1a OpenVariant ✅ &nbsp;·&nbsp; R1b Somatic classifier 🔶"
626
- ))
627
- with gr.Tabs(elem_classes="inner-tabs") as inner_tabs:
628
- # R1 · Variant classification
629
- with gr.TabItem("R1 · Variant classification"):
630
- with gr.Tabs(elem_classes="sub-sub-tabs") as sub_tabs:
631
- # R1a · OpenVariant
632
- with gr.TabItem("R1a · OpenVariant"):
633
- gr.HTML(proj_badge("S1-A · R1a", "OpenVariant — SNV Pathogenicity Classifier", "AUC=0.939"))
634
- hgvs = gr.Textbox(label="HGVS notation", placeholder="BRCA1:p.R1699Q")
635
- gr.Markdown("**Or enter functional scores manually:**")
636
- with gr.Row():
637
- sift = gr.Slider(0,1,value=0.5,step=0.01,label="SIFT (0=damaging)")
638
- pp = gr.Slider(0,1,value=0.5,step=0.01,label="PolyPhen-2")
639
- gn = gr.Slider(0,0.01,value=0.001,step=0.0001,label="gnomAD AF")
640
- b_v = gr.Button("Predict Pathogenicity", variant="primary")
641
- o_v = gr.HTML()
642
- gr.Examples([["BRCA1:p.R1699Q",0.82,0.05,0.0012],
643
- ["TP53:p.R248W",0.00,1.00,0.0],
644
- ["BRCA2:p.D2723A",0.01,0.98,0.0]],
645
- inputs=[hgvs,sift,pp,gn], cache_examples=False)
646
- b_v.click(predict_variant, [hgvs,sift,pp,gn], o_v)
647
- # R1b · Somatic Classifier (в розробці)
648
- with gr.TabItem("R1b · Somatic Classifier 🔶"):
649
- gr.HTML(proj_badge("S1-A · R1b", "Somatic Mutation Classifier — BRCA · LUAD panels", "🔶 In progress"))
650
- gr.Markdown("> This module is in active development. Coming in the next release.")
651
-
652
- # 3. S1-B · PHYLO-RNA
653
- with gr.TabItem("🔬 PHYLO-RNA"):
654
- gr.HTML(section_header(
655
- "S1-B", "PHYLO-RNA", "— How to silence it via RNA",
656
- "R1a miRNA ✅ &nbsp;·&nbsp; R2a siRNA ✅ &nbsp;·&nbsp; R3a lncRNA ✅ &nbsp;·&nbsp; R3b ASO ✅"
657
- ))
658
- with gr.Tabs(elem_classes="inner-tabs"):
659
- # R1 · miRNA silencing
660
- with gr.TabItem("R1 · miRNA silencing"):
661
- with gr.Tabs(elem_classes="sub-sub-tabs"):
662
- with gr.TabItem("R1a · BRCA2 miRNA"):
663
- gr.HTML(proj_badge("S1-B · R1a", "miRNA Silencing — BRCA2"))
664
- g1 = gr.Dropdown(["BRCA2","BRCA1","TP53"], value="BRCA2", label="Gene")
665
- b1 = gr.Button("Find miRNAs", variant="primary")
666
- o1 = gr.Dataframe(label="Top 5 downregulated miRNAs")
667
- gr.Examples([["BRCA2"],["BRCA1"],["TP53"]], inputs=[g1])
668
- b1.click(predict_mirna, [g1], o1)
669
- # R2 · siRNA SL
670
- with gr.TabItem("R2 · siRNA SL"):
671
- with gr.Tabs(elem_classes="sub-sub-tabs"):
672
- with gr.TabItem("R2a · TP53 siRNA"):
673
- gr.HTML(proj_badge("S1-B · R2a", "siRNA Synthetic Lethal — TP53-null"))
674
- g2 = gr.Dropdown(["LUAD","BRCA","COAD"], value="LUAD", label="Cancer type")
675
- b2 = gr.Button("Find Targets", variant="primary")
676
- o2 = gr.Dataframe(label="Top 5 synthetic lethal targets")
677
- gr.Examples([["LUAD"],["BRCA"],["COAD"]], inputs=[g2], cache_examples=False)
678
- b2.click(predict_sirna, [g2], o2)
679
- # R3 · lncRNA + ASO
680
- with gr.TabItem("R3 · lncRNA + ASO"):
681
- with gr.Tabs(elem_classes="sub-sub-tabs"):
682
- with gr.TabItem("R3a · lncRNA-TREM2"):
683
- gr.HTML(proj_badge("S1-B · R3a", "lncRNA-TREM2 ceRNA Network"))
684
- b3a = gr.Button("Load ceRNA", variant="primary")
685
- o3a = gr.Dataframe(label="ceRNA Network (R3a)")
686
- b3a.click(lambda: pd.DataFrame(CERNA), [], o3a)
687
- with gr.TabItem("R3b · ASO Designer"):
688
- gr.HTML(proj_badge("S1-B · R3b", "ASO Designer"))
689
- b3b = gr.Button("Load ASO Candidates", variant="primary")
690
- o3b = gr.Dataframe(label="ASO Candidates (R3b)")
691
- b3b.click(lambda: pd.DataFrame(ASO), [], o3b)
692
-
693
- # 4. S1-C · PHYLO-DRUG
694
- with gr.TabItem("💊 PHYLO-DRUG"):
695
- gr.HTML(section_header(
696
- "S1-C", "PHYLO-DRUG", "— Which molecule treats it",
697
- "R1a FGFR3 ✅ &nbsp;·&nbsp; R1b SL drug mapping 🔶 &nbsp;·&nbsp; R2a m6A×Ferroptosis×Circadian 🔴⭐"
698
- ))
699
- with gr.Tabs(elem_classes="inner-tabs"):
700
- # R1 · RNA-directed drug
701
- with gr.TabItem("R1 · RNA-directed drug"):
702
- with gr.Tabs(elem_classes="sub-sub-tabs"):
703
- with gr.TabItem("R1a · FGFR3 RNA Drug"):
704
- gr.HTML(proj_badge("S1-C · R1a", "FGFR3 RNA-Directed Drug Discovery", "top score 0.793"))
705
- g4 = gr.Radio(["P1 (hairpin loop)","P10 (G-quadruplex)"],
706
- value="P1 (hairpin loop)", label="Target pocket")
707
- b4 = gr.Button("Screen Compounds", variant="primary")
708
- o4t = gr.Dataframe(label="Top 5 candidates")
709
- o4p = gr.Image(label="Binding scores")
710
- gr.Examples([["P1 (hairpin loop)"],["P10 (G-quadruplex)"]], inputs=[g4])
711
- b4.click(predict_drug, [g4], [o4t, o4p])
712
- with gr.TabItem("R1b · SL Drug Mapping 🔶"):
713
- gr.HTML(proj_badge("S1-C · R1b", "Synthetic Lethal Drug Mapping", "🔶 In progress"))
714
- gr.Markdown("> In development. Coming soon.")
715
- # R2 · Frontier
716
- with gr.TabItem("R2 · Frontier"):
717
- with gr.Tabs(elem_classes="sub-sub-tabs"):
718
- with gr.TabItem("R2a · m6A×Ferroptosis×Circadian 🔴⭐"):
719
- gr.HTML(proj_badge("S1-C · R2a", "m6A × Ferroptosis × Circadian", "🔴 Frontier"))
720
- gr.Markdown(
721
- "> **Research gap:** This triple intersection has never been studied as an integrated system.\n\n"
722
- "> **Planned datasets:** TCGA-PAAD · GEO m6A atlases · Circadian gene panels\n\n"
723
- "> **Expected timeline:** Q3 2026"
724
- )
725
-
726
- # 5. S1-D · PHYLO-LNP
727
- with gr.TabItem("🧪 PHYLO-LNP"):
728
- gr.HTML(section_header(
729
- "S1-D", "PHYLO-LNP", "— How to deliver the drug",
730
- "R1a Corona ✅ · R2a Flow ✅ · R3a Brain ✅ · R4a NLP ✅ · R5a CSF/BM 🔴⭐"
731
- ))
732
- with gr.Tabs(elem_classes="inner-tabs"):
733
- # R1 · Serum corona
734
- with gr.TabItem("R1 · Serum corona"):
735
- with gr.Tabs(elem_classes="sub-sub-tabs"):
736
- with gr.TabItem("R1a · LNP Corona ML"):
737
- gr.HTML(proj_badge("S1-D · R1a", "LNP Protein Corona (Serum)", "AUC=0.791"))
738
- with gr.Row():
739
- sz = gr.Slider(50,300,value=100,step=1,label="Size (nm)")
740
- zt = gr.Slider(-40,10,value=-5,step=1,label="Zeta (mV)")
741
- with gr.Row():
742
- pg = gr.Slider(0,5,value=1.5,step=0.1,label="PEG mol%")
743
- lp = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Lipid type")
744
- b6 = gr.Button("Predict", variant="primary"); o6 = gr.Markdown()
745
- gr.Examples([[100,-5,1.5,"Ionizable"],[80,5,0.5,"Cationic"]], inputs=[sz,zt,pg,lp])
746
- b6.click(predict_corona, [sz,zt,pg,lp], o6)
747
- # R2 · Flow corona
748
- with gr.TabItem("R2 · Flow corona"):
749
- with gr.Tabs(elem_classes="sub-sub-tabs"):
750
- with gr.TabItem("R2a · Flow Corona"):
751
- gr.HTML(proj_badge("S1-D · R2a", "Flow Corona — Vroman Effect"))
752
- with gr.Row():
753
- s8 = gr.Slider(50,300,value=100,step=1,label="Size (nm)")
754
- z8 = gr.Slider(-40,10,value=-5,step=1,label="Zeta (mV)")
755
- pg8 = gr.Slider(0,5,value=1.5,step=0.1,label="PEG mol%")
756
- with gr.Row():
757
- ch8 = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Charge")
758
- fl8 = gr.Slider(0,40,value=20,step=1,label="Flow cm/s (aorta=40)")
759
- b8 = gr.Button("Model Vroman Effect", variant="primary")
760
- o8t = gr.Markdown(); o8p = gr.Image(label="Kinetics")
761
- gr.Examples([[100,-5,1.5,"Ionizable",40],[150,5,0.5,"Cationic",10]], inputs=[s8,z8,pg8,ch8,fl8])
762
- b8.click(predict_flow, [s8,z8,pg8,ch8,fl8], [o8t,o8p])
763
- # R3 · Brain BBB
764
- with gr.TabItem("R3 · Brain BBB"):
765
- with gr.Tabs(elem_classes="sub-sub-tabs"):
766
- with gr.TabItem("R3a · LNP Brain"):
767
- gr.HTML(proj_badge("S1-D · R3a", "LNP Brain Delivery"))
768
- smi = gr.Textbox(label="Ionizable lipid SMILES",
769
- value="CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C")
770
- with gr.Row():
771
- pk = gr.Slider(4,8,value=6.5,step=0.1,label="pKa")
772
- zt9 = gr.Slider(-20,10,value=-3,step=1,label="Zeta (mV)")
773
- b9 = gr.Button("Predict BBB Crossing", variant="primary")
774
- o9t = gr.Markdown(); o9p = gr.Image(label="Radar profile")
775
- gr.Examples([["CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C",6.5,-3]], inputs=[smi,pk,zt9])
776
- b9.click(predict_bbb, [smi,pk,zt9], [o9t,o9p])
777
- # R4 · NLP
778
- with gr.TabItem("R4 · NLP"):
779
- with gr.Tabs(elem_classes="sub-sub-tabs"):
780
- with gr.TabItem("R4a · AutoCorona NLP"):
781
- gr.HTML(proj_badge("S1-D · R4a", "AutoCorona NLP", "F1=0.71"))
782
- txt = gr.Textbox(lines=5,label="Paper abstract",placeholder="Paste abstract here...")
783
- b10 = gr.Button("Extract Data", variant="primary")
784
- o10j = gr.Code(label="Extracted JSON", language="json")
785
- o10f = gr.Textbox(label="Validation flags")
786
- gr.Examples([[
787
- "LNPs composed of MC3, DSPC, Cholesterol (50:10:40 mol%) with 1.5% PEG-DMG. "
788
- "Hydrodynamic diameter was 98 nm, zeta potential -3.2 mV, PDI 0.12. "
789
- "Incubated in human plasma. Corona: albumin, apolipoprotein E, fibrinogen."
790
- ]], inputs=[txt])
791
- b10.click(extract_corona, txt, [o10j, o10f])
792
- # R5 · Exotic fluids
793
- with gr.TabItem("R5 · Exotic fluids 🔴⭐"):
794
- with gr.Tabs(elem_classes="sub-sub-tabs"):
795
- with gr.TabItem("R5a · CSF/Vitreous/BM"):
796
- gr.HTML(proj_badge("S1-D · R5a", "LNP Corona in CSF · Vitreous · Bone Marrow", "🔴 0 prior studies"))
797
- gr.Markdown(
798
- "> **Research gap:** Protein corona has only been characterized in serum/plasma. "
799
- "CSF, vitreous humor, and bone marrow interstitial fluid remain completely unstudied.\n\n"
800
- "> **Target cancers:** DIPG (CSF) · UVM (vitreous) · pAML (bone marrow)\n\n"
801
- "> **Expected timeline:** Q2–Q3 2026"
802
- )
803
-
804
- # 6. S1-E · PHYLO-BIOMARKERS
805
- with gr.TabItem("🩸 PHYLO-BIOMARKERS"):
806
- gr.HTML(section_header(
807
- "S1-E", "PHYLO-BIOMARKERS", "— Detect without biopsy",
808
- "R1a Liquid Biopsy ✅ &nbsp;·&nbsp; R1b Protein validator 🔶"
809
- ))
810
- with gr.Tabs(elem_classes="inner-tabs"):
811
- with gr.TabItem("R1 · Liquid biopsy"):
812
- with gr.Tabs(elem_classes="sub-sub-tabs"):
813
- with gr.TabItem("R1a · Liquid Biopsy"):
814
- gr.HTML(proj_badge("S1-E · R1a", "Liquid Biopsy Classifier", "AUC=0.992*"))
815
- with gr.Row():
816
- p1=gr.Slider(-3,3,value=0,step=0.1,label="CTHRC1")
817
- p2=gr.Slider(-3,3,value=0,step=0.1,label="FHL2")
818
- p3=gr.Slider(-3,3,value=0,step=0.1,label="LDHA")
819
- p4=gr.Slider(-3,3,value=0,step=0.1,label="P4HA1")
820
- p5=gr.Slider(-3,3,value=0,step=0.1,label="SERPINH1")
821
- with gr.Row():
822
- p6=gr.Slider(-3,3,value=0,step=0.1,label="ABCA8")
823
- p7=gr.Slider(-3,3,value=0,step=0.1,label="CA4")
824
- p8=gr.Slider(-3,3,value=0,step=0.1,label="CKB")
825
- p9=gr.Slider(-3,3,value=0,step=0.1,label="NNMT")
826
- p10=gr.Slider(-3,3,value=0,step=0.1,label="CACNA2D2")
827
- b7=gr.Button("Classify", variant="primary")
828
- o7t=gr.HTML(); o7p=gr.Image(label="Feature contributions")
829
- gr.Examples([[2,2,1.5,1.8,1.6,-1,-1.2,-0.8,1.4,-1.1],[0]*10],
830
- inputs=[p1,p2,p3,p4,p5,p6,p7,p8,p9,p10])
831
- b7.click(predict_cancer, [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10], [o7t,o7p])
832
- with gr.TabItem("R1b · Protein Validator 🔶"):
833
- gr.HTML(proj_badge("S1-E · R1b", "Protein Panel Validator", "🔶 In progress"))
834
- gr.Markdown("> Coming next — validates R1a results against GEO plasma proteomics datasets.")
835
-
836
- # 7. S1-F · PHYLO-RARE
837
- with gr.TabItem("🧠 PHYLO-RARE"):
838
- gr.HTML(section_header(
839
- "S1-F", "PHYLO-RARE", "— Where almost nobody has looked yet",
840
- "<b style='color:#ef4444'>⚠️ <300 cases/yr · <5% survival · 0–1 prior studies per gap</b><br>"
841
- "R1a DIPG 🔶 &nbsp;·&nbsp; R2a UVM 🔶 &nbsp;·&nbsp; R3a pAML 🔶"
842
- ))
843
- with gr.Tabs(elem_classes="inner-tabs"):
844
- # R1 · DIPG
845
- with gr.TabItem("R1 · DIPG"):
846
- with gr.Tabs(elem_classes="sub-sub-tabs"):
847
- with gr.TabItem("R1a · DIPG Toolkit"):
848
- gr.HTML(proj_badge("S1-F · R1a", "DIPG Toolkit", "PBTA · GSE126319"))
849
- gr.Markdown(
850
- "> **Why DIPG?** Diffuse Intrinsic Pontine Glioma — median survival 9–11 months. "
851
- "H3K27M oncohistone in **78%** cases. "
852
- "CSF delivery is the only viable route past the brainstem BBB. "
853
- "Circadian disruption (BMAL1 suppression) newly linked — **0 prior LNP studies**."
854
- )
855
- with gr.Tabs():
856
- with gr.TabItem("Variants"):
857
- sort_d = gr.Radio(["Frequency", "Drug status"], value="Frequency", label="Sort by")
858
- b_dv = gr.Button("Load DIPG Variants", variant="primary")
859
- o_dv = gr.Dataframe(label="H3K27M co-mutations · PBTA/GSE126319")
860
- b_dv.click(dipg_variants, [sort_d], o_dv)
861
- with gr.TabItem("CSF LNP"):
862
- with gr.Row():
863
- d_peg = gr.Slider(0.5, 3.0, value=1.5, step=0.1, label="PEG mol%")
864
- d_size = gr.Slider(60, 150, value=90, step=5, label="Target size (nm)")
865
- b_dc = gr.Button("Rank CSF Formulations", variant="primary")
866
- o_dct = gr.Dataframe(label="CSF LNP ranking")
867
- o_dcp = gr.Image(label="ApoE% in CSF corona")
868
- b_dc.click(dipg_csf, [d_peg, d_size], [o_dct, o_dcp])
869
- with gr.TabItem("Research Gap"):
870
- gr.Markdown(
871
- "**Data:** PBTA (n=240) · GSE126319 (n=28) · GTEx circadian genes\n\n"
872
- "| Layer | Known | This study gap |\n"
873
- "|-------|-------|----------------|\n"
874
- "| Genomics | H3K27M freq=78% | H3K27M × BMAL1/CLOCK |\n"
875
- "| Delivery | CED convection | LNP corona **in CSF** |\n"
876
- "| Biology | PRC2 inhibition | Ferroptosis in H3K27M+ DIPG |"
877
- )
878
- # R2 · UVM
879
- with gr.TabItem("R2 · UVM"):
880
- with gr.Tabs(elem_classes="sub-sub-tabs"):
881
- with gr.TabItem("R2a · UVM Toolkit"):
882
- gr.HTML(proj_badge("S1-F · R2a", "UVM Toolkit", "TCGA-UVM n=80"))
883
- gr.Markdown(
884
- "> **Why UVM?** Uveal Melanoma — metastatic 5-yr survival **15%**. "
885
- "GNAQ/GNA11 mutations in 78% cases. "
886
- "Vitreous humor protein corona has **never been profiled**. "
887
- "METTL3/WTAP upregulated in GNAQ+ tumors — 0 therapeutic studies."
888
- )
889
- with gr.Tabs():
890
- with gr.TabItem("Variants + m6A"):
891
- b_uv = gr.Button("Load UVM Variants", variant="primary")
892
- o_uv = gr.Dataframe(label="GNAQ/GNA11 map · TCGA-UVM")
893
- b_uv.click(uvm_variants, [], o_uv)
894
- with gr.TabItem("Vitreous LNP"):
895
- b_uw = gr.Button("Rank Vitreous Formulations", variant="primary")
896
- o_uwt = gr.Dataframe(label="Vitreous LNP retention ranking")
897
- o_uwp = gr.Image(label="Retention (hours)")
898
- b_uw.click(uvm_vitreous, [], [o_uwt, o_uwp])
899
- with gr.TabItem("Research Gap"):
900
- gr.Markdown(
901
- "**Data:** TCGA-UVM (n=80) · GEO m6A atlases · Vitreous proteomics\n\n"
902
- "| Layer | Known | This study gap |\n"
903
- "|-------|-------|----------------|\n"
904
- "| Genomics | GNAQ/GNA11 mutations | m6A landscape GNAQ+ vs GNA11+ |\n"
905
- "| Delivery | Intravitreal injection | LNP corona **in vitreous humor** |\n"
906
- "| Biology | PLCβ→PKC→MAPK | GNAQ × METTL3 × YTHDF2 axis |"
907
- )
908
- # R3 · pAML
909
- with gr.TabItem("R3 · pAML"):
910
- with gr.Tabs(elem_classes="sub-sub-tabs"):
911
- with gr.TabItem("R3a · pAML Toolkit"):
912
- gr.HTML(proj_badge("S1-F · R3a", "pAML Toolkit", "TARGET-AML n≈197"))
913
- gr.Markdown(
914
- "> **Why pAML?** Pediatric AML — relapse OS **<30%**. "
915
- "FLT3-ITD in 25% cases. "
916
- "Bone marrow niche LNP corona: **never studied**. "
917
- "Ferroptosis–FLT3 intersection: 0 prior studies (FerrDb v2 confirmed)."
918
- )
919
- with gr.Tabs():
920
- with gr.TabItem("Ferroptosis Explorer"):
921
- var_sel = gr.Dropdown(
922
- ["FLT3-ITD", "NPM1 c.860_863dupTCAG", "DNMT3A p.R882H",
923
- "CEBPA biallelic", "IDH1/2 mutation"],
924
- value="FLT3-ITD", label="Select variant"
925
- )
926
- b_pf = gr.Button("Analyze Ferroptosis Profile", variant="primary")
927
- o_pft = gr.HTML()
928
- o_pfp = gr.Image(label="Target radar")
929
- b_pf.click(paml_ferroptosis, var_sel, [o_pft, o_pfp])
930
- with gr.TabItem("BM Niche LNP"):
931
- gr.Dataframe(
932
- value=pd.DataFrame(PAML_BM_LNP),
933
- label="Bone marrow niche LNP candidates · TARGET-AML context"
934
- )
935
- with gr.TabItem("Research Gap"):
936
- gr.Markdown(
937
- "**Data:** TARGET-AML (n=197) · BeatAML · FerrDb v2\n\n"
938
- "| Layer | Known | This study gap |\n"
939
- "|-------|-------|----------------|\n"
940
- "| Genomics | FLT3-ITD → Midostaurin | FLT3-ITD × GPX4/SLC7A11 |\n"
941
- "| Delivery | Liposomal daunorubicin | LNP corona **in bone marrow** |\n"
942
- "| Biology | Midostaurin inhibits FLT3 | Ferroptosis SL + FLT3i |"
943
- )
944
-
945
- # 8. Journal
946
- with gr.TabItem("📓 Journal"):
947
- gr.Markdown("### Lab Journal\nEvery tool call auto-logged with project code.")
948
- with gr.Row():
949
- note_text = gr.Textbox(label="📝 Observation", placeholder="What did you discover?", lines=3)
950
- note_tab = gr.Textbox(label="Project code (e.g. S1-A-R1a)", value="General")
951
- note_last = gr.Textbox(visible=False)
952
- save_btn = gr.Button("💾 Save", variant="primary")
953
- save_msg = gr.Markdown()
954
- journal_df = gr.Dataframe(label="📋 Full History", value=load_journal(), interactive=False)
955
- refresh_btn = gr.Button("🔄 Refresh")
956
- refresh_btn.click(load_journal, [], journal_df)
957
- save_btn.click(save_note, [note_text, note_tab, note_last], [save_msg, journal_df])
958
-
959
- # 9. Learning
960
- with gr.TabItem("📚 Learning"):
961
- gr.Markdown("""
962
- ## 🧪 Guided Investigations — S1 Biomedical
963
- > 🟢 Beginner → 🟡 Intermediate → 🔴 Advanced
964
-
965
- ---
966
- ### 🟢 Case 1 · S1-A · R1a
967
- **Why does the same position give two different outcomes?**
968
- 1. PHYLO-GENOMICS → R1a · OpenVariant → `BRCA1:p.R1699Q` → Benign
969
- 2. Enter `BRCA1:p.R1699W` → Pathogenic
970
- 3. Same position, different amino acid — Q (polar) vs W (bulky-aromatic)
971
-
972
- ---
973
- ### 🟢 Case 2 · S1-D · R1a + R3a
974
- **How does PEG% control which protein coats the nanoparticle?**
975
- 1. PHYLO-LNP → R1a · Corona → Ionizable, Zeta=−5, PEG=**0.5%** → note protein
976
- 2. Change PEG=**2.5%** → compare
977
- 3. R3a · Brain → pKa=6.5 → check ApoE%
978
-
979
- ---
980
- ### 🟡 Case 3 · S1-D · R2a
981
- **Does blood flow reshape the corona over time?**
982
- 1. PHYLO-LNP → R2a · Flow → Flow=0 → observe ApoE curve
983
- 2. Flow=40 (arterial) → compare
984
- 3. At what minute does ApoE dominate?
985
-
986
- ---
987
- ### 🟡 Case 4 · S1-B · R2a
988
- **Which cancer has the most novel (undrugged) siRNA targets?**
989
- 1. PHYLO-RNA → R2a · siRNA → LUAD → count "Novel"
990
- 2. Repeat BRCA, COAD
991
-
992
- ---
993
- ### 🔴 Case 5 · S1-E · R1a
994
- **Minimum protein signal that flips to CANCER?**
995
- 1. PHYLO-BIOMARKERS → R1a · Liquid Biopsy → all=0 → HEALTHY
996
- 2. Set CTHRC1=2.5, FHL2=2.0, LDHA=1.8 → observe
997
- 3. Reset. Increase only CTHRC1 step by step.
998
-
999
- ---
1000
- ### 🔴 Case 6 · Cross-tool convergence
1001
- 1. PHYLO-RNA → R1a · miRNA → TP53 → find top targets (BCL2, CDK6)
1002
- 2. PHYLO-DRUG → R1a · FGFR3 → check CDK6 pathway overlap
1003
- 3. PHYLO-RNA → R2a · siRNA → BRCA → does CDK6 appear?
1004
-
1005
- ---
1006
- ### 📖 Tool Index
1007
- | Code | Module | Tool | Metric |
1008
- |------|--------|------|--------|
1009
- | S1-A·R1a | PHYLO-GENOMICS | OpenVariant | AUC=0.939 |
1010
- | S1-B·R1a | PHYLO-RNA | miRNA silencing | top: hsa-miR-148a |
1011
- | S1-B·R2a | PHYLO-RNA | siRNA SL | SPC24 top LUAD |
1012
- | S1-B·R3a | PHYLO-RNA | lncRNA-TREM2 | CYTOR→AKT1 |
1013
- | S1-C·R1a | PHYLO-DRUG | FGFR3 drug | score=0.793 |
1014
- | S1-D·R1a | PHYLO-LNP | Corona | AUC=0.791 |
1015
- | S1-D·R2a | PHYLO-LNP | Flow Vroman | 3–4× faster |
1016
- | S1-D·R3a | PHYLO-LNP | LNP Brain | pKa 6.2–6.8 |
1017
- | S1-E·R1a | PHYLO-BIOMARKERS | Liquid Biopsy | AUC=0.992* |
1018
- | S1-D·R4a | PHYLO-LNP | AutoCorona NLP | F1=0.71 |
1019
- """)
1020
-
1021
- gr.Markdown(
1022
- "---\n**K R&D Lab** · Science Sphere · S1 Biomedical · "
1023
- "[GitHub](https://github.com/K-RnD-Lab) · "
1024
- "[HuggingFace](https://huggingface.co/K-RnD-Lab) · "
1025
- "[KOSATIKS GROUP 🦈](https://kosatiks-group.pp.ua) · MIT License"
1026
- )
1027
-
1028
- demo.queue()
1029
  demo.launch()
 
9
  from PIL import Image
10
  from datetime import datetime
11
  from pathlib import Path
 
12
 
13
+ # ... (тут ваші кольори, логування, бази даних та функції – без змін)
14
+
15
+ with gr.Blocks(title="K R&D Lab") as demo:
16
+ gr.Markdown("# K R&D Lab")
17
+ with gr.Tabs():
18
+ with gr.TabItem("S1-A · R1a · OpenVariant"):
19
+ hgvs = gr.Textbox(label="HGVS")
20
+ sift = gr.Slider(0,1,value=0.5,label="SIFT")
21
+ pp = gr.Slider(0,1,value=0.5,label="PolyPhen")
22
+ gn = gr.Slider(0,0.01,value=0.001,label="gnomAD")
23
+ btn = gr.Button("Predict")
24
+ out = gr.HTML()
25
+ btn.click(predict_variant, [hgvs,sift,pp,gn], out)
26
+ with gr.TabItem("S1-B · R1a · miRNA"):
27
+ gene = gr.Dropdown(["BRCA2","BRCA1","TP53"], value="BRCA2", label="Gene")
28
+ btn2 = gr.Button("Find")
29
+ out2 = gr.Dataframe()
30
+ btn2.click(predict_mirna, [gene], out2)
31
+ # ... інші вкладки аналогічно, але без вкладених Tabs
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  demo.launch()