Spaces:
Sleeping
Sleeping
File size: 6,951 Bytes
31d5c57 e872263 32cf4da 31d5c57 32cf4da e872263 31d5c57 487f949 32cf4da e872263 32cf4da e872263 32cf4da e872263 32cf4da e872263 31d5c57 e872263 31d5c57 e872263 31d5c57 32cf4da 31d5c57 e872263 31d5c57 e872263 e210ebd e872263 31d5c57 d0e808d e872263 487f949 e872263 487f949 e872263 31d5c57 e872263 31d5c57 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | import streamlit as st
import logging
import numpy as np
import os
import base64
# Configure Logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def get_base64_of_bin_file(bin_file):
with open(bin_file, 'rb') as f:
data = f.read()
return base64.b64encode(data).decode()
# Page configuration
sidebar_state = "expanded"
st.set_page_config(
page_title="spMetaTME-Atlas",
page_icon=":material/hub:",
layout="wide",
initial_sidebar_state=sidebar_state,
)
from src.ui.components.header import render_header, load_css
from src.ui.components.footer import render_footer
from src.ui.pages.home import show_overview
from src.ui.pages.analyze import (
page_domain_statistics,
page_spatial_flux,
page_umap_analysis,
page_differential_analysis,
page_metabolic_interactions,
page_metabolite_balance,
page_reset
)
def init_session_state():
"""Initialise global session state."""
if "adata" not in st.session_state:
st.session_state.adata = None
if "metabolic_adata" not in st.session_state:
st.session_state.metabolic_adata = None
if "data_type" not in st.session_state:
st.session_state.data_type = None
if "preprocessing_done" not in st.session_state:
st.session_state.preprocessing_done = False
if "flux_analysis_done" not in st.session_state:
st.session_state.flux_analysis_done = False
if "interaction_scores" not in st.session_state:
st.session_state.interaction_scores = None
if "interaction_type" not in st.session_state:
st.session_state.interaction_type = None
# Pagination States
if "dataset_page" not in st.session_state:
st.session_state.dataset_page = 1
if "umap_page" not in st.session_state:
st.session_state.umap_page = 1
if "spatial_flux_page" not in st.session_state:
st.session_state.spatial_flux_page = 1
# Developer Mode
if "dev_mode" not in st.session_state:
st.session_state.dev_mode = True
def render_branding_header():
"""Display a clean, professional branding header using the network background."""
try:
bg_img_path = "assets/network_bg_red.png"
bg_base64 = get_base64_of_bin_file(bg_img_path) if os.path.exists(bg_img_path) else ""
subtitle = "A spatial atlas of tumour microenvironment metabolism and metabolic interactions inferred by a pretrained self-supervised metabolic hypergraph"
# Load brand logo from npy
brand_text = "spMetaTME-Atlas"
brand_path = "assets/spMetaTME_brand.npy"
if os.path.exists(brand_path):
try:
brand_data = np.load(brand_path, allow_pickle=True)
brand_text = brand_data.item() if hasattr(brand_data, 'item') else str(brand_data)
except Exception:
pass
html_code = f"""
<div style="position: relative; width: 100%; background: transparent; padding: 0.5rem 0; margin-bottom: 1rem; overflow: hidden; border-bottom: 1px solid #f0f0f0; text-align: center; border-radius: 12px;">
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url('data:image/png;base64,{bg_base64}'); background-size: cover; background-position: center; opacity: 0.05; z-index: 1; pointer-events: none;"></div>
<div style="position: relative; z-index: 10; display: flex; flex-direction: column; align-items: center;">
<pre class="brand-logo-ascii" style="margin-bottom: 5px; zoom: 0.85;">{brand_text}</pre>
<p style="font-size: 0.85rem; color: #666; max-width: 900px; margin: 0 auto; font-weight: 400; line-height: 1.2;">{subtitle}</p>
</div>
</div>
"""
st.html(html_code)
except Exception as e:
try:
st.markdown(html_code, unsafe_allow_html=True)
except:
logger.error(f"Failed to load branding header: {e}")
def render_sidebar_dev():
"""Developer shortcuts in sidebar."""
with st.sidebar:
st.markdown("---")
st.session_state.dev_mode = st.checkbox("Developer Mode", value=st.session_state.dev_mode)
if st.session_state.dev_mode:
st.info("Dev Shortcuts Active")
if st.button("Load Breast Cancer Block A", use_container_width=True):
with st.spinner("Loading example data..."):
for key in ['interaction_scores', 'interaction_type']:
if key in st.session_state:
del st.session_state[key]
import scanpy as sc
adata = sc.read_h5ad(r"example_data/metabolic_Breast_cancer_Block_A.h5ad")
if adata is not None:
st.session_state.metabolic_adata = adata
st.session_state.data_type = "metabolic"
st.session_state.just_loaded = True
if 'domain' not in adata.obs.columns and 'domain_id' in adata.obs.columns:
adata.obs['domain'] = adata.obs['domain_id']
st.success("Loaded Breast Cancer Block A")
st.rerun()
def main():
init_session_state()
load_css()
home_page = st.Page(show_overview, title="Home", icon=":material/home:", url_path="home")
domain_stats_page = st.Page(page_domain_statistics, title="Domain Statistics", icon=":material/pie_chart:", url_path="domain_stats")
analysis_pages = [
st.Page(page_reset, title="Back to Home", icon=":material/home:", url_path="reset_to_home"),
domain_stats_page,
st.Page(page_spatial_flux, title="Spatial Flux Distribution", icon=":material/image:", url_path="spatial_flux"),
st.Page(page_umap_analysis, title="UMAP Analysis", icon=":material/palette:", url_path="umap_analysis"),
st.Page(page_differential_analysis, title="Differential Reactions", icon=":material/bar_chart:", url_path="differential_analysis"),
st.Page(page_metabolic_interactions, title="Spatial Metabolic Interactions", icon=":material/link:", url_path="metabolic_interactions"),
st.Page(page_metabolite_balance, title="Metabolite Balance Analysis", icon=":material/opacity:", url_path="metabolite_balance"),
]
if st.session_state.metabolic_adata is None:
pg = st.navigation([home_page], position="hidden")
render_header()
# render_sidebar_dev()
pg.run()
else:
pg = st.navigation({"Metabolic Analysis": analysis_pages}, position="sidebar")
render_branding_header()
# Developer Shortcuts
# render_sidebar_dev()
if st.session_state.get('just_loaded', False):
st.session_state.just_loaded = False
st.switch_page(domain_stats_page)
pg.run()
render_footer()
if __name__ == "__main__":
main()
|