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
83 changes: 41 additions & 42 deletions content/FLASHDeconv/FLASHDeconvWorkflow.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import time

import pandas as pd
import streamlit as st

Expand Down Expand Up @@ -25,65 +27,62 @@
wf.show_execution_section()
with t[3]:

# (file name suffix, name tag, prefix FLASHDeconv uses in its own output)
UPLOAD_FILE_TYPES = (
('deconv.mzML', 'out_deconv_mzML', 'out'),
('annotated.mzML', 'anno_annotated_mzML', 'anno'),
('spec1.tsv', 'spec1_tsv', ''),
('spec2.tsv', 'spec2_tsv', ''),
)

def process_uploaded_files(uploaded_files):


# FLASHDeconv names its output files 'out_deconv.mzML' and
# 'anno_annotated.mzML', so the part in front of the suffix ('out'
# and 'anno') is not an experiment name: file those under a common
# dataset, otherwise the two halves of a run never meet.
default_dataset = time.strftime('uploaded_%Y%m%d-%H%M%S')

# Store all uploaded files
for file in uploaded_files:
if file.name.endswith("mzML"):
if file.name.endswith('_deconv.mzML'):
wf.file_manager.store_file(
file.name.split('_deconv.mzML')[0], 'out_deconv_mzML', file
)
elif file.name.endswith('_annotated.mzML'):
wf.file_manager.store_file(
file.name.split('_annotated.mzML')[0], 'anno_annotated_mzML', file
)
else:
st.warning(f'Invalid file : {file.name}')
elif file.name.endswith("tsv"):
if file.name.endswith('_spec1.tsv'):
wf.file_manager.store_file(
file.name.split('_spec1.tsv')[0], 'spec1_tsv', file
)
elif file.name.endswith('_spec2.tsv'):
wf.file_manager.store_file(
file.name.split('_spec2.tsv')[0], 'spec2_tsv', file
)
else:
st.warning(f'Invalid file : {file.name}')
for suffix, name_tag, tool_prefix in UPLOAD_FILE_TYPES:
if not file.name.endswith(suffix):
continue
experiment = file.name[:-len(suffix)].rstrip('_')
if experiment in ('', tool_prefix):
experiment = default_dataset
wf.file_manager.store_file(experiment, name_tag, file)
break
else:
st.warning(f'Invalid file : {file.name}')

# Get the unparsed files
input_files = set(wf.file_manager.get_results_list(['out_deconv_mzML', 'anno_annotated_mzML']))
parsed_files = set(wf.file_manager.get_results_list(['deconv_dfs', 'anno_dfs']))
unparsed_files = input_files - parsed_files

# Get the unpared tsv files
ms1_tsv_files = set(wf.file_manager.get_results_list(['spec1_tsv']))
parsed_ms1_tsv_files = set(wf.file_manager.get_results_list(['parsed_tsv_file_ms1']))
ms2_tsv_files = set(wf.file_manager.get_results_list(['spec2_tsv']))
parsed_ms2_tsv_files = set(wf.file_manager.get_results_list(['parsed_tsv_file_ms2']))
unparsed_tsv_files = (
(
(ms1_tsv_files - parsed_ms1_tsv_files)
| (ms2_tsv_files - parsed_ms2_tsv_files)
) & input_files
)

# Process unparsed datasets
for unparsed_dataset in (unparsed_files | unparsed_tsv_files):
for unparsed_dataset in unparsed_files:
results = wf.file_manager.get_results(
unparsed_dataset,
['out_deconv_mzML', 'anno_annotated_mzML',
'spec1_tsv', 'spec2_tsv'],
partial=True
)

parsed_data = parseDeconv(**results)

for k, v in parsed_data.items():
wf.file_manager.store_data(unparsed_dataset, k, v)
if not ('out_deconv_mzML' in results and 'anno_annotated_mzML' in results):
st.warning(
f"Experiment '{unparsed_dataset}' needs both the "
"deconvolved and the annotated mzML file."
)
continue

with st.spinner(f"Processing '{unparsed_dataset}'..."):
parseDeconv(
wf.file_manager, unparsed_dataset,
results['out_deconv_mzML'], results['anno_annotated_mzML'],
results.get('spec1_tsv'), results.get('spec2_tsv'),
logger=wf.logger
)

