"""Shared look-and-feel for the ProtHGT Streamlit pages (header, CSS, stepper).""" import streamlit as st ACCENT = "#3B4BD8" GITHUB_URL = "https://github.com/HUBioDataLab/ProtHGT" PAPER_URL = "https://www.biorxiv.org/content/10.1101/2025.04.19.649272" # Minimum score behind each strictness preset (used by the app and the user guide). # Replace "Balanced" with your validation-set Fmax threshold(s) to match the paper exactly. STRICTNESS = { "Precise": (0.70, "Fewer, high-confidence terms"), "Balanced": (0.50, "Recommended default"), "Exploratory": (0.30, "More candidates to screen"), } # How to read the knowledge graph view. Shown in the User guide and in the "How to read this graph" # expander of the Knowledge graph tab, so the two stay in sync. KG_VIEW_GUIDE = """ The view shows the part of the ProtHGT knowledge graph around one query protein, drawn at the centre with a dark ring. Direct neighbours sit on an inner ring, grouped by kind (confirmed predictions, novel predictions, known annotations, then other node types); second-degree neighbours sit on an outer ring next to the neighbour they connect to. Choose the protein, then click **Show graph**. - **Predicted GO terms** – how many of the highest-scoring predictions are shown for each predicted GO category. - **Neighbours per edge type** – how many knowledge-graph neighbours are shown for each relationship type (domains, interactions, pathways, …), including known GO annotations outside the top predictions. - **Second-degree neighbours** – set above 0 to also expand the neighbours' own connections, excluding edges back to the query protein, up to that many per edge type. Keep it low: the graph quickly becomes cluttered. Second-degree edges always come from the knowledge graph, never from predictions. Node colours mark the entity type (see the legend at the top of the graph). Predictions are drawn for the selected protein only; select another protein in **Protein** to see its predictions. Edge colours mark the kind of link: - **Purple** – predicted GO term that is also annotated in the knowledge graph. Known annotations that the model predicted are purple even when they rank below the top terms set by **Predicted GO terms**. - **Red** – novel prediction (one of the top predicted terms) not annotated in the knowledge graph. - **Blue** – GO annotation in the knowledge graph that the model did not predict in this run. - **Grey** – other relationships, such as protein–protein interactions, domains, drug targets, pathways, domain–GO mappings and GO hierarchy links. Interacting with the graph: - **Hover** a node to highlight its connections and show their relationship names, with a card giving the node's name, type and a link to the source database (UniProt, QuickGO, InterPro, …). Hover an edge to see the relationship and, for GO terms, the score. - **Drag** nodes to rearrange them; **scroll** to zoom and drag the background to pan. - **Click a legend item** to hide that node type or edge kind; nodes left without visible edges are hidden too. Click it again to bring it back. - Use the icons at the top right to **reset** the view, save it as a **PNG**, or download the edges currently shown as **JSON** (with their scores and edge kind; hidden edge kinds and node types are left out). For exploration beyond second-degree connections, download the complete knowledge graph from the link at the top of the Knowledge graph tab. """ _CSS = """ """.replace("ACCENT", ACCENT) def apply_style(): st.markdown(_CSS, unsafe_allow_html=True) def render_header(current="predict"): apply_style() cols = st.columns([3, 1.1, 1.1, 0.9, 1.1], vertical_alignment="center") with cols[0]: st.markdown('

ProtHGT

', unsafe_allow_html=True) with cols[1]: st.page_link("ProtHGT_app.py", label="Predict") with cols[2]: st.page_link("pages/User_Guide.py", label="User guide") with cols[3]: st.page_link("pages/About.py", label="About") with cols[4]: st.page_link(GITHUB_URL, label="GitHub") def render_stepper(step): labels = ["Add proteins", "Choose what to predict", "Review results"] items = [] for i, label in enumerate(labels, start=1): if i < step: cls, mark, state = "done", "✓", "" elif i == step: cls, mark, state = "current", str(i), ' aria-current="step"' else: cls, mark, state = "", str(i), "" items.append( f'
  • {mark}' f'Step {i}{label}
  • ' ) st.markdown(f'
      {"".join(items)}
    ', unsafe_allow_html=True)