Skip to content

Commit 9f7f835

Browse files
authored
Merge pull request #242 from mwang87/mass-spec-query2
MassQL Inclusion into Interface
2 parents cf44cef + d1855fb commit 9f7f835

12 files changed

+262
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*pyc

Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ RUN conda install -c conda-forge openjdk=11.0.9.1
3333
COPY requirements.txt .
3434
RUN pip install -r requirements.txt
3535

36+
# Installing MassQL
37+
RUN pip install massql==0.0.11
38+
3639
COPY . /app
3740
WORKDIR /app
3841

app.py

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@
7272
from layout_xic_options import ADVANCED_XIC_MODAL
7373
from layout_overlay import OVERLAY_PANEL
7474
from layout_fastsearch import ADVANCED_LIBRARYSEARCH_MODAL, ADVANCED_LIBRARYSEARCHMASSIVEKB_MODAL
75+
from layout_massql import MASSSPEC_QUERY_PANEL
7576
from layout_sync import SYCHRONIZATION_MODAL
7677

7778

79+
7880
server = Flask(__name__)
7981
app = dash.Dash(__name__, server=server, external_stylesheets=[dbc.themes.BOOTSTRAP])
8082
app.title = 'GNPS - LCMS Browser'
@@ -166,6 +168,7 @@
166168
),
167169
dbc.Nav(
168170
[
171+
dbc.NavItem(dbc.NavLink("GNPS LCMS Dashboard - Version 0.53", href="/")),
169172
dbc.NavItem(dbc.NavLink("GNPS LCMS Dashboard - Version 0.54", href="/")),
170173
dbc.NavItem(dbc.NavLink("Documentation", href="https://ccms-ucsd.github.io/GNPSDocumentation/lcms-dashboard/")),
171174
dbc.NavItem(dbc.NavLink("GNPS Datasets", href="https://gnps.ucsd.edu/ProteoSAFe/datasets.jsp#%7B%22query%22%3A%7B%7D%2C%22table_sort_history%22%3A%22createdMillis_dsc%22%2C%22title_input%22%3A%22GNPS%22%7D")),
@@ -361,6 +364,7 @@
361364
# {'label': 'TidyMS', 'value': 'TidyMS'},
362365
{'label': 'MZmine2 (Metabolomics)', 'value': 'MZmine2'},
363366
{'label': 'Dinosaur (Proteomics)', 'value': 'Dinosaur'},
367+
{'label': 'MassQL Query', 'value': 'MassQL'},
364368
],
365369
searchable=False,
366370
clearable=False,
@@ -1300,6 +1304,20 @@
13001304
)
13011305
]),
13021306

1307+
# MassQL Query Panel
1308+
dbc.Row([
1309+
dbc.Collapse(
1310+
[
1311+
dbc.Col([
1312+
dbc.Card(MASSSPEC_QUERY_PANEL),
1313+
]),
1314+
],
1315+
id='massql-collapse',
1316+
is_open=False,
1317+
style={"width": "100%", "marginTop": 30}
1318+
)
1319+
]),
1320+
13031321

13041322

