TEZv commited on
Commit
ae37db2
·
verified ·
1 Parent(s): 8c0ab49

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +409 -380
app.py CHANGED
@@ -221,7 +221,6 @@ def safe_img_from_fig(fig):
221
  return img
222
  except Exception:
223
  plt.close(fig)
224
- # Return a blank image as fallback
225
  return Image.new('RGB', (100, 100), color=CARD)
226
 
227
  def predict_mirna(gene):
@@ -517,7 +516,7 @@ def proj_badge(code, title, metric=""):
517
  f"</div>"
518
  )
519
 
520
- # ========== 3D моделі (функції) ==========
521
  def plot_nanoparticle(r, peg):
522
  theta = np.linspace(0, 2*np.pi, 30)
523
  phi = np.linspace(0, np.pi, 30)
@@ -594,8 +593,8 @@ def plot_corona():
594
  css = f"""
595
  body, .gradio-container {{ background: {BG} !important; color: {TXT} !important; }}
596
 
597
- /* OUTER tab bar — PHYLO categories (S1-A, S1-B, ...) */
598
- .outer-tabs .tab-nav button {{
599
  color: {TXT} !important;
600
  background: {CARD} !important;
601
  font-size: 13px !important;
@@ -603,14 +602,14 @@ body, .gradio-container {{ background: {BG} !important; color: {TXT} !important;
603
  padding: 8px 16px !important;
604
  border-radius: 6px 6px 0 0 !important;
605
  }}
606
- .outer-tabs .tab-nav button.selected {{
607
  border-bottom: 3px solid {ACC} !important;
608
  color: {ACC} !important;
609
  background: {BG} !important;
610
  }}
611
 
612
- /* INNER sub-tab bar R1, R2, R3 (напрямки) */
613
- .inner-tabs .tab-nav button {{
614
  color: {DIM} !important;
615
  background: {BG} !important;
616
  font-size: 12px !important;
@@ -621,32 +620,58 @@ body, .gradio-container {{ background: {BG} !important; color: {TXT} !important;
621
  border-bottom: none !important;
622
  margin-right: 3px !important;
623
  }}
624
- .inner-tabs .tab-nav button.selected {{
625
  color: {ACC2} !important;
626
  background: {CARD} !important;
627
  border-color: {ACC2} !important;
628
  border-bottom: none !important;
629
  }}
630
- .inner-tabs > .tabitem {{
631
  background: {CARD} !important;
632
  border: 1px solid {BORDER} !important;
633
  border-radius: 0 6px 6px 6px !important;
634
  padding: 14px !important;
635
  }}
636
 
637
- /* Третій рівень вкладок a, b (експерименти) */
638
- .sub-sub-tabs .tab-nav button {{
639
- color: {DIM} !important;
640
- background: {CARD} !important;
641
- font-size: 11px !important;
642
- padding: 3px 8px !important;
643
- border-radius: 3px 3px 0 0 !important;
644
  }}
645
- .sub-sub-tabs .tab-nav button.selected {{
646
- color: {ACC} !important;
647
- background: {BG} !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  }}
649
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
  h1, h2, h3 {{ color: {ACC} !important; }}
651
  .gr-button-primary {{ background: {ACC} !important; border: none !important; }}
652
  footer {{ display: none !important; }}
@@ -691,7 +716,7 @@ MAP_HTML = f"""
691
  </div>
