Skip to content

Commit

Permalink
resolved conflitcs
Browse files Browse the repository at this point in the history
  • Loading branch information
subCode321 committed Mar 6, 2025
2 parents 2eac24a + d65c9c9 commit 89a84d7
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 80 deletions.
12 changes: 8 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ jobs:
python-version: ["3.11"]
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
- uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: openms
python-version: ${{ matrix.python-version }}
channels: defaults,bioconda,conda-forge

- name: Install OpenMS
run: |
conda install openms -y
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt # test with requirements file so can easily bump with dependabot
pip install pytest
- name: Test
run: |
python -m pytest test_gui.py
python -m pytest test_gui.py
7 changes: 6 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import streamlit as st
from pathlib import Path
import json
# For some reason the windows version only works if this is imported here
import pyopenms

if "settings" not in st.session_state:
with open("settings.json", "r") as f:
st.session_state.settings = json.load(f)

if __name__ == '__main__':
pages = {
"OpenMS Web App" : [
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="📖"),
],
Expand Down
26 changes: 13 additions & 13 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
###### TODO: how use exact version specifiers for all packages ######
name: streamlit-env
channels:
- conda-forge
- conda-forge
dependencies:
- python==3.11
- plotly==5.22.0
- pip==24.0
- numpy==1.26.4 # pandas and numpy are dependencies of pyopenms, however, pyopenms needs numpy<=1.26.4
- mono==6.12.0.90
- pip:
# dependencies only available through pip
# streamlit dependencies
- streamlit>=1.38.0
- captcha==0.5.0
- pyopenms_viz>=0.1.2
- streamlit-js-eval
- python==3.11
- plotly==5.22.0
- pip==24.0
- numpy==1.26.4 # pandas and numpy are dependencies of pyopenms, however, pyopenms needs numpy<=1.26.4
- mono==6.12.0.90
- pip:
# dependencies only available through pip
# streamlit dependencies
- streamlit>=1.38.0
- captcha==0.5.0
- pyopenms_viz==1.0.0
- streamlit-js-eval
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pyopenms==3.2.0
numpy==1.26.4 # pandas and numpy are dependencies of pyopenms, however, pyopenms needs numpy<=1.26.4
plotly==5.22.0
captcha==0.5.0
pyopenms_viz>=0.1.2
pyopenms_viz==1.0.0
streamlit-js-eval
redis==5.2.1
rq==2.1.0
rq==2.1.0
2 changes: 2 additions & 0 deletions settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"app-name": "OpenMS WebApp Template",
"github-user": "OpenMS",
"version": "1.0.2",
"repository-name": "streamlit-template",
"analytics": {
"google-analytics": {
Expand All @@ -13,5 +14,6 @@
}
},
"online_deployment": false,
"enable_workspaces": true,
"test": true
}
143 changes: 92 additions & 51 deletions src/common/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ def load_params(default: bool = False) -> dict[str, Any]:
Returns:
dict[str, Any]: A dictionary containing the parameters.
"""

# Check if workspace is enabled. If not, load default parameters.
if not st.session_state.settings["enable_workspaces"]:
default = True

# Construct the path to the parameter file
path = Path(st.session_state.workspace, "params.json")

Expand Down Expand Up @@ -75,6 +80,11 @@ def save_params(params: dict[str, Any]) -> None:
Returns:
dict[str, Any]: Updated parameters.
"""

# Check if the workspace is enabled and if a 'params.json' file exists in the workspace directory
if not st.session_state.settings["enable_workspaces"]:
return

# Update the parameter dictionary with any modified parameters from the current session
for key, value in st.session_state.items():
if key in params.keys():
Expand Down Expand Up @@ -199,21 +209,28 @@ def page_setup(page: str = "") -> dict[str, Any]:
os.chdir("../streamlit-template")
# Define the directory where all workspaces will be stored
workspaces_dir = Path("..", "workspaces-" + st.session_state.settings["repository-name"])
if "workspace" in st.query_params:
st.session_state.workspace = Path(workspaces_dir, st.query_params.workspace)
elif st.session_state.location == "online":
workspace_id = str(uuid.uuid1())
st.session_state.workspace = Path(workspaces_dir, workspace_id)
st.query_params.workspace = workspace_id
# Check if workspace logic is enabled
if st.session_state.settings["enable_workspaces"]:
if "workspace" in st.query_params:
st.session_state.workspace = Path(workspaces_dir, st.query_params.workspace)
elif st.session_state.location == "online":
workspace_id = str(uuid.uuid1())
st.session_state.workspace = Path(workspaces_dir, workspace_id)
st.query_params.workspace = workspace_id
else:
st.session_state.workspace = Path(workspaces_dir, "default")
st.query_params.workspace = "default"

