Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/build-windows-executable-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ env:
OPENMS_VERSION: 3.2.0
PYTHON_VERSION: 3.11.0
# Name of the installer
APP_NAME: FLASHApp-0.50
APP_NAME: FLASHApp-0.70

jobs:
build-vue-js-component:
Expand Down
1 change: 1 addition & 0 deletions .streamlit/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ developmentMode = false

[server]
port = 8501 # should be same as configured in deployment repo
maxUploadSize = 1000

[theme]

Expand Down
165 changes: 22 additions & 143 deletions content/FLASHDeconv/FLASHDeconvViewer.py
Original file line number Diff line number Diff line change
@@ -1,142 +1,15 @@
import numpy as np
import pandas as pd
import streamlit as st

from pathlib import Path

from src.common.common import page_setup, save_params
from src.masstable import getMSSignalDF, getSpectraTableDF
from src.components import PlotlyHeatmap, PlotlyLineplot, Plotly3Dplot, Tabulator, SequenceView, InternalFragmentMap, \
FlashViewerComponent, flash_viewer_grid_component, FDRPlotly
from src.sequence import getFragmentDataFromSeq, getInternalFragmentDataFromSeq
from src.workflow.FileManager import FileManager

from src.render.render import render_grid

DEFAULT_LAYOUT = [['ms1_deconv_heat_map'], ['scan_table', 'mass_table'],
['anno_spectrum', 'deconv_spectrum'], ['3D_SN_plot']]


def sendDataToJS(selected_data, layout_info_per_exp, grid_key='flash_viewer_grid'):

# Get data
results = file_manager.get_results(
selected_data,
['anno_dfs', 'deconv_dfs', 'parsed_tsv_file_ms1', 'parsed_tsv_file_ms2'],
partial=True
)
spec_df = results['deconv_dfs']
anno_df = results['anno_dfs']

fdr_dfs = []
if 'parsed_tsv_file_ms1' in results:
fdr_dfs.append(results['parsed_tsv_file_ms1'])
if 'parsed_tsv_file_ms2' in results:
fdr_dfs.append(results['parsed_tsv_file_ms2'])
if len(fdr_dfs) > 0:
fdr_dfs = pd.concat(fdr_dfs, axis=0, ignore_index=True)
else:
fdr_dfs = None

components = []
data_to_send = {}
per_scan_contents = {'mass_table': False, 'anno_spec': False, 'deconv_spec': False, '3d': False}
for row in layout_info_per_exp:
components_of_this_row = []
for col_index, comp_name in enumerate(row):
component_arguments = None

# prepare component arguments
if comp_name == 'ms1_raw_heatmap':
data_to_send['raw_heatmap_df'] = getMSSignalDF(anno_df)
component_arguments = PlotlyHeatmap(title="Raw MS1 Heatmap")
elif comp_name == 'ms1_deconv_heat_map':
data_to_send['deconv_heatmap_df'] = getMSSignalDF(spec_df)
component_arguments = PlotlyHeatmap(title="Deconvolved MS1 Heatmap")
elif comp_name == 'scan_table':
data_to_send['per_scan_data'] = getSpectraTableDF(spec_df)
component_arguments = Tabulator('ScanTable')
elif comp_name == 'deconv_spectrum':
per_scan_contents['deconv_spec'] = True
component_arguments = PlotlyLineplot(title="Deconvolved Spectrum")
elif comp_name == 'anno_spectrum':
per_scan_contents['anno_spec'] = True
component_arguments = PlotlyLineplot(title="Annotated Spectrum")
elif comp_name == 'mass_table':
per_scan_contents['mass_table'] = True
component_arguments = Tabulator('MassTable')
elif comp_name == '3D_SN_plot':
per_scan_contents['3d'] = True
component_arguments = Plotly3Dplot(title="Precursor Signals")
elif comp_name == 'sequence_view':
data_to_send['sequence_data'] = {0: getFragmentDataFromSeq(st.session_state.input_sequence)}
component_arguments = SequenceView()
elif comp_name == 'internal_fragment_map':
data_to_send['internal_fragment_data'] = {0: getInternalFragmentDataFromSeq(st.session_state.input_sequence)}
component_arguments = InternalFragmentMap()
elif comp_name == 'fdr_plot':
if fdr_dfs is not None:
ecdf_target, ecdf_decoy = ecdf(fdr_dfs)
data_to_send['ecdf_target'] = ecdf_target
data_to_send['ecdf_decoy'] = ecdf_decoy
component_arguments = FDRPlotly()

components_of_this_row.append(FlashViewerComponent(component_arguments))
components.append(components_of_this_row)

if any(per_scan_contents.values()):
scan_table = data_to_send['per_scan_data']
dfs = [scan_table]
for key, exist in per_scan_contents.items():
if not exist: continue