692
  """
693
 
694
- # ========== ІНТЕРФЕЙС З ТРЬОМА РІВНЯМИ ВКЛАДОК ==========
695
  with gr.Blocks(css=css, title="K R&D Lab · S1 Biomedical") as demo:
696
  gr.Markdown(
697
  "# 🔬 K R&D Lab · Science Sphere — S1 Biomedical\n"
@@ -699,384 +724,372 @@ with gr.Blocks(css=css, title="K R&D Lab · S1 Biomedical") as demo:
699
  "*Research only. Not clinical advice.*"
700
  )
701
 
702
- with gr.Tabs(elem_classes="outer-tabs"):
703
- # 🗺️ Lab Map
704
- with gr.TabItem("🗺️ Lab Map"):
705
- gr.HTML(MAP_HTML)
706
-
707
- # === S1-A · PHYLO-GENOMICS ===
708
- with gr.TabItem("🧬 S1-A PHYLO-GENOMICS"):
709
- gr.HTML(section_header(
710
- "S1-A", "PHYLO-GENOMICS", "— What breaks in DNA",
711
- "R1a OpenVariant ✅ &nbsp;·&nbsp; R1b Somatic classifier 🔶"
712
- ))
713
- with gr.Tabs(elem_classes="inner-tabs"):
714
- with gr.TabItem("R1 · Variant classification"):
715
- with gr.Tabs(elem_classes="sub-sub-tabs"):
716
- # R1a · OpenVariant
717
- with gr.TabItem("R1a · OpenVariant"):
718
- gr.HTML(proj_badge("S1-A · R1a", "OpenVariant — SNV Pathogenicity Classifier", "AUC=0.939"))
719
- hgvs = gr.Textbox(label="HGVS notation", placeholder="BRCA1:p.R1699Q")
720
- gr.Markdown("**Or enter functional scores manually:**")
721
- with gr.Row():
722
- sift = gr.Slider(0,1,value=0.5,step=0.01,label="SIFT (0=damaging)")
723
- pp = gr.Slider(0,1,value=0.5,step=0.01,label="PolyPhen-2")
724
- gn = gr.Slider(0,0.01,value=0.001,step=0.0001,label="gnomAD AF")
725
- b_v = gr.Button("Predict Pathogenicity", variant="primary")
726
- o_v = gr.HTML()
727
- gr.Examples([["BRCA1:p.R1699Q",0.82,0.05,0.0012],
728
- ["TP53:p.R248W",0.00,1.00,0.0],
729
- ["BRCA2:p.D2723A",0.01,0.98,0.0]], inputs=[hgvs,sift,pp,gn], cache_examples=False)
730
- b_v.click(predict_variant, [hgvs,sift,pp,gn], o_v)
731
- # R1b · Somatic Classifier (в розробці)
732
- with gr.TabItem("R1b · Somatic Classifier 🔶"):
733
- gr.HTML(proj_badge("S1-A · R1b", "Somatic Mutation Classifier", "🔶 In progress"))
734
- gr.Markdown("> This module is in active development. Coming in the next release.")
735
-
736
- # === S1-B · PHYLO-RNA ===
737
- with gr.TabItem("🔬 S1-B PHYLO-RNA"):
738
- gr.HTML(section_header(
739
- "S1-B", "PHYLO-RNA", "— How to silence it via RNA",
740
- "R1a miRNA ✅ &nbsp;·&nbsp; R2a siRNA ✅ &nbsp;·&nbsp; R3a lncRNA ✅ &nbsp;·&nbsp; R3b ASO ✅"
741
- ))
742
- with gr.Tabs(elem_classes="inner-tabs"):
743
- # R1 · miRNA silencing
744
- with gr.TabItem("R1 · miRNA silencing"):
745
- with gr.Tabs(elem_classes="sub-sub-tabs"):
746
- with gr.TabItem("R1a · BRCA2 miRNA"):
747
- gr.HTML(proj_badge("S1-B · R1a", "miRNA Silencing — BRCA1/2 · TP53"))
748
- g1 = gr.Dropdown(["BRCA2","BRCA1","TP53"], value="BRCA2", label="Gene")
749
- b1 = gr.Button("Find miRNAs", variant="primary")
750
- o1 = gr.Dataframe(label="Top 5 downregulated miRNAs")
751
- gr.Examples([["BRCA2"],["BRCA1"],["TP53"]], inputs=[g1])
752
- b1.click(predict_mirna, [g1], o1)
753
- # R2 · siRNA SL
754
- with gr.TabItem("R2 · siRNA SL"):
755
- with gr.Tabs(elem_classes="sub-sub-tabs"):
756
- with gr.TabItem("R2a · TP53 siRNA"):
757
- gr.HTML(proj_badge("S1-B · R2a", "siRNA Synthetic Lethal — TP53-null"))
758
- g2 = gr.Dropdown(["LUAD","BRCA","COAD"], value="LUAD", label="Cancer type")
759
- b2 = gr.Button("Find Targets", variant="primary")
760
- o2 = gr.Dataframe(label="Top 5 synthetic lethal targets")
761
- gr.Examples([["LUAD"],["BRCA"],["COAD"]], inputs=[g2], cache_examples=False)
762
- b2.click(predict_sirna, [g2], o2)
763
- # R3 · lncRNA + ASO
764
- with gr.TabItem("R3 · lncRNA + ASO"):
765
- with gr.Tabs(elem_classes="sub-sub-tabs"):
766
- with gr.TabItem("R3a · lncRNA-TREM2"):
767
- gr.HTML(proj_badge("S1-B · R3a", "lncRNA-TREM2 ceRNA Network"))
768
- b3a = gr.Button("Load ceRNA", variant="primary")
769
- o3a = gr.Dataframe(label="ceRNA Network (R3a)")
770
- b3a.click(lambda: pd.DataFrame(CERNA), [], o3a)
771
- with gr.TabItem("R3b · ASO Designer"):
772
- gr.HTML(proj_badge("S1-B · R3b", "ASO Designer"))
773
- b3b = gr.Button("Load ASO Candidates", variant="primary")
774
- o3b = gr.Dataframe(label="ASO Candidates (R3b)")
775
- b3b.click(lambda: pd.DataFrame(ASO), [], o3b)
776
 
777
- # === S1-C · PHYLO-DRUG ===
778
- with gr.TabItem("💊 S1-C PHYLO-DRUG"):
779
- gr.HTML(section_header(
780
- "S1-C", "PHYLO-DRUG", "— Which molecule treats it",
781
- "R1a FGFR3&nbsp;·&nbsp; R1b SL drug mapping 🔶 &nbsp;·&nbsp; R2a m6A×Ferroptosis×Circadian 🔴⭐"
782
- ))
783
- with gr.Tabs(elem_classes="inner-tabs"):
784
- # R1 · RNA-directed drug
785
- with gr.TabItem("R1 · RNA-directed drug"):
786
- with gr.Tabs(elem_classes="sub-sub-tabs"):
787
- with gr.TabItem("R1a · FGFR3 RNA Drug"):
788
- gr.HTML(proj_badge("S1-C · R1a", "FGFR3 RNA-Directed Drug Discovery", "top score 0.793"))
789
- g4 = gr.Radio(["P1 (hairpin loop)","P10 (G-quadruplex)"],
790
- value="P1 (hairpin loop)", label="Target pocket")
791
- b4_drug = gr.Button("Screen Compounds", variant="primary")
792
- o4t = gr.Dataframe(label="Top 5 candidates")
793
- o4p = gr.Image(label="Binding scores")
794
- gr.Examples([["P1 (hairpin loop)"],["P10 (G-quadruplex)"]], inputs=[g4])
795
- b4_drug.click(predict_drug, [g4], [o4t, o4p])
796
- with gr.TabItem("R1b · SL Drug Mapping 🔶"):
797
- gr.HTML(proj_badge("S1-C · R1b", "Synthetic Lethal Drug Mapping", "🔶 In progress"))
798
- gr.Markdown("> In development. Coming soon.")
799
- # R2 · Frontier
800
- with gr.TabItem("R2 · Frontier"):
801
- with gr.Tabs(elem_classes="sub-sub-tabs"):
802
- with gr.TabItem("R2a · m6A×Ferroptosis×Circadian 🔴⭐"):
803
- gr.HTML(proj_badge("S1-C · R2a", "m6A × Ferroptosis × Circadian", "🔴 Frontier"))
804
- gr.Markdown(
805
- "> **Research gap:** This triple intersection has never been studied as an integrated system.\n\n"
806
- "> **Planned datasets:** TCGA-PAAD · GEO m6A atlases · Circadian gene panels\n\n"
807
- "> **Expected timeline:** Q3 2026"
808
- )
809
 
810
- # === S1-D · PHYLO-LNP ===
811
- with gr.TabItem("🧪 S1-D PHYLO-LNP"):
812
- gr.HTML(section_header(
813
- "S1-D", "PHYLO-LNP", "— How to deliver the drug",
814
- "R1a Corona ✅ · R2a Flow ✅ · R3a Brain ✅ · R4a NLP · R5a CSF/BM 🔴⭐"
815
- ))
816
- with gr.Tabs(elem_classes="inner-tabs"):
817
- # R1 · Serum corona
818
- with gr.TabItem("R1 · Serum corona"):
819
- with gr.Tabs(elem_classes="sub-sub-tabs"):
820
- with gr.TabItem("R1a · LNP Corona ML"):
821
- gr.HTML(proj_badge("S1-D · R1a", "LNP Protein Corona (Serum)", "AUC=0.791"))
822
- with gr.Row():
823
- sz = gr.Slider(50,300,value=100,step=1,label="Size (nm)")
824
- zt = gr.Slider(-40,10,value=-5,step=1,label="Zeta (mV)")
825
- with gr.Row():
826
- pg = gr.Slider(0,5,value=1.5,step=0.1,label="PEG mol%")
827
- lp = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Lipid type")
828
- b6 = gr.Button("Predict", variant="primary")
829
- o6 = gr.Markdown()
830
- gr.Examples([[100,-5,1.5,"Ionizable"],[80,5,0.5,"Cationic"]], inputs=[sz,zt,pg,lp])
831
- b6.click(predict_corona, [sz,zt,pg,lp], o6)
832
- # R2 · Flow corona
833
- with gr.TabItem("R2 · Flow corona"):
834
- with gr.Tabs(elem_classes="sub-sub-tabs"):
835
- with gr.TabItem("R2a · Flow Corona"):
836
- gr.HTML(proj_badge("S1-D · R2a", "Flow Corona — Vroman Effect"))
837
- with gr.Row():
838
- s8 = gr.Slider(50,300,value=100,step=1,label="Size (nm)")
839
- z8 = gr.Slider(-40,10,value=-5,step=1,label="Zeta (mV)")
840
- pg8 = gr.Slider(0,5,value=1.5,step=0.1,label="PEG mol%")
841
- with gr.Row():
842
- ch8 = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Charge")
843
- fl8 = gr.Slider(0,40,value=20,step=1,label="Flow cm/s (aorta=40)")
844
- b8 = gr.Button("Model Vroman Effect", variant="primary")
845
- o8t = gr.Markdown()
846
- o8p = gr.Image(label="Kinetics")
847
- gr.Examples([[100,-5,1.5,"Ionizable",40],[150,5,0.5,"Cationic",10]], inputs=[s8,z8,pg8,ch8,fl8])
848
- b8.click(predict_flow, [s8,z8,pg8,ch8,fl8], [o8t,o8p])
849
- # R3 · Brain BBB
850
- with gr.TabItem("R3 · Brain BBB"):
851
- with gr.Tabs(elem_classes="sub-sub-tabs"):
852
- with gr.TabItem("R3a · LNP Brain"):
853
- gr.HTML(proj_badge("S1-D · R3a", "LNP Brain Delivery"))
854
- smi = gr.Textbox(label="Ionizable lipid SMILES",
855
- value="CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C")
856
- with gr.Row():
857
- pk = gr.Slider(4,8,value=6.5,step=0.1,label="pKa")
858
- zt9 = gr.Slider(-20,10,value=-3,step=1,label="Zeta (mV)")
859
- b9 = gr.Button("Predict BBB Crossing", variant="primary")
860
- o9t = gr.Markdown()
861
- o9p = gr.Image(label="Radar profile")
862
- gr.Examples([["CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C",6.5,-3]], inputs=[smi,pk,zt9])
863
- b9.click(predict_bbb, [smi,pk,zt9], [o9t,o9p])
864
- # R4 · NLP
865
- with gr.TabItem("R4 · NLP"):
866
- with gr.Tabs(elem_classes="sub-sub-tabs"):
867
- with gr.TabItem("R4a · AutoCorona NLP"):
868
- gr.HTML(proj_badge("S1-D · R4a", "AutoCorona NLP", "F1=0.71"))
869
- txt = gr.Textbox(lines=5,label="Paper abstract",placeholder="Paste abstract here...")
870
- b10 = gr.Button("Extract Data", variant="primary")
871
- o10j = gr.Code(label="Extracted JSON", language="json")
872
- o10f = gr.Textbox(label="Validation flags")
873
- gr.Examples([[
874
- "LNPs composed of MC3, DSPC, Cholesterol (50:10:40 mol%) with 1.5% PEG-DMG. "
875
- "Hydrodynamic diameter was 98 nm, zeta potential -3.2 mV, PDI 0.12. "
876
- "Incubated in human plasma. Corona: albumin, apolipoprotein E, fibrinogen."
877
- ]], inputs=[txt])
878
- b10.click(extract_corona, txt, [o10j, o10f])
879
- # R5 · Exotic fluids
880
- with gr.TabItem("R5 · Exotic fluids 🔴⭐"):
881
- with gr.Tabs(elem_classes="sub-sub-tabs"):
882
- with gr.TabItem("R5a · CSF/Vitreous/BM"):
883
- gr.HTML(proj_badge("S1-D · R5a", "LNP Corona in CSF · Vitreous · Bone Marrow", "🔴 0 prior studies"))
884
- gr.Markdown(
885
- "> **Research gap:** Protein corona has only been characterized in serum/plasma. "
886
- "CSF, vitreous humor, and bone marrow interstitial fluid remain completely unstudied.\n\n"
887
- "> **Target cancers:** DIPG (CSF) · UVM (vitreous) · pAML (bone marrow)\n\n"
888
- "> **Expected timeline:** Q2–Q3 2026"
889
- )
890
 
891
- # === S1-E · PHYLO-BIOMARKERS ===
892
- with gr.TabItem("🩸 S1-E PHYLO-BIOMARKERS"):
893
- gr.HTML(section_header(
894
- "S1-E", "PHYLO-BIOMARKERS", "— Detect without biopsy",
895
- "R1a Liquid Biopsy &nbsp;·&nbsp; R1b Protein validator 🔶"
896
- ))
897
- with gr.Tabs(elem_classes="inner-tabs"):
898
- with gr.TabItem("R1 · Liquid biopsy"):
899
- with gr.Tabs(elem_classes="sub-sub-tabs"):
900
- with gr.TabItem("R1a · Liquid Biopsy"):
901
- gr.HTML(proj_badge("S1-E · R1a", "Liquid Biopsy Classifier", "AUC=0.992*"))
902
- with gr.Row():
903
- p1=gr.Slider(-3,3,value=0,step=0.1,label="CTHRC1")
904
- p2=gr.Slider(-3,3,value=0,step=0.1,label="FHL2")
905
- p3=gr.Slider(-3,3,value=0,step=0.1,label="LDHA")
906
- p4=gr.Slider(-3,3,value=0,step=0.1,label="P4HA1")
907
- p5=gr.Slider(-3,3,value=0,step=0.1,label="SERPINH1")
908
- with gr.Row():
909
- p6=gr.Slider(-3,3,value=0,step=0.1,label="ABCA8")
910
- p7=gr.Slider(-3,3,value=0,step=0.1,label="CA4")
911
- p8=gr.Slider(-3,3,value=0,step=0.1,label="CKB")
912
- p9=gr.Slider(-3,3,value=0,step=0.1,label="NNMT")
913
- p10=gr.Slider(-3,3,value=0,step=0.1,label="CACNA2D2")
914
- b7=gr.Button("Classify", variant="primary")
915
- o7t=gr.HTML()
916
- o7p=gr.Image(label="Feature contributions")
917
- gr.Examples([[2,2,1.5,1.8,1.6,-1,-1.2,-0.8,1.4,-1.1],[0]*10],
918
- inputs=[p1,p2,p3,p4,p5,p6,p7,p8,p9,p10])
919
- b7.click(predict_cancer, [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10], [o7t,o7p])
920
- with gr.TabItem("R1b · Protein Validator 🔶"):
921
- gr.HTML(proj_badge("S1-E · R1b", "Protein Panel Validator", "🔶 In progress"))
922
- gr.Markdown("> Coming next — validates R1a results against GEO plasma proteomics datasets.")
923
 
924
- # === S1-F · PHYLO-RARE ===
925
- with gr.TabItem("🧠 S1-F PHYLO-RARE"):
926
- gr.HTML(section_header(
927
- "S1-F", "PHYLO-RARE", "— Where almost nobody has looked yet",
928
- "<b style='color:#ef4444'>⚠️ <300 cases/yr · <5% survival · 0–1 prior studies per gap</b><br>"
929
- "R1a DIPG 🔶 &nbsp;·&nbsp; R2a UVM 🔶 &nbsp;·&nbsp; R3a pAML 🔶"
930
- ))
931
- with gr.Tabs(elem_classes="inner-tabs"):
932
- # R1 · DIPG
933
- with gr.TabItem("R1 · DIPG"):
934
- with gr.Tabs(elem_classes="sub-sub-tabs"):
935
- with gr.TabItem("R1a · DIPG Toolkit"):
936
- gr.HTML(proj_badge("S1-F · R1a", "DIPG Toolkit", "PBTA · GSE126319"))
937
- gr.Markdown(
938
- "> **Why DIPG?** Diffuse Intrinsic Pontine Glioma — median survival 9–11 months. "
939
- "H3K27M oncohistone in **78%** cases. "
940
- "CSF delivery is the only viable route past the brainstem BBB. "
941
- "Circadian disruption (BMAL1 suppression) newly linked — **0 prior LNP studies**."
942
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
943
  with gr.Tabs():
944
- with gr.TabItem("Variants"):
945
- sort_d = gr.Radio(["Frequency", "Drug status"], value="Frequency", label="Sort by")
946
- b_dv = gr.Button("Load DIPG Variants", variant="primary")
947
- o_dv = gr.Dataframe(label="H3K27M co-mutations · PBTA/GSE126319")
948
- b_dv.click(dipg_variants, [sort_d], o_dv)
949
- with gr.TabItem("CSF LNP"):
950
  with gr.Row():
951
- d_peg = gr.Slider(0.5, 3.0, value=1.5, step=0.1, label="PEG mol%")
952
- d_size = gr.Slider(60, 150, value=90, step=5, label="Target size (nm)")
953
- b_dc = gr.Button("Rank CSF Formulations", variant="primary")
954
- o_dct = gr.Dataframe(label="CSF LNP ranking")
955
- o_dcp = gr.Image(label="ApoE% in CSF corona")
956
- b_dc.click(dipg_csf, [d_peg, d_size], [o_dct, o_dcp])
957
- with gr.TabItem("Research Gap"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
958
  gr.Markdown(
959
- "**Data:** PBTA (n=240) · GSE126319 (n=28) · GTEx circadian genes\n\n"
960
- "| Layer | Known | This study gap |\n"
961
- "|-------|-------|----------------|\n"
962
- "| Genomics | H3K27M freq=78% | H3K27M × BMAL1/CLOCK |\n"
963
- "| Delivery | CED convection | LNP corona **in CSF** |\n"
964
- "| Biology | PRC2 inhibition | Ferroptosis in H3K27M+ DIPG |"
965
  )
966
- # R2 · UVM
967
- with gr.TabItem("R2 · UVM"):
968
- with gr.Tabs(elem_classes="sub-sub-tabs"):
969
- with gr.TabItem("R2a · UVM Toolkit"):
970
- gr.HTML(proj_badge("S1-F · R2a", "UVM Toolkit", "TCGA-UVM n=80"))
971
- gr.Markdown(
972
- "> **Why UVM?** Uveal Melanoma — metastatic 5-yr survival **15%**. "
973
- "GNAQ/GNA11 mutations in 78% cases. "
974
- "Vitreous humor protein corona has **never been profiled**. "
975
- "METTL3/WTAP upregulated in GNAQ+ tumors — 0 therapeutic studies."
976
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977
  with gr.Tabs():
978
- with gr.TabItem("Variants + m6A"):
979
- b_uv = gr.Button("Load UVM Variants", variant="primary")
980
- o_uv = gr.Dataframe(label="GNAQ/GNA11 map · TCGA-UVM")
981
- b_uv.click(uvm_variants, [], o_uv)
982
- with gr.TabItem("Vitreous LNP"):
983
- b_uw = gr.Button("Rank Vitreous Formulations", variant="primary")
984
- o_uwt = gr.Dataframe(label="Vitreous LNP retention ranking")
985
- o_uwp = gr.Image(label="Retention (hours)")
986
- b_uw.click(uvm_vitreous, [], [o_uwt, o_uwp])
987
- with gr.TabItem("Research Gap"):
988
  gr.Markdown(
989
- "**Data:** TCGA-UVM (n=80) · GEO m6A atlases · Vitreous proteomics\n\n"
990
- "| Layer | Known | This study gap |\n"
991
- "|-------|-------|----------------|\n"
992
- "| Genomics | GNAQ/GNA11 mutations | m6A landscape GNAQ+ vs GNA11+ |\n"
993
- "| Delivery | Intravitreal injection | LNP corona **in vitreous humor** |\n"
994
- "| Biology | PLCβ→PKC→MAPK | GNAQ × METTL3 × YTHDF2 axis |"
995
  )
996
- # R3 · pAML
997
- with gr.TabItem("R3 · pAML"):
998
- with gr.Tabs(elem_classes="sub-sub-tabs"):
999
- with gr.TabItem("R3a · pAML Toolkit"):
1000
- gr.HTML(proj_badge("S1-F · R3a", "pAML Toolkit", "TARGET-AML n≈197"))
1001
- gr.Markdown(
1002
- "> **Why pAML?** Pediatric AML — relapse OS **<30%**. "
1003
- "FLT3-ITD in 25% cases. "
1004
- "Bone marrow niche LNP corona: **never studied**. "
1005
- "Ferroptosis–FLT3 intersection: 0 prior studies (FerrDb v2 confirmed)."
1006
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1007
  with gr.Tabs():
1008
- with gr.TabItem("Ferroptosis Explorer"):
1009
- var_sel = gr.Dropdown(
1010
- ["FLT3-ITD", "NPM1 c.860_863dupTCAG", "DNMT3A p.R882H",
1011
- "CEBPA biallelic", "IDH1/2 mutation"],
1012
- value="FLT3-ITD", label="Select variant"
1013
- )
1014
- b_pf = gr.Button("Analyze Ferroptosis Profile", variant="primary")
1015
- o_pft = gr.HTML()
1016
- o_pfp = gr.Image(label="Target radar")
1017
- b_pf.click(paml_ferroptosis, var_sel, [o_pft, o_pfp])
1018
- with gr.TabItem("BM Niche LNP"):
1019
- gr.Dataframe(
1020
- value=pd.DataFrame(PAML_BM_LNP),
1021
- label="Bone marrow niche LNP candidates · TARGET-AML context"
1022
  )
1023
- with gr.TabItem("Research Gap"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
  gr.Markdown(
1025
- "**Data:** TARGET-AML (n=197) · BeatAML · FerrDb v2\n\n"
1026
- "| Layer | Known | This study gap |\n"
1027
- "|-------|-------|----------------|\n"
1028
- "| Genomics | FLT3-ITD Midostaurin | FLT3-ITD × GPX4/SLC7A11 |\n"
1029
- "| Delivery | Liposomal daunorubicin | LNP corona **in bone marrow** |\n"
1030
- "| Biology | Midostaurin inhibits FLT3 | Ferroptosis SL + FLT3i |"
1031
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1032
 
1033
- # === S1-G · 3D Lab (НОВА ВКЛАДКА) ===
1034
- with gr.TabItem("🧊 3D Lab"):
1035
- gr.HTML(section_header(
1036
- "S1-G", "PHYLO-SIM", "— 3D Models & Simulations",
1037
- "Interactive visualizations for learning"
1038
- ))
1039
- with gr.Tabs(elem_classes="inner-tabs"):
1040
- with gr.TabItem("Nanoparticle"):
1041
- gr.Markdown("### 3D Model of a Lipid Nanoparticle")
1042
- with gr.Row():
1043
- np_radius = gr.Slider(2, 20, value=5, step=1, label="Radius (nm)")
1044
- np_peg = gr.Slider(0, 1, value=0.3, step=0.05, label="PEG density")
1045
- np_btn = gr.Button("Generate", variant="primary")
1046
- np_plot = gr.Plot(label="Nanoparticle")
1047
- np_btn.click(plot_nanoparticle, [np_radius, np_peg], np_plot)
1048
-
1049
- with gr.TabItem("DNA Helix"):
1050
- gr.Markdown("### 3D Model of a DNA Double Helix")
1051
- dna_btn = gr.Button("Generate DNA", variant="primary")
1052
- dna_plot = gr.Plot()
1053
- dna_btn.click(plot_dna, [], dna_plot)
1054
 
1055
- with gr.TabItem("Protein Corona"):
1056
- gr.Markdown("### Schematic of Protein Corona on Nanoparticle")
1057
- corona_btn = gr.Button("Show Corona", variant="primary")
1058
- corona_plot = gr.Plot()
1059
- corona_btn.click(plot_corona, [], corona_plot)
1060
 
1061
- # === Journal (покращений) ===
1062
- with gr.TabItem("📓 Journal"):
1063
- gr.Markdown("### Lab Journal")
1064
- with gr.Row():
1065
- note_text = gr.Textbox(label="📝 Observation", placeholder="What did you discover?", lines=3)
1066
- note_tab = gr.Textbox(label="Project code (e.g. S1-A·R1a)", value="General")
1067
- with gr.Row():
1068
- save_btn = gr.Button("💾 Save", variant="primary")
1069
- refresh_btn = gr.Button("🔄 Refresh")
1070
- clear_btn = gr.Button("🗑️ Clear Journal", variant="secondary")
1071
- journal_display = gr.Markdown(value=load_journal())
1072
-
1073
- save_btn.click(save_note, [note_text, note_tab], journal_display)
1074
- refresh_btn.click(load_journal, [], journal_display)
1075
- clear_btn.click(clear_journal, [], journal_display)
1076
 
1077
- # === Learning ===
1078
- with gr.TabItem("📚 Learning"):
1079
- gr.Markdown("""
1080
  ## 🧪 Guided Investigations