else:
# Use default workspace when workspace feature is disabled
st.session_state.workspace = Path(workspaces_dir, "default")
st.query_params.workspace = "default"

if st.session_state.location != "online":
# not any captcha so, controllo should be true
st.session_state["controllo"] = True

if "workspace" not in st.query_params:
# If no workspace is specified and workspace feature is enabled, set default workspace and query param
if "workspace" not in st.query_params and st.session_state.settings["enable_workspaces"]:
st.query_params.workspace = st.session_state.workspace.name

# Make sure the necessary directories exist
Expand Down Expand Up @@ -259,51 +276,53 @@ def render_sidebar(page: str = "") -> None:
params = load_params()
with st.sidebar:
# The main page has workspace switcher
with st.expander("🖥️ **Workspaces**"):
# Define workspaces directory outside of repository
workspaces_dir = Path("..", "workspaces-" + st.session_state.settings["repository-name"])
# Online: show current workspace name in info text and option to change to other existing workspace
if st.session_state.location == "local":
# Define callback function to change workspace
def change_workspace():
for key in params.keys():
if key in st.session_state.keys():
del st.session_state[key]
st.session_state.workspace = Path(
workspaces_dir, st.session_state["chosen-workspace"]
# Display workspace switcher if workspace is enabled in local mode
if st.session_state.settings["enable_workspaces"]:
with st.expander("🖥️ **Workspaces**"):
# Define workspaces directory outside of repository
workspaces_dir = Path("..", "workspaces-" + st.session_state.settings["repository-name"])
# Online: show current workspace name in info text and option to change to other existing workspace
if st.session_state.location == "local":
# Define callback function to change workspace
def change_workspace():
for key in params.keys():
if key in st.session_state.keys():
del st.session_state[key]
st.session_state.workspace = Path(
workspaces_dir, st.session_state["chosen-workspace"]
)
st.query_params.workspace = st.session_state["chosen-workspace"]

# Get all available workspaces as options
options = [
file.name for file in workspaces_dir.iterdir() if file.is_dir()
]
# Let user chose an already existing workspace
st.selectbox(
"choose existing workspace",
options,
index=options.index(str(st.session_state.workspace.stem)),
on_change=change_workspace,
key="chosen-workspace",
)
st.query_params.workspace = st.session_state["chosen-workspace"]

# Get all available workspaces as options
options = [
file.name for file in workspaces_dir.iterdir() if file.is_dir()
]
# Let user chose an already existing workspace
st.selectbox(
"choose existing workspace",
options,
index=options.index(str(st.session_state.workspace.stem)),
on_change=change_workspace,
key="chosen-workspace",
)
# Create or Remove workspaces
create_remove = st.text_input("create/remove workspace", "")
path = Path(workspaces_dir, create_remove)
# Create new workspace
if st.button("**Create Workspace**"):
path.mkdir(parents=True, exist_ok=True)
st.session_state.workspace = path
st.query_params.workspace = create_remove
# Temporary as the query update takes a short amount of time
time.sleep(1)
st.rerun()
# Remove existing workspace and fall back to default
if st.button("⚠️ Delete Workspace"):
if path.exists():
shutil.rmtree(path)
st.session_state.workspace = Path(workspaces_dir, "default")
st.query_params.workspace = "default"
# Create or Remove workspaces
create_remove = st.text_input("create/remove workspace", "")
path = Path(workspaces_dir, create_remove)
# Create new workspace
if st.button("**Create Workspace**"):
path.mkdir(parents=True, exist_ok=True)
st.session_state.workspace = path
st.query_params.workspace = create_remove
# Temporary as the query update takes a short amount of time
time.sleep(1)
st.rerun()
# Remove existing workspace and fall back to default
if st.button("⚠️ Delete Workspace"):
if path.exists():
shutil.rmtree(path)
st.session_state.workspace = Path(workspaces_dir, "default")
st.query_params.workspace = "default"
st.rerun()

# All pages have settings, workflow indicator and logo
with st.expander("⚙️ **Settings**"):
Expand All @@ -322,6 +341,28 @@ def change_workspace():
)
else:
st.session_state["spectrum_num_bins"] = 50