st.subheader("**Upload FLASHDeconv output files (\*_annotated.mzML & \*_deconv.mzML) or spec1/2 TSV files (Qscore Density Plot only)**")
st.info(
Expand Down
99 changes: 64 additions & 35 deletions content/FLASHTnT/FLASHTnTWorkflow.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import time

import pandas as pd
import streamlit as st

from pathlib import Path

from src.parse.tnt import parseTnT
from src.parse.deconv import parseDeconv
from src.Workflow import TagWorkflow
from src.common.common import page_setup, save_params

Expand All @@ -25,35 +28,43 @@
wf.show_execution_section()
with t[3]:

# (file name suffix, name tag, prefix the tools use in their own output)
UPLOAD_FILE_TYPES = (
('deconv.mzML', 'out_deconv_mzML', 'out'),
('annotated.mzML', 'anno_annotated_mzML', 'anno'),
('tags.tsv', 'tags_tsv', ''),
('tagged.tsv', 'tags_tsv', ''),
('protein.tsv', 'protein_tsv', ''),
)

REQUIRED_FILES = (
('deconvolved mzML', 'out_deconv_mzML'),
('annotated mzML', 'anno_annotated_mzML'),
('tags.tsv', 'tags_tsv'),
('protein.tsv', 'protein_tsv'),
)

def process_uploaded_files(uploaded_files):


# FLASHDeconv and FLASHTnT name their output files 'out_deconv.mzML',
# 'anno_annotated.mzML', 'tags.tsv' and 'protein.tsv', so the part in
# front of the suffix is not an experiment name: file those under a
# common dataset, otherwise the files of a run never meet.
default_dataset = time.strftime('uploaded_%Y%m%d-%H%M%S')

# Store all uploaded files
for file in uploaded_files:
if file.name.endswith("mzML"):
if file.name.endswith('_deconv.mzML'):
wf.file_manager.store_file(
file.name.split('_deconv.mzML')[0], 'out_deconv_mzML', file
)
elif file.name.endswith('_annotated.mzML'):
wf.file_manager.store_file(
file.name.split('_annotated.mzML')[0], 'anno_annotated_mzML', file
)
else:
st.warning(f'Invalid file : {file.name}')
elif file.name.endswith("tsv"):
if file.name.endswith('_tagged.tsv'):
wf.file_manager.store_file(
file.name.split('_tagged.tsv')[0], 'tags_tsv', file
)
elif file.name.endswith('_protein.tsv'):
wf.file_manager.store_file(
file.name.split('_protein.tsv')[0], 'protein_tsv', file
)
else:
st.warning(f'Invalid file : {file.name}')
for suffix, name_tag, tool_prefix in UPLOAD_FILE_TYPES:
if not file.name.endswith(suffix):
continue
experiment = file.name[:-len(suffix)].rstrip('_')
if experiment in ('', tool_prefix):
experiment = default_dataset
wf.file_manager.store_file(experiment, name_tag, file)
break
else:
st.warning(f'Invalid file : {file.name}')

# Get the unparsed files
input_files = set(wf.file_manager.get_results_list(
['out_deconv_mzML', 'anno_annotated_mzML', 'tags_tsv', 'protein_tsv']
Expand All @@ -64,22 +75,40 @@ def process_uploaded_files(uploaded_files):
unparsed_files = input_files - parsed_files

# Process unparsed datasets
for unparsed_dataset in (unparsed_files):
for unparsed_dataset in unparsed_files:
results = wf.file_manager.get_results(
unparsed_dataset,
['out_deconv_mzML', 'anno_annotated_mzML', 'tags_tsv', 'protein_tsv']
['out_deconv_mzML', 'anno_annotated_mzML', 'tags_tsv', 'protein_tsv'],
partial=True
)

parsed_data = parseTnT(
results['out_deconv_mzML'], results['anno_annotated_mzML'],
results['tags_tsv'], results['protein_tsv']
)

for k, v in parsed_data.items():
wf.file_manager.store_data(unparsed_dataset, k, v)
missing = [n for n, tag in REQUIRED_FILES if tag not in results]
if missing:
st.warning(
f"Experiment '{unparsed_dataset}' is missing the "
f"{', '.join(missing)} file(s)."
)
continue

with st.spinner(f"Processing '{unparsed_dataset}'..."):
# The tags are matched against the deconvolved masses, so the
# mzML files have to be parsed first
if not wf.file_manager.result_exists(
unparsed_dataset, 'deconv_tolerance'
):
parseDeconv(
wf.file_manager, unparsed_dataset,
results['out_deconv_mzML'], results['anno_annotated_mzML'],
logger=wf.logger
)
parseTnT(
wf.file_manager, unparsed_dataset,
results['out_deconv_mzML'], results['anno_annotated_mzML'],
results['tags_tsv'], results['protein_tsv'],
logger=wf.logger
)

# Upload files via upload widget
st.subheader("**Upload FLASHDeconv & FLASHTagger output files (\*_annotated.mzML, \*_deconv.mzML, \*_tagged.tsv & \*_protein.tsv)**")
st.subheader("**Upload FLASHDeconv & FLASHTnT output files (anno_annotated.mzML, out_deconv.mzML, tags.tsv & protein.tsv)**")
# Display info how to upload files
st.info(
"""
Expand Down
12 changes: 9 additions & 3 deletions src/workflow/FileManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,19 @@ def store_file(self, dataset_id: str, name_tag: str, file: Path | BytesIO,
file (Path of File-Like): The file that should be stored.
remove (bool): Wether or not the file should be removed
after copying it.
filetype (str): The file extension of the file. Only
neccessary if a file-like object is used as input.
file_name (str): The name to store the file under. Only
neccessary if the input has no file extension to derive
it from.
"""

# Define storage path
if file_name is None:
file_name = f"{name_tag}{file.suffix}"
# File-like objects have no `suffix`; Streamlit's UploadedFile
# carries the original file name in `name` instead.
suffix = getattr(file, 'suffix', None)
if suffix is None:
suffix = Path(getattr(file, 'name', '')).suffix
file_name = f"{name_tag}{suffix}"

target_path = Path(
self.cache_path, 'files', dataset_id, file_name
Expand Down
Loading
Loading