1081
  > 🟢 Beginner → 🟡 Intermediate → 🔴 Advanced
1082
 
@@ -1086,7 +1099,23 @@ with gr.Blocks(css=css, title="K R&D Lab · S1 Biomedical") as demo:
1086
  **S1-B · R2a** siRNA – count "Novel" targets across cancer types
1087
  **S1-E · R1a** Liquid Biopsy – find minimal signal for CANCER
1088
  **S1-G · 3D Lab** – explore nanoparticle, DNA, and protein corona models
1089
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
 
1091
  gr.Markdown(
1092
  "---\n**K R&D Lab** · MIT License · "
 
221
  return img
222
  except Exception:
223
  plt.close(fig)
 
224
  return Image.new('RGB', (100, 100), color=CARD)
225
 
226
  def predict_mirna(gene):
 
516
  f"</div>"
517
  )
518
 
519
+ # ========== 3D моделі ==========
520
  def plot_nanoparticle(r, peg):
521
  theta = np.linspace(0, 2*np.pi, 30)
522
  phi = np.linspace(0, np.pi, 30)
 
593
  css = f"""
594
  body, .gradio-container {{ background: {BG} !important; color: {TXT} !important; }}
595
 
596
+ /* Вкладки верхнього рівня (категорії) */
597
+ .tabs-outer .tab-nav button {{
598
  color: {TXT} !important;
599
  background: {CARD} !important;
600
  font-size: 13px !important;
 
602
  padding: 8px 16px !important;
603
  border-radius: 6px 6px 0 0 !important;
604
  }}
605
+ .tabs-outer .tab-nav button.selected {{
606
  border-bottom: 3px solid {ACC} !important;
607
  color: {ACC} !important;
608
  background: {BG} !important;
609
  }}
610
 
611
+ /* Контейнер вкладок всередині основної колонки */
612
+ .main-tabs .tab-nav button {{
613
  color: {DIM} !important;
614
  background: {BG} !important;
615
  font-size: 12px !important;
 
620
  border-bottom: none !important;
621
  margin-right: 3px !important;
622
  }}
623
+ .main-tabs .tab-nav button.selected {{
624
  color: {ACC2} !important;
625
  background: {CARD} !important;
626
  border-color: {ACC2} !important;
627
  border-bottom: none !important;
628
  }}
629
+ .main-tabs > .tabitem {{
630
  background: {CARD} !important;
631
  border: 1px solid {BORDER} !important;
632
  border-radius: 0 6px 6px 6px !important;
633
  padding: 14px !important;
634
  }}
635
 
636
+ /* Стиль для badges */
637
+ .proj-badge {{
638
+ background: {CARD};
639
+ border-left: 3px solid {ACC};
640
+ padding: 8px 12px;
641
+ border-radius: 0 6px 6px 0;
642
+ margin-bottom: 8px;
643
  }}
644
+ .proj-code {{
645
+ color: {DIM};
646
+ font-size: 11px;
647
+ }}
648
+ .proj-title {{
649
+ color: {TXT};
650
+ font-size: 14px;
651
+ font-weight: 600;
652
+ }}
653
+ .proj-metric {{
654
+ background: #0f2a3f;
655
+ color: {ACC2};
656
+ padding: 1px 7px;
657
+ border-radius: 3px;
658
+ font-size: 10px;
659
+ margin-left: 6px;
660
  }}
661
 
662
+ /* Журнал */
663
+ .journal {{
664
+ background: {CARD};
665
+ border: 1px solid {BORDER};
666
+ border-radius: 8px;
667
+ padding: 14px;
668
+ }}
669
+ .journal h3 {{
670
+ color: {ACC};
671
+ margin-top: 0;
672
+ }}
673
+
674
+ /* Загальні */
675
  h1, h2, h3 {{ color: {ACC} !important; }}
676
  .gr-button-primary {{ background: {ACC} !important; border: none !important; }}
677
  footer {{ display: none !important; }}
 
716
  </div>
717
  """