if key == 'mass_table':
tmp_df = spec_df[['mzarray', 'intarray', 'MinCharges', 'MaxCharges', 'MinIsotopes', 'MaxIsotopes',
'cos', 'snr', 'qscore']].copy()
tmp_df.rename(columns={'mzarray': 'MonoMass', 'intarray': 'SumIntensity', 'cos': 'CosineScore',
'snr': 'SNR', 'qscore': 'QScore'},
inplace=True)
elif key == 'deconv_spec':
if per_scan_contents['mass_table']: continue # deconv_spec shares same data with mass_table

tmp_df = spec_df[['mzarray', 'intarray']].copy()
tmp_df.rename(columns={'mzarray': 'MonoMass', 'intarray': 'SumIntensity'}, inplace=True)
elif key == 'anno_spec':
tmp_df = anno_df[['mzarray', 'intarray']].copy()
tmp_df.rename(columns={'mzarray': 'MonoMass_Anno', 'intarray': 'SumIntensity_Anno'}, inplace=True)
elif key == '3d':
tmp_df = spec_df[['PrecursorScan', 'SignalPeaks', 'NoisyPeaks']].copy()
else: # shouldn't come here
continue

dfs.append(tmp_df)
data_to_send['per_scan_data'] = pd.concat(dfs, axis=1)

# if Internal fragment map was selected, but sequence view was not
if ('internal_fragment_data' in data_to_send) and ('sequence_data' not in data_to_send):
data_to_send['sequence_data'] = {0 : getFragmentDataFromSeq(st.session_state.input_sequence)}
data_to_send['dataset'] = selected_data

flash_viewer_grid_component(components=components, data=data_to_send, component_key=grid_key)

def ecdf(df):
target_qscores = df[df['TargetDecoyType'] == 0]['Qscore']
decoy_qscores = df[df['TargetDecoyType'] > 0]['Qscore']

ecdf_target = pd.DataFrame({
'x' : np.sort(target_qscores),
'y' : np.arange(1, len(target_qscores) + 1) / len(target_qscores)
})
ecdf_decoy = pd.DataFrame({
'x' : np.sort(decoy_qscores),
'y' : np.arange(1, len(decoy_qscores) + 1) / len(decoy_qscores)
})
return ecdf_target, ecdf_decoy

def setSequenceViewInDefaultView():
if 'input_sequence' in st.session_state and st.session_state.input_sequence:
global DEFAULT_LAYOUT
DEFAULT_LAYOUT = DEFAULT_LAYOUT + [['sequence_view']]

if 'input_sequence' in st.session_state and st.session_state.input_sequence:
DEFAULT_LAYOUT = DEFAULT_LAYOUT + [['sequence_view']]

def select_experiment():
st.session_state.selected_experiment0 = st.session_state.selected_experiment_dropdown
Expand All @@ -146,15 +19,9 @@ def select_experiment():
continue
st.session_state[f"selected_experiment{exp_index}"] = st.session_state[f'selected_experiment_dropdown_{exp_index}']





# page initialization
params = page_setup()

st.title("FLASHViewer")
setSequenceViewInDefaultView()

# Get available results
file_manager = FileManager(
Expand Down Expand Up @@ -190,8 +57,10 @@ def select_experiment():
on_change=select_experiment
)
if 'selected_experiment0' in st.session_state:
with st.spinner('Loading component...'):
sendDataToJS(st.session_state.selected_experiment0, layout[0])
render_grid(
st.session_state.selected_experiment0, layout[0], file_manager,
'flashdeconv', "selected_experiment0", 'flash_viewer_grid_0'
)
with c2:
st.selectbox(
"choose experiment", results,
Expand All @@ -201,7 +70,11 @@ def select_experiment():
)
if f"selected_experiment1" in st.session_state:
with st.spinner('Loading component...'):
sendDataToJS(st.session_state["selected_experiment1"], layout[1], 'flash_viewer_grid_1')
render_grid(
st.session_state["selected_experiment1"], layout[1],
file_manager, 'flashdeconv', 'selected_experiment1',
'flash_viewer_grid_1'
)

else:
### for only single experiment on one view
Expand All @@ -214,8 +87,10 @@ def select_experiment():


if 'selected_experiment0' in st.session_state:
with st.spinner('Loading component...'):
sendDataToJS(st.session_state.selected_experiment0, layout[0])
render_grid(
st.session_state.selected_experiment0, layout[0], file_manager,
'flashdeconv', 'selected_experiment0'
)