13051323
# Show Data
@@ -1704,6 +1722,9 @@ def draw_fastsearch_massivekb(usi, usi_select, ms2_identifier):
17041722
Output("feature_finding_min_peak_rt", "value"),
17051723
Output("feature_finding_max_peak_rt", "value"),
17061724
Output("feature_finding_rt_tolerance", "value"),
1725+
1726+
Output("massql_statement", "value"),
1727+
17071728
Output("sychronization_session_id", "value"),
17081729
17091730
Output("chromatogram_options", "value"),
@@ -1762,6 +1783,8 @@ def draw_fastsearch_massivekb(usi, usi_select, ms2_identifier):
17621783
State('feature_finding_min_peak_rt', 'value'),
17631784
State('feature_finding_max_peak_rt', 'value'),
17641785
State('feature_finding_rt_tolerance', 'value'),
1786+
1787+
State("massql_statement", "value"),
17651788
17661789
State('sychronization_session_id', 'value'),
17671790
@@ -1825,6 +1848,8 @@ def determine_url_only_parameters( search,
18251848
existing_feature_finding_max_peak_rt,
18261849
existing_feature_finding_rt_tolerance,
18271850

1851+
existing_massql_statement,
1852+
18281853
existing_sychronization_session_id,
18291854

18301855
existing_chromatogram_options,
@@ -1839,7 +1864,7 @@ def determine_url_only_parameters( search,
18391864

18401865
# Here we clicked a button
18411866
if "darkmode_button" in triggered_id:
1842-
output = [dash.no_update] * 36
1867+
output = [dash.no_update] * 37
18431868
output[-1] = "plotly_dark"
18441869
output[-3] = "Turbo"
18451870
return output
@@ -1908,6 +1933,9 @@ def determine_url_only_parameters( search,
19081933
feature_finding_max_peak_rt = _get_param_from_url(search, "", "feature_finding_max_peak_rt", dash.no_update, session_dict=session_dict, old_value=existing_feature_finding_max_peak_rt, no_change_default=dash.no_update)
19091934
feature_finding_rt_tolerance = _get_param_from_url(search, "", "feature_finding_rt_tolerance", dash.no_update, session_dict=session_dict, old_value=existing_feature_finding_rt_tolerance, no_change_default=dash.no_update)
19101935

1936+
# MassQL
1937+
massql_statement = _get_param_from_url(search, "", "massql_statement", dash.no_update, session_dict=session_dict, old_value=existing_massql_statement, no_change_default=dash.no_update)
1938+
19111939
# Sychronization
19121940
default_session_id = str(uuid.uuid4()).replace("-", "")
19131941
if len(existing_sychronization_session_id) > 0:
@@ -1983,6 +2011,7 @@ def determine_url_only_parameters( search,
19832011
polarity_filtering2,
19842012
overlay_usi, overlay_mz, overlay_rt, overlay_color, overlay_size, overlay_hover, overlay_filter_column, overlay_filter_value,
19852013
feature_finding_type, feature_finding_ppm, feature_finding_noise, feature_finding_min_peak_rt, feature_finding_max_peak_rt, feature_finding_rt_tolerance,
2014+
massql_statement,
19862015
sychronization_session_id,
19872016
chromatogram_options,
19882017
comment,
@@ -2410,12 +2439,28 @@ def _perform_feature_finding(filename, feature_finding=None):
24102439
while(1):
24112440
if result.ready():
24122441
break
2413-
sleep(3)
2442+
sleep(1)
24142443
features_list = result.get()
24152444
else:
24162445
features_list = tasks.task_featurefinding(filename, json.dumps(feature_finding))
24172446

24182447
features_df = pd.DataFrame(features_list)
2448+
2449+
# Forcing Types
2450+
if "rt" in features_df:
2451+
features_df["rt"] = features_df["rt"].astype(float)
2452+
else:
2453+
features_df["rt"] = 1.0
2454+
2455+
if "mz" in features_df:
2456+
features_df["mz"] = features_df["mz"].astype(float)
2457+
else:
2458+
features_df["mz"] = 100.0
2459+
2460+
if "i" in features_df:
2461+
features_df["i"] = features_df["i"].astype(float)
2462+
else:
2463+
features_df["i"] = 0.0
24192464

24202465
return features_df
24212466

@@ -2469,6 +2514,7 @@ def _integrate_feature_finding(filename, lcms_fig, map_selection=None, feature_f
24692514

24702515
lcms_fig.add_trace(_intermediate_fig)
24712516
except:
2517+
#raise #DEBUG
24722518
pass
24732519

24742520
return lcms_fig, features_df
@@ -3274,8 +3320,12 @@ def render_initial_file_load(usi, usi_select, usi2):
32743320
status = html.H6([dbc.Badge("Ready", color="success", className="ml-1")])
32753321
if len(usi1_list) > 0:
32763322
try:
3323+
# Resolving USI
32773324
plot_usi = utils.determine_usi_to_use(usi, usi_select)
3278-
_resolve_usi(plot_usi)
3325+
remote_link, local_filename = _resolve_usi(plot_usi)
3326+
3327+
# Kicking off caching of data, asychronously
3328+
tasks.massql_cache(local_filename)
32793329
except:
32803330
status = html.H6([dbc.Badge("USI1 Loading Error", color="warning", className="ml-1")])
32813331
return [status]
@@ -3286,6 +3336,9 @@ def render_initial_file_load(usi, usi_select, usi2):
32863336
except:
32873337
status = html.H6([dbc.Badge("USI1 Loading Error", color="warning", className="ml-1")])
32883338
return [status]
3339+
3340+
3341+
32893342

32903343
return [status]
32913344

@@ -3325,6 +3378,8 @@ def render_initial_file_load(usi, usi_select, usi2):
33253378
33263379
Input('feature_finding_type', 'value'),
33273380
Input('run_feature_finding_button', 'n_clicks'),
3381+
Input('run_massql_query_button', 'n_clicks'),
3382+
33283383
Input('image_export_format', 'value'),
33293384
Input("plot_theme", "value")
33303385
],
@@ -3334,20 +3389,23 @@ def render_initial_file_load(usi, usi_select, usi2):
33343389
State('feature_finding_min_peak_rt', 'value'),
33353390
State('feature_finding_max_peak_rt', 'value'),
33363391
State('feature_finding_rt_tolerance', 'value'),
3392+
State('massql_statement', 'value'),
33373393
])
33383394
def draw_file(url_search, usi, usi_select,
33393395
map_plot_zoom, highlight_box_zoom, map_plot_quantization_level, map_plot_color_scale,
33403396
show_ms2_markers, ms2marker_color, ms2marker_size, polarity_filter,
33413397
overlay_usi, overlay_mz, overlay_rt, overlay_size, overlay_color, overlay_hover, overlay_filter_column, overlay_filter_value, overlay_tabular_data,
33423398
feature_finding_type,
3343-
feature_finding_click,
3399+
run_feature_finding_button_click,
3400+
run_massql_query_button_click,
33443401
export_format,
33453402
plot_theme,
33463403
feature_finding_ppm,
33473404
feature_finding_noise,
33483405
feature_finding_min_peak_rt,
33493406
feature_finding_max_peak_rt,
3350-
feature_finding_rt_tolerance):
3407+
feature_finding_rt_tolerance,
3408+
massql_statement):
33513409

33523410
triggered_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
33533411

@@ -3375,6 +3433,8 @@ def draw_file(url_search, usi, usi_select,
33753433
feature_finding_params["params"]["feature_finding_max_peak_rt"] = feature_finding_max_peak_rt
33763434
feature_finding_params["params"]["feature_finding_rt_tolerance"] = feature_finding_rt_tolerance
33773435

3436+
feature_finding_params["params"]["massql_statement"] = massql_statement
3437+
33783438
current_map_selection = json.loads(map_plot_zoom)
33793439
highlight_box = None
33803440
try:
@@ -3400,6 +3460,7 @@ def draw_file(url_search, usi, usi_select,
34003460
# Adding on Overlay Data
34013461
map_fig = _integrate_overlay(overlay_usi, map_fig, overlay_mz, overlay_rt, overlay_filter_column, overlay_filter_value, overlay_size, overlay_color, overlay_hover, map_selection=current_map_selection, overlay_tabular_data=overlay_tabular_data)
34023462

3463+
feature_finding_figures = []
34033464
try:
34043465
# Creating a table
34053466
table_graph = dash_table.DataTable(
@@ -3412,6 +3473,21 @@ def draw_file(url_search, usi, usi_select,
34123473
filter_action="native",
34133474
export_format="csv"
34143475
)
3476+
3477+
feature_finding_figures.append(table_graph)
3478+
except:
3479+
pass
3480+
3481+
# Creating a feature finding figure
3482+
try:
3483+
feature_finding_figures.append(html.Br())
3484+
feature_finding_figures.append(html.Br())
3485+
3486+
scatter_plot_figure = px.scatter(features_df, x="rt", y="i", title="{} - RT vs Intensity".format(feature_finding_type))
3487+
feature_finding_figures.append(dcc.Graph(figure=scatter_plot_figure))
3488+
3489+
scatter_plot_figure = px.scatter(features_df, x="rt", y="mz", size="i", title="{} - RT vs m/z".format(feature_finding_type))
3490+
feature_finding_figures.append(dcc.Graph(figure=scatter_plot_figure))
34153491
except:
34163492
pass
34173493

@@ -3428,7 +3504,7 @@ def draw_file(url_search, usi, usi_select,
34283504
# Writing output status
34293505
status = html.H6([dbc.Badge("Ready", color="success", className="ml-1")])
34303506

3431-
return [map_fig, graph_config, remote_link, table_graph, status]
3507+
return [map_fig, graph_config, remote_link, feature_finding_figures, status]
34323508

34333509

34343510
@app.callback([
@@ -3593,6 +3669,8 @@ def create_gnps_mzmine2_link(usi, usi2, feature_finding_type, feature_finding_pp
35933669
Input("feature_finding_max_peak_rt", "value"),
35943670
Input("feature_finding_rt_tolerance", "value"),
35953671
3672+
Input("massql_statement", "value"),
3673+
35963674
Input("sychronization_save_session_button", "n_clicks"),
35973675
Input("sychronization_set_type_button", "n_clicks"),
35983676
Input("sychronization_session_id", "value"),
@@ -3616,6 +3694,7 @@ def create_link(usi, usi_select, usi2, xic_mz, xic_formula, xic_peptide,
36163694
ms2_identifier, map_plot_zoom, polarity_filtering, polarity_filtering2, show_lcms_2nd_map, tic_option,
36173695
overlay_usi, overlay_mz, overlay_rt, overlay_color, overlay_size, overlay_hover, overlay_filter_column, overlay_filter_value,
36183696
feature_finding_type, feature_finding_ppm, feature_finding_noise, feature_finding_min_peak_rt, feature_finding_max_peak_rt, feature_finding_rt_tolerance,
3697+
massql_statement,
36193698
sychronization_save_session_button_clicks, sychronization_set_type_button_clicks, sychronization_session_id, synchronization_leader_token,
36203699
chromatogram_options,
36213700
comment,
@@ -3664,6 +3743,9 @@ def create_link(usi, usi_select, usi2, xic_mz, xic_formula, xic_peptide,
36643743
url_params["feature_finding_max_peak_rt"] = feature_finding_max_peak_rt
36653744
url_params["feature_finding_rt_tolerance"] = feature_finding_rt_tolerance
36663745

3746+
# MassQL
3747+
url_params["massql_statement"] = massql_statement
3748+
36673749
# Sychronization Options
36683750
url_params["sychronization_session_id"] = sychronization_session_id
36693751

@@ -4397,6 +4479,14 @@ def toggle_collapse1(show_lcms_1st_map, is_open):
43974479
def toggle_collapse_filters(show_filters):
43984480
return [show_filters, show_filters]
43994481

4482+
@app.callback(
4483+
[Output("massql-collapse", "is_open")],
4484+
[Input("feature_finding_type", "value")],
4485+
)
4486+
def toggle_collapse_massql(feature_finding_type):
4487+
if feature_finding_type == "MassQL":
4488+
return [True]
4489+
return [False]
44004490

44014491
@app.callback(
44024492
[Output("feature-finding-collapse", "is_open")],

docker-compose.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,28 @@ services:
6969
limits:
7070
memory: 32000M
7171

72+
gnpslcms-worker-featurefinding:
73+
build:
74+
context: .
75+
dockerfile: Dockerfile
76+
container_name: gnpslcms-worker-featurefinding
77+
volumes:
78+
- ./output:/app/output:rw
79+
- ./logs:/app/logs:rw
80+
- ./temp:/app/temp:rw
81+
- ./feature_finding:/app/feature_finding:ro
82+
command: /app/run_worker_featurefinding.sh
83+
restart: unless-stopped
84+
depends_on:
85+
- gnpslcms-redis
86+
networks:
87+
- default
88+
- nginx-net
89+
deploy:
90+
resources:
91+
limits:
92+
memory: 32000M
93+
7294
gnpslcms-worker-sync:
7395
build:
7496
context: .

0 commit comments

Comments
 (0)