718
 
719
+ # ========== UI З ДВОМА КОЛОНКАМИ ==========
720
  with gr.Blocks(css=css, title="K R&D Lab · S1 Biomedical") as demo:
721
  gr.Markdown(
722
  "# 🔬 K R&D Lab · Science Sphere — S1 Biomedical\n"
 
724
  "*Research only. Not clinical advice.*"
725
  )
726
 
727
+ with gr.Row():
728
+ # Основна колонка з вкладками (ширша)
729
+ with gr.Column(scale=4):
730
+ with gr.Tabs(elem_classes="tabs-outer") as outer_tabs:
731
+ # 🗺️ Lab Map
732
+ with gr.TabItem("🗺️ Lab Map"):
733
+ gr.HTML(MAP_HTML)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
734
 
735
+ # === S1-A · PHYLO-GENOMICS ===
736
+ with gr.TabItem("🧬 S1-A · PHYLO-GENOMICS"):
737
+ gr.HTML(section_header(
738
+ "S1-A", "PHYLO-GENOMICS", "— What breaks in DNA",
739
+ "R1a OpenVariant ✅ · R1b Somatic classifier 🔶"
740
+ ))
741
+ with gr.Tabs(elem_classes="main-tabs"):
742
+ # R1 · Variant classification
743
+ with gr.TabItem("R1 · Variant classification"):
744
+ with gr.Tabs():
745
+ # R1a · OpenVariant
746
+ with gr.TabItem("R1a · OpenVariant"):
747
+ gr.HTML(proj_badge("S1-A · R1a", "OpenVariant — SNV Pathogenicity Classifier", "AUC=0.939"))
748
+ hgvs = gr.Textbox(label="HGVS notation", placeholder="BRCA1:p.R1699Q")
749
+ gr.Markdown("**Or enter functional scores manually:**")
750
+ with gr.Row():
751
+ sift = gr.Slider(0,1,value=0.5,step=0.01,label="SIFT (0=damaging)")
752
+ pp = gr.Slider(0,1,value=0.5,step=0.01,label="PolyPhen-2")
753
+ gn = gr.Slider(0,0.01,value=0.001,step=0.0001,label="gnomAD AF")
754
+ b_v = gr.Button("Predict Pathogenicity", variant="primary")
755
+ o_v = gr.HTML()
756
+ gr.Examples([["BRCA1:p.R1699Q",0.82,0.05,0.0012],
757
+ ["TP53:p.R248W",0.00,1.00,0.0],
758
+ ["BRCA2:p.D2723A",0.01,0.98,0.0]], inputs=[hgvs,sift,pp,gn], cache_examples=False)
759
+ b_v.click(predict_variant, [hgvs,sift,pp,gn], o_v)
760
+ # R1b · Somatic Classifier (в розробці)
761
+ with gr.TabItem("R1b · Somatic Classifier 🔶"):
762
+ gr.HTML(proj_badge("S1-A · R1b", "Somatic Mutation Classifier", "🔶 In progress"))
763
+ gr.Markdown("> This module is in active development. Coming in the next release.")
 
 
 