### for multiple experiments on one view
if len(layout) > 1:
Expand All @@ -233,7 +108,11 @@ def select_experiment():
)
# if #experiment input files are less than #layouts, all the pre-selection will be the first experiment
if f"selected_experiment{exp_index}" in st.session_state:
with st.spinner('Loading component...'):
sendDataToJS(st.session_state["selected_experiment%d" % exp_index], layout[exp_index], 'flash_viewer_grid_%d' % exp_index)
render_grid(
st.session_state["selected_experiment%d" % exp_index],
layout[exp_index], file_manager, 'flashdeconv',
"selected_experiment%d" % exp_index,
'flash_viewer_grid_%d' % exp_index
)

save_params(params)
17 changes: 11 additions & 6 deletions content/FLASHQuant/FLASHQuantViewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from src.workflow.FileManager import FileManager
from src.common.common import page_setup, save_params
from src.components import flash_viewer_grid_component, FlashViewerComponent, FLASHQuant

# from src.render.components import flash_viewer_grid_component, FlashViewerComponent, FLASHQuant
from src.render.render import render_grid

# page initialization
params = page_setup()
Expand Down Expand Up @@ -34,10 +34,15 @@
st.selectbox("choose experiment", results, key="selected_experiment0_quant")
selected_exp0 = st.session_state.selected_experiment0_quant

# Get data
quant_df = file_manager.get_results(selected_exp0, 'quant_dfs')['quant_dfs']
render_grid(
st.session_state.selected_experiment0_quant, [['quant_visualization']],
file_manager, 'flashquant', 'selected_experiment0_quant'
)

# # Get data
# quant_df = file_manager.get_results(selected_exp0, 'quant_dfs')['quant_dfs']

component = [[FlashViewerComponent(FLASHQuant())]]
flash_viewer_grid_component(components=component, data={'quant_data': quant_df, 'dataset': selected_exp0}, component_key='flash_viewer_grid')
# component = [[FlashViewerComponent(FLASHQuant())]]
# flash_viewer_grid_component(components=component, data={'quant_data': quant_df, 'dataset': selected_exp0}, component_key='flash_viewer_grid')
Comment on lines +42 to +46
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove commented-out code.

Since the refactoring to use the new rendering system is now complete, the commented-out code for manual data retrieval and component initialization should be removed.

-# # Get data
-# quant_df = file_manager.get_results(selected_exp0, 'quant_dfs')['quant_dfs']

-# component = [[FlashViewerComponent(FLASHQuant())]]
-# flash_viewer_grid_component(components=component, data={'quant_data': quant_df, 'dataset': selected_exp0}, component_key='flash_viewer_grid')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# # Get data
# quant_df = file_manager.get_results(selected_exp0, 'quant_dfs')['quant_dfs']
component = [[FlashViewerComponent(FLASHQuant())]]
flash_viewer_grid_component(components=component, data={'quant_data': quant_df, 'dataset': selected_exp0}, component_key='flash_viewer_grid')
# component = [[FlashViewerComponent(FLASHQuant())]]
# flash_viewer_grid_component(components=component, data={'quant_data': quant_df, 'dataset': selected_exp0}, component_key='flash_viewer_grid')


save_params(params)
2 changes: 1 addition & 1 deletion content/FLASHTnT/FLASHTnTLayoutManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
'sequence_view',
'internal_fragment_map',
'tag_table',
'deconv_spectrum'
'combined_spectrum'
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Component name updated from 'deconv_spectrum' to 'combined_spectrum'.

This naming change aligns with the unified data rendering approach being implemented across the visualization modules. Ensure that all references to this component in other parts of the codebase (such as templates, component initialization logic, and documentation) have been updated consistently.


🏁 Script executed:

#!/bin/bash
# Verify all references to the spectrum component have been updated consistently
echo "Searching for any remaining references to 'deconv_spectrum'..."
rg "deconv_spectrum" --type py

Length of output: 1091


Missing references to rename ‘deconv_spectrum’ to ‘combined_spectrum’

The search uncovered several remaining usages of the old component name that must be updated:

• src/render/initialize.py
elif comp_name == 'deconv_spectrum':
file_manager.get_results(..., ['deconv_spectrum'])
data_to_send['per_scan_data'] = data['deconv_spectrum']
• src/parse/deconv.py
file_manager.store_data(dataset_id, 'deconv_spectrum', deconv_spectrum)
– References in concatenation, renaming, and list literals
• content/FLASHDeconv/FLASHDeconvViewer.py
– Initialization lists including ‘deconv_spectrum’
• content/FLASHDeconv/FLASHDeconvLayoutManager.py
– LayoutManager component list entry

Please update all of these to use 'combined_spectrum' (including import/initialization logic, data-store keys, and template references) so that the component name is consistent across the codebase.

]

# Setup cache access
Expand Down
Loading
Loading