# Display OpenMS WebApp Template Version from settings.json
with st.container():
st.markdown(
"""
<style>
.version-box {
border: 1px solid #a4a5ad;
padding: 10px;
border-radius: 0.5rem;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
</style>
""",
unsafe_allow_html=True
)
version_info = st.session_state.settings["version"]
app_name = st.session_state.settings["app-name"]
st.markdown(f'<div class="version-box">{app_name}<br>Version: {version_info}</div>', unsafe_allow_html=True)
return params


Expand Down
25 changes: 16 additions & 9 deletions src/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def get_df(file: Union[str, Path]) -> pd.DataFrame:
else:
precs.append(np.nan)
df_spectra["precursor m/z"] = precs

# Drop spectra without peaks
df_spectra = df_spectra[df_spectra["mzarray"].apply(lambda x: len(x) > 0)]

df_spectra["max intensity m/z"] = df_spectra.apply(
lambda x: x["mzarray"][x["intarray"].argmax()], axis=1
)
Expand Down Expand Up @@ -75,13 +79,13 @@ def plot_bpc_tic() -> go.Figure:
fig = df.plot(
backend="ms_plotly",
kind="chromatogram",
fig=fig,
x="RT",
y="inty",
by="type",
line_color="#f24c5c",
color="#f24c5c",
show_plot=False,
grid=False,
aggregate_duplicates=True,
)
if st.session_state.view_bpc:
df = st.session_state.view_ms1.groupby("RT").max().reset_index()
Expand All @@ -91,13 +95,13 @@ def plot_bpc_tic() -> go.Figure:
fig = df.plot(
backend="ms_plotly",
kind="chromatogram",
fig=fig,
x="RT",
y="inty",
by="type",
line_color="#2d3a9d",
color="#2d3a9d",
show_plot=False,
grid=False,
aggregate_duplicates=True,
)
if st.session_state.view_eic:
df = st.session_state.view_ms1
Expand All @@ -111,21 +115,21 @@ def plot_bpc_tic() -> go.Figure:
df_eic = df[
(df["mz"] >= target_value - tolerance)
& (df["mz"] <= target_value + tolerance)
]
].copy()
if not df_eic.empty:
df_eic["type"] = "XIC"
df_eic.loc[:, "type"] = "XIC"
if df_eic["inty"].max() > max_int:
max_int = df_eic["inty"].max()
fig = df_eic.plot(
backend="ms_plotly",
kind="chromatogram",
fig=fig,
x="RT",
y="inty",
by="type",
line_color="#f6bf26",
color="#f6bf26",
show_plot=False,
grid=False,
aggregate_duplicates=True,
)
except ValueError:
st.error("Invalid m/z value for XIC provided. Please enter a valid number.")
Expand All @@ -149,12 +153,13 @@ def plot_ms_spectrum(df, title, bin_peaks, num_x_bins):
backend="ms_plotly",
x="mz",
y="intensity",
line_color="#2d3a9d",
color="#2d3a9d",
title=title,
show_plot=False,
grid=False,
bin_peaks=bin_peaks,
num_x_bins=num_x_bins,
aggregate_duplicates=True,
)
fig.update_layout(
template="plotly_white", dragmode="select", plot_bgcolor="rgb(255,255,255)"
Expand Down Expand Up @@ -183,6 +188,7 @@ def view_peak_map():
show_plot=False,
bin_peaks=True,
backend="ms_plotly",
aggregate_duplicates=True,
)
peak_map.update_layout(template="simple_white", dragmode="select")
c1, c2 = st.columns(2)
Expand Down Expand Up @@ -212,6 +218,7 @@ def view_peak_map():
num_x_bins=st.session_state.spectrum_num_bins,
height=650,
width=900,
aggregate_duplicates=True,
)
st.plotly_chart(peak_map_3D, use_container_width=True)

Expand Down

0 comments on commit 89a84d7

Please sign in to comment.