764
 
765
+ # === S1-B · PHYLO-RNA ===
766
+ with gr.TabItem("🔬 S1-B · PHYLO-RNA"):
767
+ gr.HTML(section_header(
768
+ "S1-B", "PHYLO-RNA", "— How to silence it via RNA",
769
+ "R1a miRNA ✅ · R2a siRNA ✅ · R3a lncRNA ✅ · R3b ASO ✅"
770
+ ))
771
+ with gr.Tabs(elem_classes="main-tabs"):
772
+ # R1 · miRNA silencing
773
+ with gr.TabItem("R1 · miRNA silencing"):
774
+ with gr.Tabs():
775
+ with gr.TabItem("R1a · BRCA2 miRNA"):
776
+ gr.HTML(proj_badge("S1-B · R1a", "miRNA Silencing BRCA1/2 · TP53"))
777
+ g1 = gr.Dropdown(["BRCA2","BRCA1","TP53"], value="BRCA2", label="Gene")
778
+ b1 = gr.Button("Find miRNAs", variant="primary")
779
+ o1 = gr.Dataframe(label="Top 5 downregulated miRNAs")
780
+ gr.Examples([["BRCA2"],["BRCA1"],["TP53"]], inputs=[g1])
781
+ b1.click(predict_mirna, [g1], o1)
782
+ # R2 · siRNA SL
783
+ with gr.TabItem("R2 · siRNA SL"):
784
+ with gr.Tabs():
785
+ with gr.TabItem("R2a · TP53 siRNA"):
786
+ gr.HTML(proj_badge("S1-B · R2a", "siRNA Synthetic Lethal — TP53-null"))
787
+ g2 = gr.Dropdown(["LUAD","BRCA","COAD"], value="LUAD", label="Cancer type")
788
+ b2 = gr.Button("Find Targets", variant="primary")
789
+ o2 = gr.Dataframe(label="Top 5 synthetic lethal targets")
790
+ gr.Examples([["LUAD"],["BRCA"],["COAD"]], inputs=[g2], cache_examples=False)
791
+ b2.click(predict_sirna, [g2], o2)
792
+ # R3 · lncRNA + ASO
793
+ with gr.TabItem("R3 · lncRNA + ASO"):
794
+ with gr.Tabs():
795
+ with gr.TabItem("R3a · lncRNA-TREM2"):
796
+ gr.HTML(proj_badge("S1-B · R3a", "lncRNA-TREM2 ceRNA Network"))
797
+ b3a = gr.Button("Load ceRNA", variant="primary")
798
+ o3a = gr.Dataframe(label="ceRNA Network (R3a)")
799
+ b3a.click(lambda: pd.DataFrame(CERNA), [], o3a)
800
+ with gr.TabItem("R3b · ASO Designer"):
801
+ gr.HTML(proj_badge("S1-B · R3b", "ASO Designer"))
802
+ b3b = gr.Button("Load ASO Candidates", variant="primary")
803
+ o3b = gr.Dataframe(label="ASO Candidates (R3b)")
804
+ b3b.click(lambda: pd.DataFrame(ASO), [], o3b)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
805
 
