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
34 changes: 18 additions & 16 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,35 @@
with open("settings.json", "r") as f:
st.session_state.settings = json.load(f)

# Initialize session state for workspace
if "chosen-workspace" not in st.session_state:
if "workspace" in st.session_state:
st.session_state["chosen-workspace"] = str(st.session_state.workspace.stem)
else:
st.session_state["chosen-workspace"] = "default"

if __name__ == '__main__':
pages = {
str(st.session_state.settings["app-name"]) : [
st.Page(Path("content", "quickstart.py"), title="Quickstart", icon="👋"),
st.Page(Path("content", "documentation.py"), title="Documentation", icon="📖"),
],
"pyOpenMS Toolbox": [
st.Page(Path("content", "digest.py"), title="In Silico Digest", icon="✂️"),
st.Page(Path("content", "peptide_mz_calculator.py"), title="m/z Calculator", icon="⚖️"),
st.Page(Path("content", "isotope_pattern_generator.py"), title="Isotopic Pattern Calculator", icon="📶"),
st.Page(Path("content", "fragmentation.py"), title="Fragment Ion Generation", icon="💥"),
],
"TOPP Workflow Framework": [
st.Page(Path("content", "topp_workflow_file_upload.py"), title="File Upload", icon="📁"),
st.Page(Path("content", "topp_workflow_parameter.py"), title="Configure", icon="⚙️"),
st.Page(Path("content", "topp_workflow_execution.py"), title="Run", icon="🚀"),
st.Page(Path("content", "topp_workflow_results.py"), title="Results", icon="📊"),
],
"pyOpenMS Workflow" : [
st.Page(Path("content", "file_upload.py"), title="File Upload", icon="📂"),
st.Page(Path("content", "raw_data_viewer.py"), title="View MS data", icon="👀"),
st.Page(Path("content", "run_example_workflow.py"), title="Run Workflow", icon="⚙️"),
st.Page(Path("content", "download_section.py"), title="Download Results", icon="⬇️"),
# st.Page(Path("content", "topp_workflow_results.py"), title="Results", icon="📊"),
],
"Others Topics": [
st.Page(Path("content", "simple_workflow.py"), title="Simple Workflow", icon="⚙️"),
st.Page(Path("content", "run_subprocess.py"), title="Run Subprocess", icon="🖥️"),
"Results": [
st.Page(Path("content", "results_database_search.py"), title="Database Search", icon="🔬"),
st.Page(Path("content", "results_rescoring.py"), title="Rescoring", icon="📈"),
st.Page(Path("content", "results_filtered.py"), title="Filtered PSMs", icon="🎯"),
st.Page(Path("content", "results_abundance.py"), title="Abundance", icon="📋"),
st.Page(Path("content", "results_volcano.py"), title="Volcano", icon="🌋"),
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_pathway.py"), title="Pathway Analysis", icon="🧪"),
]
}

Expand Down
132 changes: 132 additions & 0 deletions content/results_abundance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""Abundance (ProteomicsLFQ) Results Page."""
import streamlit as st
import pandas as pd
import numpy as np
from pathlib import Path
from scipy.stats import ttest_ind
from src.common.common import page_setup
from statsmodels.stats.multitest import multipletests
from src.common.results_helpers import get_workflow_dir, get_abundance_data

params = page_setup()
st.title("Abundance Quantification")

st.markdown(
"""
View protein and PSM-level quantification from **ProteomicsLFQ**.
This page calculates differential expression statistics between sample groups.
"""
)

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

results_dir = Path(st.session_state["workspace"]) / "topp-workflow" / "results" / "quant_results"
consensus_out = results_dir / "openms_design_protein_openms.csv"

@st.cache_data
def load_data(file_path):
return pd.read_csv(file_path, sep="\t", comment="#", engine="python")

if consensus_out.exists():

# df = load_data(consensus_out)
# # ratio column removal
# df = df.loc[:, ~df.columns.str.contains('ratio', case=False)]

pre_processing_tab, protein_tab = st.tabs(["Pre-processing", "Protein Table"])

with pre_processing_tab:
# result = get_abundance_data(st.session_state["workspace"])
# DEBUG: 상세 원인 출력 (임시)
try:
result = get_abundance_data(st.session_state["workspace"])
except Exception as e:
st.exception(e)
result = None

if result is None:
ws = st.session_state.get("workspace")
st.error("Debug: get_abundance_data returned None")
st.write("workspace:", ws)
wf = Path(ws) / "topp-workflow"
st.write("workflow dir exists:", wf.exists(), "->", wf)
qdir = wf / "results" / "quant_results"
st.write("quant_dir exists:", qdir.exists(), "->", qdir)
if qdir.exists():
st.write("csv files:", sorted([p.name for p in qdir.glob('*.csv')]))
# show cached param snapshot if available
try:
from src.workflow.ParameterManager import ParameterManager
pm = ParameterManager(wf)
st.write("parameters keys (sample):", list(pm.get_parameters_from_json().items())[:20])
except Exception as e:
st.write("Param manager error:", e)
st.stop()

if result is None:
st.info("💡 Please complete the configuration in the 'Configure' page to see results.")
st.stop()

pivot_df, expr_df, group_map = result

st.write("### Final Results (Group row removed, Stats added)")
st.dataframe(pivot_df.head(10))


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."
)

# Display group comparison info
groups = sorted(set(group_map.values()))
if len(groups) >= 2:
group1, group2 = sorted(groups)[:2]
st.info(f"Statistical comparison: **{group2} vs {group1}**")

exclude_cols = ["protein", "log2FC", "p-value", "p-adj",
"n_proteins", "n_peptides", "protein_score"]

# Get sample columns (between stats and PeptideSequence)
sample_cols = [c for c in pivot_df.columns if c
not in exclude_cols and "ratio" not in c.lower()]

# Create bar chart column with log2-transformed values
pivot_df["Intensity"] = pivot_df[sample_cols].apply(
lambda row: [np.log2(v + 1) for v in row], axis=1
)

# Reorder columns: place Intensity after p-value
display_cols = ["protein", "log2FC", "p-value", "Intensity"] + sample_cols
available_cols = [c for c in display_cols if c in pivot_df.columns]

st.dataframe(
pivot_df[available_cols].sort_values("p-value"),
column_config={
"Intensity": st.column_config.BarChartColumn(
"Intensity",
help="Sample intensities (log2 scale)",
width="small",
y_min=0,
),
},
width="stretch"
)
else:
st.warning(f"File not found: {consensus_out}")

st.markdown("---")
st.markdown("**Next steps:** Explore statistical visualizations")
col1, col2, col3 = st.columns(3)
with col1:
st.page_link("content/results_volcano.py", label="Volcano Plot", icon="🌋")
with col2:
st.page_link("content/results_pca.py", label="PCA", icon="📊")
with col3:
st.page_link("content/results_heatmap.py", label="Heatmap", icon="🔥")
79 changes: 79 additions & 0 deletions content/results_database_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""Database Search (Comet) Results Page."""
import streamlit as st
from pathlib import Path
from src.common.common import page_setup
from src.common.results_helpers import get_workflow_dir
from openms_insight import Table, Heatmap, LinePlot, SequenceView, StateManager

params = page_setup()
st.title("Database Search Results")

st.markdown(
"""
View peptide-spectrum matches (PSMs) identified by **Comet** database search.
Click on a PSM to view the annotated spectrum and peptide sequence.
"""
)

st.info(
"**Score:** The e-value (expectation value) represents the expected number of random PSMs "
"with an equal or better score. Lower values indicate higher confidence identifications."
)

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

workflow_dir = get_workflow_dir(st.session_state["workspace"])
comet_dir = workflow_dir / "results" / "comet_results"
cache_dir = workflow_dir / "results" / "insight_cache"

if not comet_dir.exists():
st.info("No database search results available yet. Please run the workflow first.")
st.page_link("content/workflow_run.py", label="Go to Run", icon="🚀")
st.stop()

comet_files = sorted(comet_dir.glob("*.idXML"))

if not comet_files:
st.warning("No identification output files found.")
st.stop()

selected_file = st.selectbox(
"Select identification result file",
comet_files,
format_func=lambda x: x.name
)

cache_id_prefix = selected_file.stem

# Check if cache exists
if not (cache_dir / f"table_{cache_id_prefix}").is_dir():
st.warning("Visualization cache not found. Please re-run the workflow.")
st.stop()

# Initialize state manager for cross-component linking
state_manager = StateManager()

# Load components from cache (no data parameter needed)
table = Table(cache_id=f"table_{cache_id_prefix}", cache_path=str(cache_dir))
heatmap = Heatmap(cache_id=f"heatmap_{cache_id_prefix}", cache_path=str(cache_dir))
seq_view = SequenceView(cache_id=f"seqview_{cache_id_prefix}", cache_path=str(cache_dir))
line_plot = LinePlot(cache_id=f"lineplot_{cache_id_prefix}", cache_path=str(cache_dir))

# Render components
st.subheader("PSM Overview")
heatmap(state_manager=state_manager, height=350)

st.subheader("PSM Table")
table(state_manager=state_manager, height=533)

st.subheader("Peptide Sequence")
seq_view(key=f"seqview_{cache_id_prefix}", state_manager=state_manager, height=533)

st.subheader("MS2 Spectrum")
line_plot(key=f"lineplot_{cache_id_prefix}", state_manager=state_manager, height=450, sequence_view_key=f"seqview_{cache_id_prefix}")

st.markdown("---")
st.markdown("**Next step:** View rescoring results")
st.page_link("content/results_rescoring.py", label="Go to Rescoring", icon="📈")
79 changes: 79 additions & 0 deletions content/results_filtered.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""Filtered PSMs Results Page."""
import streamlit as st
from pathlib import Path
from src.common.common import page_setup
from src.common.results_helpers import get_workflow_dir
from openms_insight import Table, Heatmap, LinePlot, SequenceView, StateManager

params = page_setup()
st.title("Filtered PSMs")

st.markdown(
"""
View FDR-controlled peptide identifications after **IDFilter** processing.
These are high-confidence PSMs that passed the specified FDR threshold.
Click on a PSM to view the annotated spectrum and peptide sequence.
"""
)

st.info(
"**Score:** The q-value represents the minimum false discovery rate (FDR) at which this PSM "
"would be accepted. Lower values indicate higher confidence identifications."
)

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

workflow_dir = get_workflow_dir(st.session_state["workspace"])
filter_dir = workflow_dir / "results" / "psm_filter"
cache_dir = workflow_dir / "results" / "insight_cache"

if not filter_dir.exists():
st.info("No filtered results available yet. Please run the workflow first.")
st.stop()

filter_files = sorted(filter_dir.glob("*.idXML"))

if not filter_files:
st.warning("No filtering output files found.")
st.stop()

selected_file = st.selectbox(
"Select filtering result file",
filter_files,
format_func=lambda x: x.name
)

cache_id_prefix = selected_file.stem

# Check if cache exists
if not (cache_dir / f"table_{cache_id_prefix}").is_dir():
st.warning("Visualization cache not found. Please re-run the workflow.")
st.stop()

# Initialize state manager for cross-component linking
state_manager = StateManager()

# Load components from cache (no data parameter needed)
table = Table(cache_id=f"table_{cache_id_prefix}", cache_path=str(cache_dir))
heatmap = Heatmap(cache_id=f"heatmap_{cache_id_prefix}", cache_path=str(cache_dir))
seq_view = SequenceView(cache_id=f"seqview_{cache_id_prefix}", cache_path=str(cache_dir))
line_plot = LinePlot(cache_id=f"lineplot_{cache_id_prefix}", cache_path=str(cache_dir))

# Render components
st.subheader("PSM Overview")
heatmap(state_manager=state_manager, height=350)

st.subheader("PSM Table")
table(state_manager=state_manager, height=533)

st.subheader("Peptide Sequence")
seq_view(key=f"seqview_{cache_id_prefix}", state_manager=state_manager, height=533)

st.subheader("MS2 Spectrum")
line_plot(key=f"lineplot_{cache_id_prefix}", state_manager=state_manager, height=450, sequence_view_key=f"seqview_{cache_id_prefix}")

st.markdown("---")
st.markdown("**Next step:** View abundance quantification")
st.page_link("content/results_abundance.py", label="Go to Abundance", icon="📋")
Loading