chromaquant 0.3.1__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chromaquant/__init__.py +9 -2
- chromaquant/data/__init__.py +14 -0
- chromaquant/data/breakdown.py +430 -0
- chromaquant/data/dataset.py +195 -0
- chromaquant/data/table.py +412 -0
- chromaquant/data/value.py +215 -0
- chromaquant/formula/__init__.py +13 -0
- chromaquant/formula/base_formulas.py +168 -0
- chromaquant/formula/formula.py +507 -0
- chromaquant/import_local_packages.py +55 -0
- chromaquant/logging_and_handling.py +76 -0
- chromaquant/match/__init__.py +13 -0
- chromaquant/match/match.py +184 -0
- chromaquant/match/match_config.py +296 -0
- chromaquant/match/match_tools.py +154 -0
- chromaquant/{Handle → results}/__init__.py +2 -2
- chromaquant/results/reporting_tools.py +190 -0
- chromaquant/results/results.py +250 -0
- chromaquant/utils/__init__.py +14 -0
- chromaquant/utils/categories.py +127 -0
- chromaquant/utils/chemical_formulas.py +104 -0
- chromaquant/utils/dataframe_processing.py +222 -0
- chromaquant/utils/file_tools.py +100 -0
- chromaquant/utils/formula_tools.py +119 -0
- chromaquant-0.5.0.dist-info/METADATA +61 -0
- chromaquant-0.5.0.dist-info/RECORD +29 -0
- {chromaquant-0.3.1.dist-info → chromaquant-0.5.0.dist-info}/WHEEL +1 -1
- {chromaquant-0.3.1.dist-info → chromaquant-0.5.0.dist-info}/licenses/LICENSE.txt +1 -1
- chromaquant-0.5.0.dist-info/licenses/LICENSES_bundled.txt +251 -0
- chromaquant/Handle/handleDirectories.py +0 -89
- chromaquant/Manual/HydroUI.py +0 -418
- chromaquant/Manual/QuantUPP.py +0 -373
- chromaquant/Manual/Quantification.py +0 -1305
- chromaquant/Manual/__init__.py +0 -10
- chromaquant/Manual/duplicateMatch.py +0 -211
- chromaquant/Manual/fpm_match.py +0 -798
- chromaquant/Manual/label-type.py +0 -179
- chromaquant/Match/AutoFpmMatch.py +0 -1133
- chromaquant/Match/__init__.py +0 -12
- chromaquant/Quant/AutoQuantification.py +0 -1329
- chromaquant/Quant/__init__.py +0 -12
- chromaquant/__main__.py +0 -493
- chromaquant/properties.json +0 -4
- chromaquant-0.3.1.dist-info/METADATA +0 -189
- chromaquant-0.3.1.dist-info/RECORD +0 -22
- chromaquant-0.3.1.dist-info/entry_points.txt +0 -2
- chromaquant-0.3.1.dist-info/licenses/LICENSES_bundled.txt +0 -1035
chromaquant/Manual/HydroUI.py
DELETED
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
COPYRIGHT STATEMENT:
|
|
6
|
-
|
|
7
|
-
ChromaQuant – A quantification software for complex gas chromatographic data
|
|
8
|
-
|
|
9
|
-
Copyright (c) 2024, by Julia Hancock
|
|
10
|
-
Affiliation: Dr. Julie Elaine Rorrer
|
|
11
|
-
URL: https://www.rorrerlab.com/
|
|
12
|
-
|
|
13
|
-
License: BSD 3-Clause License
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
SCRIPT WHICH RUNS A DESKTOP APPLICATION FOR FUTURE USE IN SPECTRA VISUALIZATION
|
|
18
|
-
|
|
19
|
-
Julia Hancock
|
|
20
|
-
Started 11/21/2023
|
|
21
|
-
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
""" PACKAGES """
|
|
25
|
-
import sys
|
|
26
|
-
import pandas as pd
|
|
27
|
-
#Dash and plotly – dcc = "Dash Core Components", px = "Plotly express" with visualization tools
|
|
28
|
-
from dash import Dash, html, dash_table, dcc, callback, Output, Input
|
|
29
|
-
from plotly.subplots import make_subplots
|
|
30
|
-
import plotly.express as px
|
|
31
|
-
import plotly.graph_objects as go
|
|
32
|
-
from pubchempy import Compound, get_compounds
|
|
33
|
-
from rdkit import Chem
|
|
34
|
-
from rdkit.Chem.Draw import MolsToGridImage, MolDrawing, rdMolDraw2D
|
|
35
|
-
import base64
|
|
36
|
-
from io import BytesIO
|
|
37
|
-
import os
|
|
38
|
-
from molmass import Formula
|
|
39
|
-
|
|
40
|
-
""" PARAMETERS """
|
|
41
|
-
#Write sample name
|
|
42
|
-
sname = "MBPR048_01"
|
|
43
|
-
|
|
44
|
-
#Write whether sample is liquid ("L") or gas ("G")
|
|
45
|
-
stype = "G"
|
|
46
|
-
|
|
47
|
-
#Write whether there exists a file containing matched FID and MS peaks (True/False)
|
|
48
|
-
smatchtf = False
|
|
49
|
-
|
|
50
|
-
""" DIRECTORIES """
|
|
51
|
-
#Current script directory
|
|
52
|
-
script_directory = os.path.dirname(__file__)
|
|
53
|
-
|
|
54
|
-
""" DATA IMPORTS """
|
|
55
|
-
#Define file names using user parameters
|
|
56
|
-
if stype == "G":
|
|
57
|
-
fn_FID_SPEC = sname+"_GS2_FID_SPEC.csv"
|
|
58
|
-
fn_MS_SPEC = sname+"_GS1_MS_SPEC.csv"
|
|
59
|
-
|
|
60
|
-
if smatchtf == True:
|
|
61
|
-
fn_FPM = sname+"_GS2_FIDpMS.csv"
|
|
62
|
-
else:
|
|
63
|
-
fn_FPM = "default_FIDpMS.csv"
|
|
64
|
-
|
|
65
|
-
if stype == "L":
|
|
66
|
-
fn_FID_SPEC = sname+"_LQ1_FID_SPEC.csv"
|
|
67
|
-
fn_MS_SPEC = sname+"_LQ1_MS_SPEC.csv"
|
|
68
|
-
|
|
69
|
-
if smatchtf == True:
|
|
70
|
-
fn_FPM = sname+"_LQ1_FIDpMS.csv"
|
|
71
|
-
else:
|
|
72
|
-
fn_FPM = "default_FIDpMS.csv"
|
|
73
|
-
|
|
74
|
-
#Define directories for desired dataframes
|
|
75
|
-
DIR_LQ_FIDpMS_PeaksLB = "/Users/connards/Desktop/University/Rorrer Lab/Scripts/Quantification/data/"+sname+"/"+fn_FPM
|
|
76
|
-
DIR_LQ_FID_SPEC = "/Users/connards/Desktop/University/Rorrer Lab/Scripts/Quantification/data/"+sname+"/"+fn_FID_SPEC
|
|
77
|
-
DIR_LQ_MS_SPEC = "/Users/connards/Desktop/University/Rorrer Lab/Scripts/Quantification/data/"+sname+"/"+fn_MS_SPEC
|
|
78
|
-
#Column names to add to imported spectral data
|
|
79
|
-
col_names_SPEC = ['RT','Signal']
|
|
80
|
-
|
|
81
|
-
#Read matched peak data between FID and MS
|
|
82
|
-
LQ_FIDpMS_PeaksLB = pd.read_csv(DIR_LQ_FIDpMS_PeaksLB)
|
|
83
|
-
|
|
84
|
-
#Read spectra data for FID
|
|
85
|
-
LQ_FID_SPEC = pd.read_csv(DIR_LQ_FID_SPEC, names=col_names_SPEC, header=None)
|
|
86
|
-
#Add column labeling FID data
|
|
87
|
-
LQ_FID_SPEC['SignalType'] = 'FID'
|
|
88
|
-
|
|
89
|
-
#Read spectra data for MS
|
|
90
|
-
LQ_MS_SPEC = pd.read_csv(DIR_LQ_MS_SPEC, names=col_names_SPEC, header=None)
|
|
91
|
-
#Add column labeling MS data
|
|
92
|
-
LQ_MS_SPEC['SignalType'] = 'MS'
|
|
93
|
-
|
|
94
|
-
#Get dictionary of checklist entries to SignalType entries
|
|
95
|
-
dictSPEC = {'FID':'FID','MS':'MS'}
|
|
96
|
-
#Get list of checklist keys
|
|
97
|
-
dictSPEC_keys = list(dictSPEC.keys())
|
|
98
|
-
|
|
99
|
-
#Append MS dataframe to FID dataframe
|
|
100
|
-
LQ_FIDpMS_SPEC = pd.concat([LQ_FID_SPEC,LQ_MS_SPEC],ignore_index=True)
|
|
101
|
-
|
|
102
|
-
""" ACCESSING PUBCHEM """
|
|
103
|
-
|
|
104
|
-
#If there exists FIDpMS files, proceed
|
|
105
|
-
if smatchtf == True:
|
|
106
|
-
#Create a copy of the PeaksLB dataframe called PeaksLB_SMILES
|
|
107
|
-
PeaksLB_Smiles = LQ_FIDpMS_PeaksLB.copy()
|
|
108
|
-
#Read the existing smilePairs.csv
|
|
109
|
-
smilePairs = pd.read_csv(os.path.join(script_directory,'resources','smilePairs.csv'))
|
|
110
|
-
#Add a column to the PeaksLB dataframe with the smiles of matched compounds, ignoring 'No match'
|
|
111
|
-
PeaksLB_Smiles['isoSMILES'] = ''
|
|
112
|
-
#List of indices with compound names
|
|
113
|
-
compindex = []
|
|
114
|
-
#Set up temporary smile string for use in for loop
|
|
115
|
-
tempSmile = smilePairs.loc[smilePairs['Compound Name']==PeaksLB_Smiles.at[4,'Compound Name']]
|
|
116
|
-
|
|
117
|
-
#Loop through all rows in PeaksLB_Smiles
|
|
118
|
-
print('[MAIN] Assessing compound structures through SMILES...')
|
|
119
|
-
for i, row in PeaksLB_Smiles.iterrows():
|
|
120
|
-
|
|
121
|
-
#Only add peaks with matched compounds
|
|
122
|
-
if PeaksLB_Smiles.at[i,'Compound Name'] != 'No match' and PeaksLB_Smiles.at[i,'Compound Name'] != 'No Match':
|
|
123
|
-
|
|
124
|
-
#Try/except to catch error in accessing dataframe
|
|
125
|
-
try:
|
|
126
|
-
#If the compound name can be found in the compound-SMILES .csv file, add to dataframe
|
|
127
|
-
if any(smilePairs['Compound Name']==row['Compound Name']):
|
|
128
|
-
tempSmile = smilePairs.loc[smilePairs['Compound Name']==row['Compound Name'],'isoSMILES']
|
|
129
|
-
#Choose the first SMILES in the series
|
|
130
|
-
tempSmile = tempSmile[tempSmile.index[0]]
|
|
131
|
-
#Save SMILES to PeaksLB_Smiles dataframe
|
|
132
|
-
PeaksLB_Smiles.at[i,'isoSMILES'] = tempSmile
|
|
133
|
-
#If the compound isn't in the list, get SMILES from PubCHEM
|
|
134
|
-
else:
|
|
135
|
-
PeaksLB_Smiles.at[i,'isoSMILES'] = get_compounds(PeaksLB_Smiles.at[i,'Compound Name'],\
|
|
136
|
-
'name')[0].isomeric_smiles
|
|
137
|
-
print('[MAIN] Downloading SMILES for {0}...'.format(PeaksLB_Smiles.at[i,'Compound Name']))
|
|
138
|
-
compindex.append(i)
|
|
139
|
-
|
|
140
|
-
except:
|
|
141
|
-
print('[ERROR] An error occurred in accessing SMILES for {0}'.format(row['Compound Name']))
|
|
142
|
-
|
|
143
|
-
else:
|
|
144
|
-
pass
|
|
145
|
-
|
|
146
|
-
#If any compounds were previously unlabelled, save the compound name and SMILES pairs as a .csv
|
|
147
|
-
smilePairsOut = pd.concat([smilePairs,PeaksLB_Smiles.loc[compindex,['Compound Name','isoSMILES']]],ignore_index=True)
|
|
148
|
-
if smilePairsOut.size > smilePairs.size:
|
|
149
|
-
print("[MAIN] Saving updated compound-SMILES pairs...")
|
|
150
|
-
smilePairsOut.to_csv(os.path.join(script_directory,'resources','smilePairs.csv'),index=False)
|
|
151
|
-
else:
|
|
152
|
-
pass
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
""" LABELLING SPECTRA """
|
|
156
|
-
print("[MAIN] Labelling the FID spectrum using the peak-compound dataframe...")
|
|
157
|
-
#Find only the PeaksLB_Smiles rows which have compound matches
|
|
158
|
-
PeaksLB_Smiles = PeaksLB_Smiles[~PeaksLB_Smiles['Compound Name'].isin(['No Match','No match'])]
|
|
159
|
-
#For every entry in this new PeaksLB_Smiles dataframe, find the nearest FID Spectra RT to the labelled peak RT's
|
|
160
|
-
for i, row in PeaksLB_Smiles.iterrows():
|
|
161
|
-
#Find the closest row index in LQ_FID_SPEC
|
|
162
|
-
df_closestIN = LQ_FID_SPEC.iloc[(LQ_FID_SPEC['RT']-row['FID RT']).abs().argsort()[:1]].index[0]
|
|
163
|
-
#Add four columns to the spectral data: compound name, formula, match factor, and isosmiles
|
|
164
|
-
LQ_FID_SPEC.at[df_closestIN,'Compound Name'] = row['Compound Name']
|
|
165
|
-
LQ_FID_SPEC.at[df_closestIN,'Formula'] = row['Formula']
|
|
166
|
-
LQ_FID_SPEC.at[df_closestIN,'Match Factor'] = row['Match Factor']
|
|
167
|
-
LQ_FID_SPEC.at[df_closestIN,'isoSMILES'] = row['isoSMILES']
|
|
168
|
-
#Find the molecular weight of the given compound and assign to a new column in the spectral data
|
|
169
|
-
LQ_FID_SPEC.at[df_closestIN,'MW'] = Formula(row['Formula']).mass
|
|
170
|
-
|
|
171
|
-
#Otherwise, pass
|
|
172
|
-
else:
|
|
173
|
-
pass
|
|
174
|
-
|
|
175
|
-
""" WEB APPLICATION """
|
|
176
|
-
|
|
177
|
-
#Initialize the application with the Dash constructor
|
|
178
|
-
app = Dash(__name__)
|
|
179
|
-
|
|
180
|
-
#App layout
|
|
181
|
-
app.layout = html.Div([
|
|
182
|
-
|
|
183
|
-
#First row
|
|
184
|
-
html.Div(children=[
|
|
185
|
-
#First row first column
|
|
186
|
-
html.Div(children=[
|
|
187
|
-
#Scatter plot inside of a dcc interactive figure module
|
|
188
|
-
dcc.Graph(id='controls_and_graph')],\
|
|
189
|
-
style={'display':'inline-block','vertical-align':'top','margin-left': 5,'margin-top': '3vw','width':'70%'}),
|
|
190
|
-
|
|
191
|
-
#First row second column
|
|
192
|
-
html.Div(children=[
|
|
193
|
-
#Checklist for selecting viewed data
|
|
194
|
-
html.Div(children=[dcc.Checklist(dictSPEC_keys,[dictSPEC_keys[0]],id='controls_and_checklist')],style={'margin-top':100},className='row'),
|
|
195
|
-
#Axis limit entries
|
|
196
|
-
#x limit lower
|
|
197
|
-
html.Div(children=[dcc.Input(id='xlim_l',type='number',placeholder='Lower x-limit')],style={'margin-top':20},className='row'),
|
|
198
|
-
#x limit upper
|
|
199
|
-
html.Div(children=[dcc.Input(id='xlim_u',type='number',placeholder='Upper x-limit')],className='row'),
|
|
200
|
-
#y limit lower
|
|
201
|
-
html.Div(children=[dcc.Input(id='ylim_l',type='number',placeholder='Lower y-limit')],className='row'),
|
|
202
|
-
#y limit upper
|
|
203
|
-
html.Div(children=[dcc.Input(id='ylim_u',type='number',placeholder='Upper y-limit')],className='row'),
|
|
204
|
-
#y2 limit lower
|
|
205
|
-
html.Div(children=[dcc.Input(id='y2lim_l',type='number',placeholder='Secondary Lower y-limit')],className='row'),
|
|
206
|
-
#y2 limit upper
|
|
207
|
-
html.Div(children=[dcc.Input(id='y2lim_u',type='number',placeholder='Secondary Upper y-limit')],className='row')],
|
|
208
|
-
|
|
209
|
-
#Set display style to inline-block
|
|
210
|
-
style={'display':'inline-block','vertical-align':'middle','margin-left': 0,'margin-top': '3vw','width':'25%'})],
|
|
211
|
-
className='row'),
|
|
212
|
-
|
|
213
|
-
#Second row
|
|
214
|
-
html.Div(children=[
|
|
215
|
-
#Compound structure image
|
|
216
|
-
html.Img(id='structure-image')],className='row')
|
|
217
|
-
|
|
218
|
-
])
|
|
219
|
-
|
|
220
|
-
""" CALLBACK CONTROLS """
|
|
221
|
-
#FID and MS spectra selection and axis limits callback
|
|
222
|
-
@callback(
|
|
223
|
-
Output(component_id='controls_and_graph',component_property='figure'),
|
|
224
|
-
Input(component_id='controls_and_checklist',component_property='value'),
|
|
225
|
-
Input('xlim_l','value'),
|
|
226
|
-
Input('xlim_u','value'),
|
|
227
|
-
Input('ylim_l','value'),
|
|
228
|
-
Input('ylim_u','value'),
|
|
229
|
-
Input('y2lim_l','value'),
|
|
230
|
-
Input('y2lim_u','value')
|
|
231
|
-
)
|
|
232
|
-
#Callback graph updating function
|
|
233
|
-
def update_graph(fig_chosen,xlim_lval,xlim_uval,ylim_lval,ylim_uval,y2lim_lval,y2lim_uval):
|
|
234
|
-
#Format axis limits into a list
|
|
235
|
-
axLim = [xlim_lval,xlim_uval,ylim_lval,ylim_uval,y2lim_lval,y2lim_uval]
|
|
236
|
-
#Dictionary of colors for specific use for MS and FID spectra
|
|
237
|
-
colorDict = {'FID':px.colors.qualitative.Safe[4],'MS':px.colors.qualitative.Safe[1]}
|
|
238
|
-
#List of applicable dataframe titles based on fig_chosen as keys in dictSPEC
|
|
239
|
-
fig_chosen_dictSPEC = [dictSPEC[i] for i in fig_chosen]
|
|
240
|
-
#Filter DataFrame based on fig_chosen
|
|
241
|
-
#filDF = LQ_FIDpMS_SPEC[LQ_FIDpMS_SPEC['SignalType'].isin(fig_chosen_dictSPEC)]
|
|
242
|
-
|
|
243
|
-
#Initialize figure
|
|
244
|
-
fig = make_subplots(specs=[[{'secondary_y': True}]])
|
|
245
|
-
#If there are any spectra chosen, plot them
|
|
246
|
-
if len(fig_chosen) != 0:
|
|
247
|
-
#Add a trace to the figure for each entry in fig_chosen
|
|
248
|
-
for i in range(len(fig_chosen_dictSPEC)):
|
|
249
|
-
#If the entry is past the first, set secondary_y axis value to True, otherwise set to False
|
|
250
|
-
if i > 0:
|
|
251
|
-
yTF = True
|
|
252
|
-
else:
|
|
253
|
-
yTF = False
|
|
254
|
-
#Filter DataFrame based on ith entry in fig_chosen_dictSPEC
|
|
255
|
-
filDF = LQ_FIDpMS_SPEC[LQ_FIDpMS_SPEC['SignalType'].str.match(fig_chosen_dictSPEC[i])]
|
|
256
|
-
|
|
257
|
-
#Add a trace
|
|
258
|
-
fig.add_trace(go.Scattergl(x=filDF['RT'],y=filDF['Signal'],\
|
|
259
|
-
name=fig_chosen_dictSPEC[i],marker=dict(color=colorDict[fig_chosen[i]]),mode='lines+markers'),\
|
|
260
|
-
secondary_y=yTF)
|
|
261
|
-
|
|
262
|
-
#Update figure layout by adding titles
|
|
263
|
-
fig.update_layout(title={'text':sname+' Spectra','font':{'color':'rgb(76, 46, 132)','size':20,'family':'Arial'}},\
|
|
264
|
-
legend_title='Displayed Spectra')
|
|
265
|
-
fig.update_xaxes(title_text='Retention time (min)')
|
|
266
|
-
fig.update_yaxes(title_text=fig_chosen_dictSPEC[0]+' Signal (a.u.)',secondary_y=False)
|
|
267
|
-
#Add a secondary y-axis title if necessary
|
|
268
|
-
if len(fig_chosen_dictSPEC) > 1:
|
|
269
|
-
fig.update_yaxes(title_text=fig_chosen_dictSPEC[1]+' Signal (a.u.)',secondary_y=True)
|
|
270
|
-
#Check if user-inputted axis limits are viable
|
|
271
|
-
#If lower ylim is less than upper ylim, update y-axis
|
|
272
|
-
#If any NoneType exist in the axis limits list, do not update limits
|
|
273
|
-
if None not in axLim[4:] and axLim[4] < axLim[5]:
|
|
274
|
-
fig.update_yaxes(range=[axLim[4],axLim[5]],secondary_y=True)
|
|
275
|
-
else:
|
|
276
|
-
pass
|
|
277
|
-
else:
|
|
278
|
-
pass
|
|
279
|
-
|
|
280
|
-
#Check if user-inputted axis limits are viable
|
|
281
|
-
#If lower xlim is less than upper xlim, update x-axis
|
|
282
|
-
#If any NoneType exist in the axis limits list, do not update limits
|
|
283
|
-
if None not in axLim[:1] and axLim[0] < axLim[1]:
|
|
284
|
-
fig.update_xaxes(range=[axLim[0],axLim[1]])
|
|
285
|
-
else:
|
|
286
|
-
pass
|
|
287
|
-
#If lower ylim is less than upper ylim, update y-axis
|
|
288
|
-
#If any NoneType exist in the axis limits list, do not update limits
|
|
289
|
-
if None not in axLim[2:4] and axLim[2] < axLim[3]:
|
|
290
|
-
fig.update_yaxes(range=[axLim[2],axLim[3]],secondary_y=False)
|
|
291
|
-
else:
|
|
292
|
-
pass
|
|
293
|
-
|
|
294
|
-
#If no spectra are chosen, don't plot anything
|
|
295
|
-
else:
|
|
296
|
-
pass
|
|
297
|
-
|
|
298
|
-
return fig
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
#Compound structure drawing function
|
|
302
|
-
@callback(
|
|
303
|
-
Output('structure-image','src'),
|
|
304
|
-
Input('controls_and_graph','selectedData')
|
|
305
|
-
)
|
|
306
|
-
def draw_structure(selectedData):
|
|
307
|
-
max_structs = 6
|
|
308
|
-
empty_plot = "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA="
|
|
309
|
-
|
|
310
|
-
if selectedData:
|
|
311
|
-
#Take first point in selectedData, creating nested list
|
|
312
|
-
checkPoint = [selectedData['points'][0]['curveNumber'],\
|
|
313
|
-
selectedData['points'][0]['x'],\
|
|
314
|
-
selectedData['points'][0]['y']]
|
|
315
|
-
|
|
316
|
-
#Dictionary assigning each spectra to a curve number
|
|
317
|
-
specKeys = {'FID':'','MS':''}
|
|
318
|
-
|
|
319
|
-
#Assign spectra to curve numbers according to whether or not the first point matches any points in the FID signal
|
|
320
|
-
try:
|
|
321
|
-
if checkPoint[2] == LQ_FID_SPEC.at[LQ_FID_SPEC[LQ_FID_SPEC['RT']==checkPoint[1]].index[0],'Signal']:
|
|
322
|
-
specKeys['FID'] = int(checkPoint[0])
|
|
323
|
-
specKeys['MS'] = int(not checkPoint[0])
|
|
324
|
-
else:
|
|
325
|
-
pass
|
|
326
|
-
except:
|
|
327
|
-
specKeys['FID'] = int(not checkPoint[0])
|
|
328
|
-
specKeys['MS'] = int(checkPoint[0])
|
|
329
|
-
|
|
330
|
-
#Create list of selected points filtered so only FID results show
|
|
331
|
-
selectedFIDData = []
|
|
332
|
-
for i in selectedData['points']:
|
|
333
|
-
if i['curveNumber'] == specKeys['FID']:
|
|
334
|
-
selectedFIDData.append({'x':i['x'],'y':i['y'],'pointIndex':i['pointIndex']})
|
|
335
|
-
|
|
336
|
-
if len(selectedFIDData) == 0:
|
|
337
|
-
return empty_plot
|
|
338
|
-
#List of selected point indices on FID spectrum
|
|
339
|
-
match_idx = [x['pointIndex'] for x in selectedFIDData]
|
|
340
|
-
#Dataframe with smiles and related data for selected points
|
|
341
|
-
smilesDF = LQ_FID_SPEC.loc[match_idx,['RT','Compound Name','Formula','Match Factor','isoSMILES']]
|
|
342
|
-
#Set FID spectra index to its own column and reset the indices
|
|
343
|
-
smilesDF.reset_index(inplace=True)
|
|
344
|
-
smilesDF = smilesDF.rename(columns={'index':'Spectra Index'})
|
|
345
|
-
#Filter dataframe to only include non-NaN smiles entries
|
|
346
|
-
smilesDF_F = smilesDF[smilesDF['isoSMILES'].notnull()].reset_index(drop=True)
|
|
347
|
-
#Get lists of smiles rdkit objects and corresponding compound names
|
|
348
|
-
list_smiles = [Chem.MolFromSmiles(x) for x in smilesDF_F['isoSMILES'].tolist()][:max_structs]
|
|
349
|
-
#Create a list of legend entries using data from smilesDF_F
|
|
350
|
-
list_legends = [smilesDF_F.loc[smilesDF_F.index[i],'Compound Name']+'\n'+\
|
|
351
|
-
smilesDF_F.loc[smilesDF_F.index[i],'Formula']+' - '+\
|
|
352
|
-
'{:.4}% Match'.format(smilesDF_F.loc[smilesDF_F.index[i],'Match Factor'])+'\n'+\
|
|
353
|
-
'{:.3} min'.format(smilesDF_F.loc[smilesDF_F.index[i],'RT']) for i in range(len(smilesDF_F))][:max_structs]
|
|
354
|
-
#Initialize MolDraw2DCairo drawer
|
|
355
|
-
drawer = rdMolDraw2D.MolDraw2DCairo(1200,180,200,180)
|
|
356
|
-
#Set drawing options
|
|
357
|
-
drawer.drawOptions().useBWAtomPalette()
|
|
358
|
-
drawer.drawOptions().legendFontSize = 16
|
|
359
|
-
drawer.drawOptions().legendFraction = 0.3
|
|
360
|
-
drawer.drawOptions().maxFontSize = 16
|
|
361
|
-
drawer.drawOptions().padding = 0.05
|
|
362
|
-
drawer.drawOptions().centreMoleculesBeforeDrawing = True
|
|
363
|
-
#Draw the molecules
|
|
364
|
-
drawer.DrawMolecules(list_smiles,legends=list_legends)
|
|
365
|
-
drawer.FinishDrawing()
|
|
366
|
-
#Set buffered image using BytesIO encoding
|
|
367
|
-
buffered = BytesIO(drawer.GetDrawingText())
|
|
368
|
-
|
|
369
|
-
#OLD METHOD FOR DRAWING GRID OF MOLECULE IMAGES
|
|
370
|
-
#Create a grid of molecule images using rdkit
|
|
371
|
-
#img = MolsToGridImage(list_smiles[0:max_structs], molsPerRow=structs_per_row, legends=list_legends, subImgSize=(300,300))
|
|
372
|
-
#img = SVG(drawer.GetDrawingText())
|
|
373
|
-
#Encode and save the image
|
|
374
|
-
#buffered = BytesIO()
|
|
375
|
-
#img.save(buffered, format="JPEG")
|
|
376
|
-
|
|
377
|
-
#Encode the image
|
|
378
|
-
encoded_image = base64.b64encode(buffered.getvalue())
|
|
379
|
-
#Define and return the image string
|
|
380
|
-
src_str = 'data:image/png;base64,{}'.format(encoded_image.decode())
|
|
381
|
-
return src_str
|
|
382
|
-
else:
|
|
383
|
-
#Return a blank string
|
|
384
|
-
return ''
|
|
385
|
-
|
|
386
|
-
""" EXECUTE APPLICATION """
|
|
387
|
-
|
|
388
|
-
#Run the application
|
|
389
|
-
if __name__ == '__main__':
|
|
390
|
-
app.run(debug=True)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
"""
|
|
394
|
-
#Callback controls
|
|
395
|
-
@callback(
|
|
396
|
-
Output(component_id='controls_and_graph',component_property='figure'),
|
|
397
|
-
Input(component_id='controls_and_checklist',component_property='value')
|
|
398
|
-
)
|
|
399
|
-
|
|
400
|
-
def update_graph(fig_chosen):
|
|
401
|
-
#List of applicable dataframe titles based on fig_chosen as keys in dictSPEC
|
|
402
|
-
fig_chosen_dictSPEC = [dictSPEC[i] for i in fig_chosen]
|
|
403
|
-
#Filter DataFrame based on fig_chosen
|
|
404
|
-
filDF = LQ_FIDpMS_SPEC[LQ_FIDpMS_SPEC['SignalType'].isin(fig_chosen_dictSPEC)]
|
|
405
|
-
fig = px.scatter(filDF,x='RT',y='Signal',color='SignalType',\
|
|
406
|
-
color_discrete_sequence=[px.colors.qualitative.Safe[4],\
|
|
407
|
-
px.colors.qualitative.Safe[1]])
|
|
408
|
-
#Update figure layout
|
|
409
|
-
fig.update_layout(title='MBPR031 Spectra',xaxis_title='Retention time (min)',yaxis_title='Signal (a.u.)',legend_title='Displayed Spectra')
|
|
410
|
-
return fig
|
|
411
|
-
"""
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|