Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
st.Page(Path("content", "results_pca.py"), title="PCA", icon="📊"),
st.Page(Path("content", "results_heatmap.py"), title="Heatmap", icon="🔥"),
st.Page(Path("content", "results_library.py"), title="Spectral Library", icon="📚"),
st.Page(Path("content", "results_proteomicslfq.py"), title="Proteomics LFQ", icon="🧪"),
],
}

Expand Down
6 changes: 3 additions & 3 deletions content/results_pca.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

top_proteins = (
pivot_df
.dropna(subset=["p-value"])
.sort_values("p-value", ascending=True)
.dropna(subset=["p-adj"])
.sort_values("p-adj", ascending=True)
.head(top_n)["ProteinName"]
)

Expand Down Expand Up @@ -81,7 +81,7 @@

st.plotly_chart(fig_pca, use_container_width=True)

st.markdown(f"**Proteins used:** {expr_df_pca.shape[0]} (top {top_n} by p-value)")
st.markdown(f"**Proteins used:** {expr_df_pca.shape[0]} (top {top_n} by p-adj)")

st.markdown("---")
st.markdown("**Other visualizations:**")
Expand Down
101 changes: 101 additions & 0 deletions content/results_proteomicslfq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from pathlib import Path
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px

from src.common.common import page_setup
from src.common.results_helpers import get_abundance_data

# ================================
# Page setup
# ================================
params = page_setup()
st.title("ProteomicsLFQ Results")

# ================================
# Workspace check
# ================================
if "workspace" not in st.session_state:
st.warning("Please initialize your workspace first.")
st.stop()

# ================================
# Load abundance data
# ================================
res = get_abundance_data(st.session_state["workspace"])
if res is None:
st.info(
"Abundance data not available or incomplete. "
"Please run the workflow and configure sample groups first."
)
st.stop()

pivot_df, expr_df, group_map = res

# ================================
# Tabs
# ================================
protein_tab, = st.tabs(["🧬 Protein Table"])

# ================================
# Protein-level results
# ================================
with protein_tab:
st.markdown("### 🧬 Protein-Level Abundance Table")
st.info(
"This protein-level table is generated by grouping all PSMs that map to the "
"same protein and aggregating their intensities across samples.\n\n"
"Additionally, log2 fold change and p-values are calculated between sample groups."
)

if pivot_df.empty:
st.info("No protein-level data available.")
else:
st.session_state["pivot_df"] = pivot_df
st.dataframe(pivot_df.sort_values("p-value"), use_container_width=True)

# ======================================================
# GO Enrichment Results
# ======================================================
st.markdown("---")
st.subheader("🧬 GO Enrichment Analysis")

results_dir = Path(st.session_state["workspace"]) / "topp-workflow" / "results" / "go-terms"
go_json_file = results_dir / "go_results.json"
Comment on lines +64 to +65
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for all references to "topp-workflow" in the codebase
rg -n "topp-workflow" --type=py

Repository: OpenMS/quantms-web

Length of output: 334


🏁 Script executed:

# Check the actual file and surrounding context
find . -name "results_proteomicslfq.py" -type f

Repository: OpenMS/quantms-web

Length of output: 96


🏁 Script executed:

# Find and examine WorkflowManager and WorkflowTest to understand the naming convention
fd -e py -type f | xargs grep -l "class WorkflowManager\|class WorkflowTest" | head -5

Repository: OpenMS/quantms-web

Length of output: 232


🏁 Script executed:

# Examine the results_helpers.py file to see the helper function
cat -n src/common/results_helpers.py

Repository: OpenMS/quantms-web

Length of output: 12765


🏁 Script executed:

# Search for WorkflowManager and WorkflowTest class definitions
rg -n "class WorkflowManager|class WorkflowTest" --type py -A 10

Repository: OpenMS/quantms-web

Length of output: 1713


🏁 Script executed:

# Check if there are other imports or usages of results_helpers in content files
rg -n "from.*results_helpers|import.*results_helpers" --type py

Repository: OpenMS/quantms-web

Length of output: 1045


Use the centralized get_workflow_dir() helper instead of hardcoding the path.

Line 64 hardcodes "topp-workflow", but src/common/results_helpers.py provides get_workflow_dir(workspace) for this purpose. Other result files (e.g., results_abundance.py, results_library.py, results_filtered.py) already import and use this helper. For consistency and maintainability, import get_workflow_dir and replace the hardcoded path:

from src.common.results_helpers import get_abundance_data, get_workflow_dir

Then on line 64:

workflow_dir = get_workflow_dir(st.session_state["workspace"])
results_dir = workflow_dir / "results" / "go-terms"
🤖 Prompt for AI Agents
In `@content/results_proteomicslfq.py` around lines 64 - 65, Replace the hardcoded
construction of results_dir using "topp-workflow" with the shared helper: import
get_workflow_dir from src.common.results_helpers (alongside get_abundance_data
if present) and call workflow_dir =
get_workflow_dir(st.session_state["workspace"]); then build results_dir =
workflow_dir / "results" / "go-terms" (keep go_json_file = results_dir /
"go_results.json") and remove the hardcoded Path(...) use so the file uses
get_workflow_dir consistently.


if not go_json_file.exists():
st.info("GO Enrichment results are not available yet. Please run the analysis first.")
else:
import json
import plotly.io as pio

with open(go_json_file, "r") as f:
go_data = json.load(f)

bp_tab, cc_tab, mf_tab = st.tabs([
"🧬 Biological Process",
"🏠 Cellular Component",
"⚙️ Molecular Function",
])

for tab, go_type in zip([bp_tab, cc_tab, mf_tab], ["BP", "CC", "MF"]):
with tab:
if go_type not in go_data:
st.info(f"No enriched {go_type} terms found.")
continue

fig_json = go_data[go_type]["fig_json"]
df_dict = go_data[go_type]["df_dict"]

fig = pio.from_json(fig_json)

df_go = pd.DataFrame(df_dict)

if df_go.empty:
st.info(f"No enriched {go_type} terms found.")
else:
st.plotly_chart(fig, use_container_width=True)

st.markdown(f"#### {go_type} Enrichment Results")
st.dataframe(df_go, use_container_width=True)
21 changes: 13 additions & 8 deletions content/results_volcano.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
st.stop()

volcano_df = pivot_df.copy()
volcano_df = volcano_df.dropna(subset=["log2FC", "p-value"])
volcano_df = volcano_df.dropna(subset=["log2FC", "p-adj"])

volcano_df["neg_log10_p"] = -np.log10(volcano_df["p-value"])
volcano_df["neg_log10_padj"] = -np.log10(volcano_df["p-adj"])

fc_thresh = st.slider(
"log2 Fold Change threshold",
Expand All @@ -45,7 +45,7 @@
)

p_thresh = st.slider(
"p-value threshold",
"p-adj (FDR) threshold",
min_value=0.001,
max_value=0.1,
value=0.05,
Expand All @@ -54,21 +54,26 @@

volcano_df["Significance"] = "Not significant"
volcano_df.loc[
(volcano_df["p-value"] <= p_thresh) & (volcano_df["log2FC"] >= fc_thresh),
(volcano_df["p-adj"] <= p_thresh) & (volcano_df["log2FC"] >= fc_thresh),
"Significance",
] = "Up-regulated"

volcano_df.loc[
(volcano_df["p-value"] <= p_thresh) & (volcano_df["log2FC"] <= -fc_thresh),
(volcano_df["p-adj"] <= p_thresh) & (volcano_df["log2FC"] <= -fc_thresh),
"Significance",
] = "Down-regulated"

fig_volcano = px.scatter(
volcano_df,
x="log2FC",
y="neg_log10_p",
y="neg_log10_padj",
color="Significance",
hover_data=["ProteinName", "p-value"],
hover_data=["ProteinName", "log2FC", "p-value", "p-adj"],
color_discrete_map={
"Up-regulated": "red",
"Down-regulated": "blue",
"Not significant": "lightgrey",
}
)

fig_volcano.add_vline(x=fc_thresh, line_dash="dash")
Expand All @@ -81,7 +86,7 @@

fig_volcano.update_layout(
xaxis_title="log2 Fold Change",
yaxis_title="-log10(p-value)",
yaxis_title="-log10(p-adj)",
xaxis_range=x_range,
height=600,
)
Expand Down
1 change: 0 additions & 1 deletion content/workflow_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
params = page_setup()

wf = WorkflowTest()

wf.show_execution_section()
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ polars>=1.0.0
cython
easypqp>=0.1.34
pyprophet>=2.2.0

mygene
# Redis Queue dependencies (for online mode)
redis>=5.0.0
rq>=1.16.0
statsmodels
Loading