Skip to content

Commit a8ca71b

Browse files
authored
Merge pull request #173 from mwang87/chromatogram-support
Chromatogram Support
2 parents a082a8e + d146a72 commit a8ca71b

File tree

6 files changed

+218
-37
lines changed

6 files changed

+218
-37
lines changed

app.py

Lines changed: 109 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868

6969
# Importing layout for HTML
7070
from layout_misc import EXAMPLE_DASHBOARD, SYCHRONIZATION_MODAL, SPECTRUM_DETAILS_MODAL, ADVANCED_VISUALIZATION_MODAL, ADVANCED_IMPORT_MODAL, ADVANCED_REPLAY_MODAL
71+
from layout_xic_options import ADVANCED_XIC_MODAL
7172

7273
server = Flask(__name__)
7374
app = dash.Dash(__name__, server=server, external_stylesheets=[dbc.themes.BOOTSTRAP])
@@ -199,7 +200,10 @@
199200
dbc.CardBody(dbc.Row(
200201
[ ## Left Panel
201202
dbc.Col([
202-
html.H5(children='File Selection'),
203+
dbc.Row(
204+
dbc.Col(html.H5(children='File Selection')),
205+
),
206+
html.Hr(),
203207
dbc.InputGroup(
204208
[
205209
dbc.InputGroupAddon("GNPS USI", addon_type="prepend"),
@@ -388,7 +392,20 @@
388392
], className="col-sm"),
389393
## Right Panel
390394
dbc.Col([
391-
html.H5(children='XIC Options'),
395+
dbc.Row([
396+
dbc.Col(html.H5(children='XIC Options')),
397+
dbc.Col(
398+
dbc.Button("Advanced XIC Options",
399+
id="advanced_xic_modal_button",
400+
color="info", size="sm",
401+
className="mr-1",
402+
style={
403+
"float" : "right"
404+
}
405+
),
406+
),
407+
]),
408+
html.Hr(),
392409
dbc.Row([
393410
dbc.Col(
394411
dbc.InputGroup(
@@ -407,16 +424,7 @@
407424
],
408425
className="mb-3",
409426
),
410-
),
411-
dbc.Col(
412-
dbc.InputGroup(
413-
[
414-
dbc.InputGroupAddon("XIC Peptide", addon_type="prepend"),
415-
dbc.Input(id='xic_peptide', placeholder="Enter Peptide to XIC", value=""),
416-
],
417-
className="mb-3",
418-
),
419-
),
427+
)
420428
]),
421429
dbc.Row([
422430
dbc.Col(
@@ -1368,6 +1376,7 @@
13681376
dbc.Row(ADVANCED_IMPORT_MODAL),
13691377
dbc.Row(ADVANCED_REPLAY_MODAL),
13701378
dbc.Row(ADVANCED_VISUALIZATION_MODAL),
1379+
dbc.Row(ADVANCED_XIC_MODAL),
13711380

13721381
],
13731382
fluid=True,
@@ -1623,6 +1632,8 @@ def draw_spectrum(usi, ms2_identifier, export_format, plot_theme, xic_mz):
16231632
Output("feature_finding_rt_tolerance", "value"),
16241633
Output("sychronization_session_id", "value"),
16251634
1635+
Output("chromatogram_options", "value"),
1636+
16261637
Output("comment", "value"),
16271638
16281639
Output("map_plot_color_scale", "value"),
@@ -1673,6 +1684,8 @@ def draw_spectrum(usi, ms2_identifier, export_format, plot_theme, xic_mz):
16731684
16741685
State('sychronization_session_id', 'value'),
16751686
1687+
State("chromatogram_options", "value"),
1688+
16761689
State("comment", 'value'),
16771690
16781691
State('map_plot_color_scale', 'value'),
@@ -1725,6 +1738,8 @@ def determine_url_only_parameters( search,
17251738

17261739
existing_sychronization_session_id,
17271740

1741+
existing_chromatogram_options,
1742+
17281743
existing_comment,
17291744

17301745
existing_map_plot_color_scale,
@@ -1798,6 +1813,9 @@ def determine_url_only_parameters( search,
17981813
default_session_id = existing_sychronization_session_id
17991814
sychronization_session_id = _get_param_from_url(search, "", "sychronization_session_id", default_session_id, session_dict=session_dict, old_value=existing_sychronization_session_id, no_change_default=dash.no_update)
18001815

1816+
# Chromatogram Options
1817+
chromatogram_options = _get_param_from_url(search, "", "chromatogram_options", dash.no_update, session_dict=session_dict, old_value=existing_chromatogram_options, no_change_default=dash.no_update)
1818+
18011819
# Comment
18021820
comment = _get_param_from_url(search, "", "comment", dash.no_update, session_dict=session_dict, old_value=existing_comment, no_change_default=dash.no_update)
18031821

@@ -1838,6 +1856,11 @@ def determine_url_only_parameters( search,
18381856
show_lcms_2nd_map = dash.no_update
18391857
except:
18401858
pass
1859+
1860+
try:
1861+
chromatogram_options = json.loads(chromatogram_options)
1862+
except:
1863+
pass
18411864

18421865
return [xic_formula,
18431866
xic_peptide,
@@ -1853,6 +1876,7 @@ def determine_url_only_parameters( search,
18531876
overlay_usi, overlay_mz, overlay_rt, overlay_color, overlay_size, overlay_hover, overlay_filter_column, overlay_filter_value,
18541877
feature_finding_type, feature_finding_ppm, feature_finding_noise, feature_finding_min_peak_rt, feature_finding_max_peak_rt, feature_finding_rt_tolerance,
18551878
sychronization_session_id,
1879+
chromatogram_options,
18561880
comment,
18571881
map_plot_color_scale,
18581882
map_plot_quantization_level]
@@ -2488,8 +2512,21 @@ def _perform_batch_xic(usi_list, usi1_list, usi2_list, xic_norm, all_xic_values,
24882512
pass
24892513

24902514
merged_df_long = pd.concat(df_long_list)
2515+
24912516
return merged_df_long, ms2_data
24922517

2518+
def _perform_chromatogram_extraction(usi_list, chromatogram_list):
2519+
usi = usi_list[0]
2520+
remote_link, local_filename = _resolve_usi(usi)
2521+
2522+
df_list = []
2523+
for chromatogram_value in chromatogram_list:
2524+
chromatogram_df = xic.get_chromatogram(local_filename, chromatogram_value)
2525+
chromatogram_df["USI"] = usi
2526+
df_list.append(chromatogram_df)
2527+
2528+
merged_df = pd.concat(df_list)
2529+
return merged_df
24932530

24942531
def _is_worker_up():
24952532
"""Gives us utility function to tell is celery is up and running
@@ -2528,6 +2565,27 @@ def _integrate_files(long_data_df, xic_integration_type):
25282565

25292566
return grouped_df
25302567

2568+
##################################
2569+
# XIC Chromatogram Options
2570+
##################################
2571+
@app.callback(Output('chromatogram_options', 'options'),
2572+
[
2573+
Input('usi', 'value'),
2574+
Input('usi2', 'value'),
2575+
])
2576+
def create_chromatogram_options(usi, usi2):
2577+
all_usi = usi.split("\n")
2578+
remote_link, local_filename = _resolve_usi(all_usi[0])
2579+
2580+
chromatogram_list = tasks.task_chromatogram_options(local_filename)
2581+
2582+
options = []
2583+
for term in chromatogram_list:
2584+
options.append({'label': term, 'value': term})
2585+
2586+
return options
2587+
2588+
25312589
# Creating XIC plot
25322590
@app.callback([
25332591
Output('xic-plot', 'figure'),
@@ -2540,20 +2598,21 @@ def _integrate_files(long_data_df, xic_integration_type):
25402598
Input('usi', 'value'),
25412599
Input('usi2', 'value'),
25422600
Input('xic_mz', 'value'),
2543-
Input('xic_formula', 'value'),
2544-
Input('xic_peptide', 'value'),
2545-
Input('xic_tolerance', 'value'),
2546-
Input('xic_ppm_tolerance', 'value'),
2547-
Input('xic_tolerance_unit', 'value'),
2548-
Input('xic_rt_window', 'value'),
2549-
Input('xic_integration_type', 'value'),
2550-
Input('xic_norm', 'value'),
2551-
Input('xic_file_grouping', 'value'),
2552-
Input('polarity_filtering', 'value'),
2553-
Input('image_export_format', 'value'),
2554-
Input("plot_theme", "value")
2601+
Input('xic_formula', 'value'),
2602+
Input('xic_peptide', 'value'),
2603+
Input('xic_tolerance', 'value'),
2604+
Input('xic_ppm_tolerance', 'value'),
2605+
Input('xic_tolerance_unit', 'value'),
2606+
Input('xic_rt_window', 'value'),
2607+
Input('xic_integration_type', 'value'),
2608+
Input('xic_norm', 'value'),
2609+
Input('xic_file_grouping', 'value'),
2610+
Input("chromatogram_options", "value"),
2611+
Input('polarity_filtering', 'value'),
2612+
Input('image_export_format', 'value'),
2613+
Input("plot_theme", "value"),
25552614
])
2556-
def draw_xic(usi, usi2, xic_mz, xic_formula, xic_peptide, xic_tolerance, xic_ppm_tolerance, xic_tolerance_unit, xic_rt_window, xic_integration_type, xic_norm, xic_file_grouping, polarity_filter, export_format, plot_theme):
2615+
def draw_xic(usi, usi2, xic_mz, xic_formula, xic_peptide, xic_tolerance, xic_ppm_tolerance, xic_tolerance_unit, xic_rt_window, xic_integration_type, xic_norm, xic_file_grouping, chromatogram_list, polarity_filter, export_format, plot_theme):
25572616
triggered_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
25582617
print("TRIGGERED XIC PLOT", triggered_id, file=sys.stderr)
25592618

@@ -2633,11 +2692,18 @@ def draw_xic(usi, usi2, xic_mz, xic_formula, xic_peptide, xic_tolerance, xic_ppm
26332692
pass
26342693

26352694
# Exiting if we don't have any valid XIC values
2636-
if len(all_xic_values) == 0:
2695+
if len(all_xic_values) == 0 and len(chromatogram_list) == 0:
26372696
return [placeholder_xic_plot, graph_config, dash.no_update, dash.no_update, dash.no_update]
26382697

2639-
# Performing XIC for all USI in the list
2640-
merged_df_long, ms2_data = _perform_batch_xic(usi_list, usi1_list, usi2_list, xic_norm, all_xic_values, parsed_xic_da_tolerance, parsed_xic_ppm_tolerance, xic_tolerance_unit, rt_min, rt_max, polarity_filter)
2698+
merged_df_long = pd.DataFrame()
2699+
if len(all_xic_values) > 0:
2700+
# Performing XIC for all USI in the list
2701+
merged_df_long, ms2_data = _perform_batch_xic(usi_list, usi1_list, usi2_list, xic_norm, all_xic_values, parsed_xic_da_tolerance, parsed_xic_ppm_tolerance, xic_tolerance_unit, rt_min, rt_max, polarity_filter)
2702+
2703+
# Looking at chromatograms only if a single file exists
2704+
if len(usi_list) == 1 and len(chromatogram_list) > 0:
2705+
chrom_df = _perform_chromatogram_extraction(usi_list, chromatogram_list)
2706+
merged_df_long = pd.concat([merged_df_long, chrom_df])
26412707

26422708
# Limit the plotting USIs, but not the integrals below
26432709
plotting_df = merged_df_long
@@ -3077,6 +3143,8 @@ def create_gnps_mzmine2_link(usi, usi2, feature_finding_type, feature_finding_pp
30773143
Input("sychronization_session_id", "value"),
30783144
Input("synchronization_leader_token", "value"),
30793145
3146+
Input("chromatogram_options", "value"),
3147+
30803148
Input("comment", "value"),
30813149
30823150
Input("map_plot_color_scale", "value"),
@@ -3091,6 +3159,7 @@ def create_link(usi, usi2, xic_mz, xic_formula, xic_peptide,
30913159
overlay_usi, overlay_mz, overlay_rt, overlay_color, overlay_size, overlay_hover, overlay_filter_column, overlay_filter_value,
30923160
feature_finding_type, feature_finding_ppm, feature_finding_noise, feature_finding_min_peak_rt, feature_finding_max_peak_rt, feature_finding_rt_tolerance,
30933161
sychronization_save_session_button_clicks, sychronization_session_id, synchronization_leader_token,
3162+
chromatogram_options,
30943163
comment,
30953164
map_plot_color_scale, map_plot_quantization_level,
30963165
synchronization_type):
@@ -3135,6 +3204,9 @@ def create_link(usi, usi2, xic_mz, xic_formula, xic_peptide,
31353204
# Sychronization Options
31363205
url_params["sychronization_session_id"] = sychronization_session_id
31373206

3207+
# mzML Chromatogram Options
3208+
url_params["chromatogram_options"] = json.dumps(chromatogram_options)
3209+
31383210
# Comment
31393211
url_params["comment"] = comment
31403212

@@ -3405,6 +3477,7 @@ def create_sychronization_link(sychronization_session_id, synchronization_leader
34053477

34063478

34073479

3480+
34083481
@app.callback(Output('network-link-button', 'children'),
34093482
[
34103483
Input('usi', 'value'),
@@ -3546,6 +3619,7 @@ def get_overlay_options(overlay_usi):
35463619

35473620

35483621

3622+
35493623
# Sychronization Section for callbacks
35503624
@app.callback([
35513625
Output('synchronization_leader_token', 'value'),
@@ -3759,6 +3833,13 @@ def toggle_modal(n1, n2, is_open):
37593833
[State("advanced_replay_modal", "is_open")],
37603834
)(toggle_modal)
37613835

3836+
app.callback(
3837+
Output("advanced_xic_modal", "is_open"),
3838+
[Input("advanced_xic_modal_button", "n_clicks"), Input("advanced_xic_modal_close", "n_clicks")],
3839+
[State("advanced_xic_modal", "is_open")],
3840+
)(toggle_modal)
3841+
3842+
37623843
# Helping to toggle the panels
37633844
def toggle_panel(n1, is_open):
37643845
if n1:

layout_misc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
import dash_daq as daq
1010

1111
# Plotly Imports
12-
1312
import plotly.express as px
14-
import plotly.graph_objects as go
13+
import plotly.graph_objects as go
1514

1615
EXAMPLE_DASHBOARD = [
1716
dbc.CardHeader(html.H5("Example Exploration Dashboards")),

layout_xic_options.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Dash imports
2+
3+
import dash
4+
import dash_core_components as dcc
5+
import dash_bootstrap_components as dbc
6+
import dash_html_components as html
7+
import dash_table
8+
from dash.dependencies import Input, Output, State
9+
import dash_daq as daq
10+
11+
# Plotly Imports
12+
import plotly.express as px
13+
import plotly.graph_objects as go
14+
15+
ADVANCED_XIC_MODAL = [
16+
dbc.Modal(
17+
[
18+
dbc.ModalHeader("XIC Options"),
19+
dbc.ModalBody([
20+
dbc.Row([
21+
dbc.Col(
22+
dbc.InputGroup(
23+
[
24+
dbc.InputGroupAddon("XIC Peptide", addon_type="prepend"),
25+
dbc.Input(id='xic_peptide', placeholder="Enter Peptide to XIC", value=""),
26+
],
27+
className="mb-3",
28+
),
29+
),
30+
]),
31+
dbc.Row([
32+
dbc.Col([
33+
html.H5("mzML Chromatograms"),
34+
dcc.Dropdown(
35+
id='chromatogram_options',
36+
options=[],
37+
searchable=False,
38+
clearable=True,
39+
multi=True,
40+
value=[],
41+
style={
42+
"width":"100%"
43+
}
44+
),
45+
]),
46+
])
47+
]),
48+
dbc.ModalFooter(
49+
dbc.Button("Close", id="advanced_xic_modal_close", className="ml-auto")
50+
),
51+
],
52+
id="advanced_xic_modal",
53+
size="xl",
54+
),
55+
]

tasks.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ def task_xic(local_filename, all_xic_values, xic_tolerance, xic_ppm_tolerance, x
5454
xic_df, ms2_data = xic_file(local_filename, all_xic_values, xic_tolerance, xic_ppm_tolerance, xic_tolerance_unit, rt_min, rt_max, polarity_filter, get_ms2=get_ms2)
5555
return xic_df.to_dict(orient="records"), ms2_data
5656

57+
@celery_instance.task(time_limit=60)
58+
def task_chromatogram_options(local_filename):
59+
# Caching
60+
chromatograms_list = memory.cache(xic.chromatograms_list)
61+
62+
options = chromatograms_list(local_filename)
63+
return options
64+
5765
@celery_instance.task(time_limit=90)
5866
def task_featurefinding(filename, params):
5967
feature_df = feature_finding.perform_feature_finding(filename, params, timeout=80)

test/test_debug.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@
1010
import download
1111

1212

13-
def test_scan_in_usi():
14-
usi = "mzspec:PXD023650:03552_GA1_P_041575_P00_A00_30min_R1.raw"
15-
remote_link = download._resolve_usi_remotelink(usi)
16-
print(remote_link)
13+
# def test_scan_in_usi():
14+
# usi = "mzspec:PXD023650:03552_GA1_P_041575_P00_A00_30min_R1.raw"
15+
# remote_link = download._resolve_usi_remotelink(usi)
16+
# print(remote_link)
17+
18+
# remote_link, local_filename = download._resolve_usi(usi, cleanup=False)
19+
# print(remote_link, local_filename)
20+
21+
def test_chromatograms():
22+
local_filename = "std1_022721.mzML"
23+
chrom_list = xic.chromatograms_list(local_filename)
24+
xic_df = xic.get_chromatogram(local_filename, chrom_list[0])
25+
26+
print(xic_df)
1727

18-
remote_link, local_filename = download._resolve_usi(usi, cleanup=False)
19-
print(remote_link, local_filename)

0 commit comments

Comments
 (0)