806
+ # === S1-C · PHYLO-DRUG ===
807
+ with gr.TabItem("💊 S1-C · PHYLO-DRUG"):
808
+ gr.HTML(section_header(
809
+ "S1-C", "PHYLO-DRUG", "— Which molecule treats it",
810
+ "R1a FGFR3 ✅ · R1b SL drug mapping 🔶 · R2a Frontier 🔴⭐"
811
+ ))
812
+ with gr.Tabs(elem_classes="main-tabs"):
813
+ # R1 · RNA-directed drug
814
+ with gr.TabItem("R1 · RNA-directed drug"):
815
+ with gr.Tabs():
816
+ with gr.TabItem("R1a · FGFR3 RNA Drug"):
817
+ gr.HTML(proj_badge("S1-C · R1a", "FGFR3 RNA-Directed Drug Discovery", "top score 0.793"))
818
+ g4 = gr.Radio(["P1 (hairpin loop)","P10 (G-quadruplex)"],
819
+ value="P1 (hairpin loop)", label="Target pocket")
820
+ b4_drug = gr.Button("Screen Compounds", variant="primary")
821
+ o4t = gr.Dataframe(label="Top 5 candidates")
822
+ o4p = gr.Image(label="Binding scores")
823
+ gr.Examples([["P1 (hairpin loop)"],["P10 (G-quadruplex)"]], inputs=[g4])
824
+ b4_drug.click(predict_drug, [g4], [o4t, o4p])
825
+ with gr.TabItem("R1b · SL Drug Mapping 🔶"):
826
+ gr.HTML(proj_badge("S1-C · R1b", "Synthetic Lethal Drug Mapping", "🔶 In progress"))
827
+ gr.Markdown("> In development. Coming soon.")
828
+ # R2 · Frontier
829
+ with gr.TabItem("R2 · Frontier"):
830
+ with gr.Tabs():
831
+ with gr.TabItem("R2a · m6A×Ferroptosis×Circadian 🔴⭐"):
832
+ gr.HTML(proj_badge("S1-C · R2a", "m6A × Ferroptosis × Circadian", "🔴 Frontier"))
833
+ gr.Markdown(
834
+ "> **Research gap:** This triple intersection has never been studied as an integrated system.\n\n"
835
+ "> **Planned datasets:** TCGA-PAAD · GEO m6A atlases · Circadian gene panels\n\n"
836
+ "> **Expected timeline:** Q3 2026"
837
+ )
838
 
839
+ # === S1-D · PHYLO-LNP ===
840
+ with gr.TabItem("🧪 S1-D · PHYLO-LNP"):
841
+ gr.HTML(section_header(
842
+ "S1-D", "PHYLO-LNP", "— How to deliver the drug",
843
+ "R1a Corona · R2a Flow ✅ · R3a Brain · R4a NLP · R5a CSF/BM 🔴⭐"
844
+ ))
845
+ with gr.Tabs(elem_classes="main-tabs"):
846
+ # R1 · Serum corona
847
+ with gr.TabItem("R1 · Serum corona"):
848
+ with gr.Tabs():
849
+ with gr.TabItem("R1a · LNP Corona ML"):
850
+ gr.HTML(proj_badge("S1-D · R1a", "LNP Protein Corona (Serum)", "AUC=0.791"))
851
+ with gr.Row():
852
+ sz = gr.Slider(50,300,value=100,step=1,label="Size (nm)")
853
+ zt = gr.Slider(-40,10,value=-5,step=1,label="Zeta (mV)")
854
+ with gr.Row():
855
+ pg = gr.Slider(0,5,value=1.5,step=0.1,label="PEG mol%")
856
+ lp = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Lipid type")
857
+ b6 = gr.Button("Predict", variant="primary")
858
+ o6 = gr.Markdown()
859
+ gr.Examples([[100,-5,1.5,"Ionizable"],[80,5,0.5,"Cationic"]], inputs=[sz,zt,pg,lp])
860
+ b6.click(predict_corona, [sz,zt,pg,lp], o6)
861
+ # R2 · Flow corona
862
+ with gr.TabItem("R2 · Flow corona"):
863
+ with gr.Tabs():
864
+ with gr.TabItem("R2a · Flow Corona"):
865
+ gr.HTML(proj_badge("S1-D · R2a", "Flow Corona — Vroman Effect"))
866
+ with gr.Row():
867
+ s8 = gr.Slider(50,300,value=100,step=1,label="Size (nm)")
868
+ z8 = gr.Slider(-40,10,value=-5,step=1,label="Zeta (mV)")
869
+ pg8 = gr.Slider(0,5,value=1.5,step=0.1,label="PEG mol%")
870
+ with gr.Row():
871
+ ch8 = gr.Dropdown(["Ionizable","Cationic","Anionic","Neutral"],value="Ionizable",label="Charge")
872
+ fl8 = gr.Slider(0,40,value=20,step=1,label="Flow cm/s (aorta=40)")
873
+ b8 = gr.Button("Model Vroman Effect", variant="primary")
874
+ o8t = gr.Markdown()
875
+ o8p = gr.Image(label="Kinetics")
876
+ gr.Examples([[100,-5,1.5,"Ionizable",40],[150,5,0.5,"Cationic",10]], inputs=[s8,z8,pg8,ch8,fl8])
877
+ b8.click(predict_flow, [s8,z8,pg8,ch8,fl8], [o8t,o8p])
878
+ # R3 · Brain BBB
879
+ with gr.TabItem("R3 · Brain BBB"):
880
  with gr.Tabs():
881
+ with gr.TabItem("R3a · LNP Brain"):
882
+ gr.HTML(proj_badge("S1-D · R3a", "LNP Brain Delivery"))
883
+ smi = gr.Textbox(label="Ionizable lipid SMILES",
884
+ value="CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C")
 
 
885
  with gr.Row():
886
+ pk = gr.Slider(4,8,value=6.5,step=0.1,label="pKa")
887
+ zt9 = gr.Slider(-20,10,value=-3,step=1,label="Zeta (mV)")
888
+ b9 = gr.Button("Predict BBB Crossing", variant="primary")
889
+ o9t = gr.Markdown()
890
+ o9p = gr.Image(label="Radar profile")
891
+ gr.Examples([["CC(C)CC(=O)OCC(COC(=O)CC(C)C)OC(=O)CC(C)C",6.5,-3]], inputs=[smi,pk,zt9])
892
+ b9.click(predict_bbb, [smi,pk,zt9], [o9t,o9p])
893
+ # R4 · NLP
894
+ with gr.TabItem("R4 · NLP"):
895
+ with gr.Tabs():
896
+ with gr.TabItem("R4a · AutoCorona NLP"):
897
+ gr.HTML(proj_badge("S1-D · R4a", "AutoCorona NLP", "F1=0.71"))
898
+ txt = gr.Textbox(lines=5,label="Paper abstract",placeholder="Paste abstract here...")
899
+ b10 = gr.Button("Extract Data", variant="primary")
900
+ o10j = gr.Code(label="Extracted JSON", language="json")
901
+ o10f = gr.Textbox(label="Validation flags")
902
+ gr.Examples([[
903
+ "LNPs composed of MC3, DSPC, Cholesterol (50:10:40 mol%) with 1.5% PEG-DMG. "
904
+ "Hydrodynamic diameter was 98 nm, zeta potential -3.2 mV, PDI 0.12. "
905
+ "Incubated in human plasma. Corona: albumin, apolipoprotein E, fibrinogen."
906
+ ]], inputs=[txt])
907
+ b10.click(extract_corona, txt, [o10j, o10f])
908
+ # R5 · Exotic fluids
909
+ with gr.TabItem("R5 · Exotic fluids 🔴⭐"):
910
+ with gr.Tabs():
911
+ with gr.TabItem("R5a · CSF/Vitreous/BM"):
912
+ gr.HTML(proj_badge("S1-D · R5a", "LNP Corona in CSF · Vitreous · Bone Marrow", "🔴 0 prior studies"))
913
  gr.Markdown(
914
+ "> **Research gap:** Protein corona has only been characterized in serum/plasma. "
915
+ "CSF, vitreous humor, and bone marrow interstitial fluid remain completely unstudied.\n\n"
916
+ "> **Target cancers:** DIPG (CSF) · UVM (vitreous) · pAML (bone marrow)\n\n"
917
+ "> **Expected timeline:** Q2–Q3 2026"
 
 
918
  )
919
+
920
+ # === S1-E · PHYLO-BIOMARKERS ===
921
+ with gr.TabItem("🩸 S1-E · PHYLO-BIOMARKERS"):
922
+ gr.HTML(section_header(
923
+ "S1-E", "PHYLO-BIOMARKERS", " Detect without biopsy",
924
+ "R1a Liquid Biopsy ✅ · R1b Protein validator 🔶"
925
+ ))
926
+ with gr.Tabs(elem_classes="main-tabs"):
927
+ with gr.TabItem("R1 · Liquid biopsy"):
928
+ with gr.Tabs():
929
+ with gr.TabItem("R1a · Liquid Biopsy"):
930
+ gr.HTML(proj_badge("S1-E · R1a", "Liquid Biopsy Classifier", "AUC=0.992*"))
931
+ with gr.Row():
932
+ p1=gr.Slider(-3,3,value=0,step=0.1,label="CTHRC1")
933
+ p2=gr.Slider(-3,3,value=0,step=0.1,label="FHL2")
934
+ p3=gr.Slider(-3,3,value=0,step=0.1,label="LDHA")
935
+ p4=gr.Slider(-3,3,value=0,step=0.1,label="P4HA1")
936
+ p5=gr.Slider(-3,3,value=0,step=0.1,label="SERPINH1")
937
+ with gr.Row():
938
+ p6=gr.Slider(-3,3,value=0,step=0.1,label="ABCA8")
939
+ p7=gr.Slider(-3,3,value=0,step=0.1,label="CA4")
940
+ p8=gr.Slider(-3,3,value=0,step=0.1,label="CKB")
941
+ p9=gr.Slider(-3,3,value=0,step=0.1,label="NNMT")
942
+ p10=gr.Slider(-3,3,value=0,step=0.1,label="CACNA2D2")
943
+ b7=gr.Button("Classify", variant="primary")
944
+ o7t=gr.HTML()
945
+ o7p=gr.Image(label="Feature contributions")
946
+ gr.Examples([[2,2,1.5,1.8,1.6,-1,-1.2,-0.8,1.4,-1.1],[0]*10],
947
+ inputs=[p1,p2,p3,p4,p5,p6,p7,p8,p9,p10])
948
+ b7.click(predict_cancer, [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10], [o7t,o7p])
949
+ with gr.TabItem("R1b · Protein Validator 🔶"):
950
+ gr.HTML(proj_badge("S1-E · R1b", "Protein Panel Validator", "🔶 In progress"))
951
+ gr.Markdown("> Coming next — validates R1a results against GEO plasma proteomics datasets.")
952
+
953
+ # === S1-F · PHYLO-RARE ===
954
+ with gr.TabItem("🧠 S1-F · PHYLO-RARE"):
955
+ gr.HTML(section_header(
956
+ "S1-F", "PHYLO-RARE", "�� Where almost nobody has looked yet",
957
+ "<b style='color:#ef4444'>⚠️ <300 cases/yr · <5% survival · 0–1 prior studies per gap</b><br>"
958
+ "R1a DIPG 🔶 · R2a UVM 🔶 · R3a pAML 🔶"
959
+ ))
960
+ with gr.Tabs(elem_classes="main-tabs"):
961
+ # R1 · DIPG
962
+ with gr.TabItem("R1 · DIPG"):
963
  with gr.Tabs():
964
+ with gr.TabItem("R1a · DIPG Toolkit"):
965
+ gr.HTML(proj_badge("S1-F · R1a", "DIPG Toolkit", "PBTA · GSE126319"))
 
 
 
 
 
 
 
 
966
  gr.Markdown(
967
+ "> **Why DIPG?** Diffuse Intrinsic Pontine Glioma median survival 9–11 months. "
968
+ "H3K27M oncohistone in **78%** cases. "
969
+ "CSF delivery is the only viable route past the brainstem BBB. "
970
+ "Circadian disruption (BMAL1 suppression) newly linked **0 prior LNP studies**."
 
 
971
  )
972
+ with gr.Tabs():
973
+ with gr.TabItem("Variants"):
974
+ sort_d = gr.Radio(["Frequency", "Drug status"], value="Frequency", label="Sort by")
975
+ b_dv = gr.Button("Load DIPG Variants", variant="primary")
976
+ o_dv = gr.Dataframe(label="H3K27M co-mutations · PBTA/GSE126319")
977
+ b_dv.click(dipg_variants, [sort_d], o_dv)
978
+ with gr.TabItem("CSF LNP"):
979
+ with gr.Row():
980
+ d_peg = gr.Slider(0.5, 3.0, value=1.5, step=0.1, label="PEG mol%")
981
+ d_size = gr.Slider(60, 150, value=90, step=5, label="Target size (nm)")
982
+ b_dc = gr.Button("Rank CSF Formulations", variant="primary")
983
+ o_dct = gr.Dataframe(label="CSF LNP ranking")
984
+ o_dcp = gr.Image(label="ApoE% in CSF corona")
985
+ b_dc.click(dipg_csf, [d_peg, d_size], [o_dct, o_dcp])
986
+ with gr.TabItem("Research Gap"):
987
+ gr.Markdown(
988
+ "**Data:** PBTA (n=240) · GSE126319 (n=28) · GTEx circadian genes\n\n"
989
+ "| Layer | Known | This study gap |\n"
990
+ "|-------|-------|----------------|\n"
991
+ "| Genomics | H3K27M freq=78% | H3K27M × BMAL1/CLOCK |\n"
992
+ "| Delivery | CED convection | LNP corona **in CSF** |\n"
993
+ "| Biology | PRC2 inhibition | Ferroptosis in H3K27M+ DIPG |"
994
+ )
995
+ # R2 · UVM
996
+ with gr.TabItem("R2 · UVM"):
997
  with gr.Tabs():
998
+ with gr.TabItem("R2a · UVM Toolkit"):
999
+ gr.HTML(proj_badge("S1-F · R2a", "UVM Toolkit", "TCGA-UVM n=80"))
1000
+ gr.Markdown(
1001
+ "> **Why UVM?** Uveal Melanoma — metastatic 5-yr survival **15%**. "
1002
+ "GNAQ/GNA11 mutations in 78% cases. "
1003
+ "Vitreous humor protein corona has **never been profiled**. "
1004
+ "METTL3/WTAP upregulated in GNAQ+ tumors — 0 therapeutic studies."
 
 
 
 
 
 
 
1005
  )
1006
+ with gr.Tabs():
1007
+ with gr.TabItem("Variants + m6A"):
1008
+ b_uv = gr.Button("Load UVM Variants", variant="primary")
1009
+ o_uv = gr.Dataframe(label="GNAQ/GNA11 map · TCGA-UVM")
1010
+ b_uv.click(uvm_variants, [], o_uv)
1011
+ with gr.TabItem("Vitreous LNP"):
1012
+ b_uw = gr.Button("Rank Vitreous Formulations", variant="primary")
1013
+ o_uwt = gr.Dataframe(label="Vitreous LNP retention ranking")
1014
+ o_uwp = gr.Image(label="Retention (hours)")
1015
+ b_uw.click(uvm_vitreous, [], [o_uwt, o_uwp])
1016
+ with gr.TabItem("Research Gap"):
1017
+ gr.Markdown(
1018
+ "**Data:** TCGA-UVM (n=80) · GEO m6A atlases · Vitreous proteomics\n\n"
1019
+ "| Layer | Known | This study gap |\n"
1020
+ "|-------|-------|----------------|\n"
1021
+ "| Genomics | GNAQ/GNA11 mutations | m6A landscape GNAQ+ vs GNA11+ |\n"
1022
+ "| Delivery | Intravitreal injection | LNP corona **in vitreous humor** |\n"
1023
+ "| Biology | PLCβ→PKC→MAPK | GNAQ × METTL3 × YTHDF2 axis |"
1024
+ )
1025
+ # R3 · pAML
1026
+ with gr.TabItem("R3 · pAML"):
1027
+ with gr.Tabs():
1028
+ with gr.TabItem("R3a · pAML Toolkit"):
1029
+ gr.HTML(proj_badge("S1-F · R3a", "pAML Toolkit", "TARGET-AML n≈197"))
1030
  gr.Markdown(
1031
+ "> **Why pAML?** Pediatric AML relapse OS **<30%**. "
1032
+ "FLT3-ITD in 25% cases. "
1033
+ "Bone marrow niche LNP corona: **never studied**. "
1034
+ "Ferroptosis–FLT3 intersection: 0 prior studies (FerrDb v2 confirmed)."
 
 
1035
  )
1036
+ with gr.Tabs():
1037
+ with gr.TabItem("Ferroptosis Explorer"):
1038
+ var_sel = gr.Dropdown(
1039
+ ["FLT3-ITD", "NPM1 c.860_863dupTCAG", "DNMT3A p.R882H",
1040
+ "CEBPA biallelic", "IDH1/2 mutation"],
1041
+ value="FLT3-ITD", label="Select variant"
1042
+ )
1043
+ b_pf = gr.Button("Analyze Ferroptosis Profile", variant="primary")
1044
+ o_pft = gr.HTML()
1045
+ o_pfp = gr.Image(label="Target radar")
1046
+ b_pf.click(paml_ferroptosis, var_sel, [o_pft, o_pfp])
1047
+ with gr.TabItem("BM Niche LNP"):
1048
+ gr.Dataframe(
1049
+ value=pd.DataFrame(PAML_BM_LNP),
1050
+ label="Bone marrow niche LNP candidates · TARGET-AML context"
1051
+ )
1052
+ with gr.TabItem("Research Gap"):
1053
+ gr.Markdown(
1054
+ "**Data:** TARGET-AML (n=197) · BeatAML · FerrDb v2\n\n"
1055
+ "| Layer | Known | This study gap |\n"
1056
+ "|-------|-------|----------------|\n"
1057
+ "| Genomics | FLT3-ITD → Midostaurin | FLT3-ITD × GPX4/SLC7A11 |\n"
1058
+ "| Delivery | Liposomal daunorubicin | LNP corona **in bone marrow** |\n"
1059
+ "| Biology | Midostaurin inhibits FLT3 | Ferroptosis SL + FLT3i |"
1060
+ )
1061
 
1062
+ # === S1-G · 3D Lab ===
1063
+ with gr.TabItem("🧊 S1-G · 3D Lab"):
1064
+ gr.HTML(section_header(
1065
+ "S1-G", "PHYLO-SIM", "— 3D Models & Simulations",
1066
+ "Interactive visualizations for learning"
1067
+ ))
1068
+ with gr.Tabs(elem_classes="main-tabs"):
1069
+ with gr.TabItem("Nanoparticle"):
1070
+ gr.Markdown("### 3D Model of a Lipid Nanoparticle")
1071
+ with gr.Row():
1072
+ np_radius = gr.Slider(2, 20, value=5, step=1, label="Radius (nm)")
1073
+ np_peg = gr.Slider(0, 1, value=0.3, step=0.05, label="PEG density")
1074
+ np_btn = gr.Button("Generate", variant="primary")
1075
+ np_plot = gr.Plot(label="Nanoparticle")
1076
+ np_btn.click(plot_nanoparticle, [np_radius, np_peg], np_plot)
 
 
 
 
 
 
1077
 
1078
+ with gr.TabItem("DNA Helix"):
1079
+ gr.Markdown("### 3D Model of a DNA Double Helix")
1080
+ dna_btn = gr.Button("Generate DNA", variant="primary")
1081
+ dna_plot = gr.Plot()
1082
+ dna_btn.click(plot_dna, [], dna_plot)
1083
 
1084
+ with gr.TabItem("Protein Corona"):
1085
+ gr.Markdown("### Schematic of Protein Corona on Nanoparticle")
1086
+ corona_btn = gr.Button("Show Corona", variant="primary")
1087
+ corona_plot = gr.Plot()
1088
+ corona_btn.click(plot_corona, [], corona_plot)
 
 
 
 
 
 
 
 
 
 
1089
 
1090
+ # === Learning ===
1091
+ with gr.TabItem("📚 Learning"):
1092
+ gr.Markdown("""
1093
  ## 🧪 Guided Investigations
1094
  > 🟢 Beginner → 🟡 Intermediate → 🔴 Advanced
1095
 
 
1099
  **S1-B · R2a** siRNA – count "Novel" targets across cancer types
1100
  **S1-E · R1a** Liquid Biopsy – find minimal signal for CANCER
1101
  **S1-G · 3D Lab** – explore nanoparticle, DNA, and protein corona models
1102
+ """)
1103
+
1104
+ # Права колонка з журналом
1105
+ with gr.Column(scale=1, min_width=300):
1106
+ with gr.Group(elem_classes="journal"):
1107
+ gr.Markdown("## 📓 Lab Journal")
1108
+ note_input = gr.Textbox(label="📝 Observation", placeholder="Your observation...", lines=2)
1109
+ note_tab = gr.Textbox(label="Project code (e.g. S1-A·R1a)", value="General", visible=False)
1110
+ with gr.Row():
1111
+ save_btn = gr.Button("💾 Save", size="sm", variant="primary")
1112
+ refresh_btn = gr.Button("🔄 Refresh", size="sm")
1113
+ clear_btn = gr.Button("🗑️ Clear", size="sm")
1114
+ journal_display = gr.Markdown(value=load_journal())
1115
+
1116
+ save_btn.click(save_note, [note_input, note_tab], journal_display)
1117
+ refresh_btn.click(load_journal, [], journal_display)
1118
+ clear_btn.click(clear_journal, [], journal_display)
1119
 
1120
  gr.Markdown(
1121
  "---\n**K R&D Lab** · MIT License · "