Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -160,14 +160,14 @@ visibility: hidden
|
|
160 |
|
161 |
|
162 |
class View3DmolCell(py3Dmol.view):
|
163 |
-
def __init__(self, width=
|
164 |
divid = "3dmolviewer_UNIQUEID"
|
165 |
self.uniqueid = None
|
166 |
if isinstance(width, int):
|
167 |
width = '%dpx' % width
|
168 |
-
if isinstance(
|
169 |
height = '%dpx' % height
|
170 |
-
self.startjs = '''<div id="%s"
|
171 |
</div>\n''' % (divid, width, height)
|
172 |
self.startjs += '<script>\n'
|
173 |
self.endjs = '</script>'
|
@@ -1012,8 +1012,7 @@ def submit_predict(predict_filepath, task, preset, target_family, opts, job_info
|
|
1012 |
# Advanced options for Target Protein Identification
|
1013 |
if "Calculate Max. Tanimoto Similarity between the Input Compound and Compounds in the Training Set" in opts:
|
1014 |
x1 = rdkit_canonicalize(prediction_df['X1'].iloc[0])
|
1015 |
-
|
1016 |
-
prediction_df['FP'] = prediction_df['X1'].parallel_apply(smiles_to_ecfp)
|
1017 |
|
1018 |
prediction_df[[
|
1019 |
'Max. Tanimoto Similarity to Training Compounds',
|
@@ -1037,12 +1036,11 @@ def submit_predict(predict_filepath, task, preset, target_family, opts, job_info
|
|
1037 |
|
1038 |
if "Calculate Max. Tanimoto Similarity between the Input Compound and Known Ligands of the Identified Target" in opts:
|
1039 |
x1 = rdkit_canonicalize(prediction_df['X1'].iloc[0])
|
1040 |
-
if 'FP' not in prediction_df.columns:
|
1041 |
-
prediction_df['FP'] = prediction_df['X1'].parallel_apply(smiles_to_ecfp)
|
1042 |
|
1043 |
@cache
|
1044 |
def max_sim(fasta):
|
1045 |
pos_targets_df = df_training.loc[(df_training['X2'] == fasta) & (df_training['Y'] == 1)].copy()
|
|
|
1046 |
return max_tanimoto_similarity(x1, seen_smiles_with_fp=pos_targets_df)
|
1047 |
|
1048 |
prediction_df[[
|
@@ -1051,10 +1049,8 @@ def submit_predict(predict_filepath, task, preset, target_family, opts, job_info
|
|
1051 |
]] = prediction_df['X2'].parallel_apply(max_sim).apply(pd.Series)
|
1052 |
|
1053 |
max_sim.cache_clear()
|
1054 |
-
|
1055 |
-
prediction_df.drop(
|
1056 |
-
[col for col in prediction_df.columns if col in ['N', 'FP']], axis=1
|
1057 |
-
).to_csv(predictions_file, index=False, na_rep='')
|
1058 |
status = "COMPLETED"
|
1059 |
|
1060 |
return {run_state: False}
|
@@ -1179,8 +1175,8 @@ def create_html_report(df, file=None, task=None, opts=(), progress=gr.Progress(t
|
|
1179 |
if any(col in df_html.columns for col in ['Y^', 'Y']):
|
1180 |
job = 'Target Protein Identification'
|
1181 |
category = 'Target Family'
|
1182 |
-
columns_unique = df_html.columns.isin(
|
1183 |
-
['ID1', '
|
1184 |
'Max. Tanimoto Similarity to Training Compounds', 'Max. Sim. Training Compound']
|
1185 |
+ list(FILTER_MAP.keys()) + list(SCORE_MAP.keys())
|
1186 |
)
|
@@ -1264,8 +1260,10 @@ def create_html_report(df, file=None, task=None, opts=(), progress=gr.Progress(t
|
|
1264 |
uniprot_id_formatter = HTMLTemplateFormatter(
|
1265 |
template='<% if (value == value) { ' # Check if value is not NaN
|
1266 |
'if (/^[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}$/.test(value)) '
|
1267 |
-
|
1268 |
-
'
|
|
|
|
|
1269 |
'<% } else { %><% } %>' # Output empty string if value is NaN
|
1270 |
)
|
1271 |
pubchem_id_formatter = HTMLTemplateFormatter(
|
@@ -1284,8 +1282,10 @@ def create_html_report(df, file=None, task=None, opts=(), progress=gr.Progress(t
|
|
1284 |
'Target FASTA': {'type': 'textarea', 'width': 60},
|
1285 |
'Target ID': uniprot_id_formatter,
|
1286 |
'Compound ID': pubchem_id_formatter,
|
1287 |
-
'Max.
|
1288 |
-
'Max.
|
|
|
|
|
1289 |
}
|
1290 |
formatters = {**bool_formatters, **float_formatters, **other_formatters}
|
1291 |
|
@@ -1325,14 +1325,56 @@ def create_html_report(df, file=None, task=None, opts=(), progress=gr.Progress(t
|
|
1325 |
# Remove keys with empty values
|
1326 |
pie_charts = {k: v for k, v in pie_charts.items() if any(v)}
|
1327 |
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1335 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1336 |
)
|
1337 |
|
1338 |
template = pn.template.VanillaTemplate(
|
@@ -1370,7 +1412,7 @@ def create_html_report(df, file=None, task=None, opts=(), progress=gr.Progress(t
|
|
1370 |
margin=10)
|
1371 |
)
|
1372 |
|
1373 |
-
template.save(file,
|
1374 |
return file
|
1375 |
|
1376 |
|
|
|
160 |
|
161 |
|
162 |
class View3DmolCell(py3Dmol.view):
|
163 |
+
def __init__(self, width=400, height=400):
|
164 |
divid = "3dmolviewer_UNIQUEID"
|
165 |
self.uniqueid = None
|
166 |
if isinstance(width, int):
|
167 |
width = '%dpx' % width
|
168 |
+
if isinstance(height, int):
|
169 |
height = '%dpx' % height
|
170 |
+
self.startjs = '''<div id="%s" style="position: relative; width: %s; height: %s;">
|
171 |
</div>\n''' % (divid, width, height)
|
172 |
self.startjs += '<script>\n'
|
173 |
self.endjs = '</script>'
|
|
|
1012 |
# Advanced options for Target Protein Identification
|
1013 |
if "Calculate Max. Tanimoto Similarity between the Input Compound and Compounds in the Training Set" in opts:
|
1014 |
x1 = rdkit_canonicalize(prediction_df['X1'].iloc[0])
|
1015 |
+
prediction_df['FP'] = prediction_df['X1'].parallel_apply(smiles_to_ecfp)
|
|
|
1016 |
|
1017 |
prediction_df[[
|
1018 |
'Max. Tanimoto Similarity to Training Compounds',
|
|
|
1036 |
|
1037 |
if "Calculate Max. Tanimoto Similarity between the Input Compound and Known Ligands of the Identified Target" in opts:
|
1038 |
x1 = rdkit_canonicalize(prediction_df['X1'].iloc[0])
|
|
|
|
|
1039 |
|
1040 |
@cache
|
1041 |
def max_sim(fasta):
|
1042 |
pos_targets_df = df_training.loc[(df_training['X2'] == fasta) & (df_training['Y'] == 1)].copy()
|
1043 |
+
pos_targets_df['FP'] = pos_targets_df['X1'].apply(smiles_to_ecfp)
|
1044 |
return max_tanimoto_similarity(x1, seen_smiles_with_fp=pos_targets_df)
|
1045 |
|
1046 |
prediction_df[[
|
|
|
1049 |
]] = prediction_df['X2'].parallel_apply(max_sim).apply(pd.Series)
|
1050 |
|
1051 |
max_sim.cache_clear()
|
1052 |
+
|
1053 |
+
prediction_df.drop(['N'], axis=1).to_csv(predictions_file, index=False, na_rep='')
|
|
|
|
|
1054 |
status = "COMPLETED"
|
1055 |
|
1056 |
return {run_state: False}
|
|
|
1175 |
if any(col in df_html.columns for col in ['Y^', 'Y']):
|
1176 |
job = 'Target Protein Identification'
|
1177 |
category = 'Target Family'
|
1178 |
+
columns_unique = df_html.columns.isin( # 'Pharmacophore' excluded until an image solution is available
|
1179 |
+
['ID1', 'Compound', 'Scaffold', 'X1', 'Scaffold SMILES',
|
1180 |
'Max. Tanimoto Similarity to Training Compounds', 'Max. Sim. Training Compound']
|
1181 |
+ list(FILTER_MAP.keys()) + list(SCORE_MAP.keys())
|
1182 |
)
|
|
|
1260 |
uniprot_id_formatter = HTMLTemplateFormatter(
|
1261 |
template='<% if (value == value) { ' # Check if value is not NaN
|
1262 |
'if (/^[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}$/.test(value)) '
|
1263 |
+
# Check if value is a valid UniProt ID
|
1264 |
+
'{ %><a href="https://www.uniprot.org/uniprotkb/<%= value %>" target="_blank"><%= value %></a><% '
|
1265 |
+
# Else treat it as a sequence or other plain-text string, line-warping every 60 characters
|
1266 |
+
'} else { %><div style="white-space: pre-wrap;"><%= value.match(/.{1,60}/g).join("<br>") %></div><% } %>'
|
1267 |
'<% } else { %><% } %>' # Output empty string if value is NaN
|
1268 |
)
|
1269 |
pubchem_id_formatter = HTMLTemplateFormatter(
|
|
|
1282 |
'Target FASTA': {'type': 'textarea', 'width': 60},
|
1283 |
'Target ID': uniprot_id_formatter,
|
1284 |
'Compound ID': pubchem_id_formatter,
|
1285 |
+
'Max. Sim. Ligand': pubchem_id_formatter,
|
1286 |
+
'Max. Id. Target': uniprot_id_formatter,
|
1287 |
+
'Max. Sim. Training Compound': pubchem_id_formatter,
|
1288 |
+
'Max. Id. Training Target': uniprot_id_formatter,
|
1289 |
}
|
1290 |
formatters = {**bool_formatters, **float_formatters, **other_formatters}
|
1291 |
|
|
|
1325 |
# Remove keys with empty values
|
1326 |
pie_charts = {k: v for k, v in pie_charts.items() if any(v)}
|
1327 |
|
1328 |
+
panel_css = """
|
1329 |
+
.tabulator {
|
1330 |
+
font-family: Courier New !important;
|
1331 |
+
font-weight: normal !important;
|
1332 |
+
font-size: 12px !important;
|
1333 |
+
}
|
1334 |
+
|
1335 |
+
.tabulator-cell {
|
1336 |
+
overflow: visible !important;
|
1337 |
+
}
|
1338 |
+
|
1339 |
+
|
1340 |
+
.image-zoom-viewer {
|
1341 |
+
display: inline-block;
|
1342 |
+
overflow: visible;
|
1343 |
+
z-index: 1000;
|
1344 |
+
}
|
1345 |
+
|
1346 |
+
.image-zoom-viewer::after {
|
1347 |
+
content: "";
|
1348 |
+
top: 0;
|
1349 |
+
left: 0;
|
1350 |
+
width: 100%;
|
1351 |
+
height: 100%;
|
1352 |
+
pointer-events: none;
|
1353 |
+
}
|
1354 |
+
|
1355 |
+
.image-zoom-viewer:hover::after {
|
1356 |
+
pointer-events: all;
|
1357 |
}
|
1358 |
+
|
1359 |
+
/* When hovering over the container, scale its child (the SVG) */
|
1360 |
+
.tabulator-cell:hover .image-zoom-viewer svg {
|
1361 |
+
padding: 3px;
|
1362 |
+
position: absolute;
|
1363 |
+
background-color: rgba(250, 250, 250, 0.854);
|
1364 |
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.618);
|
1365 |
+
border-radius: 3px;
|
1366 |
+
transform: scale(3); /* Scale up the SVG */
|
1367 |
+
transition: transform 0.3s ease;
|
1368 |
+
pointer-events: none; /* Prevents the SVG from blocking mouse interactions */
|
1369 |
+
z-index: 1000;
|
1370 |
+
}
|
1371 |
+
"""
|
1372 |
+
|
1373 |
+
pn.extension(
|
1374 |
+
raw_css=[panel_css],
|
1375 |
+
js_files={'panel_custom': 'static/panel.js', '3Dmol': 'static/3Dmol-min.js'},
|
1376 |
+
# js_modules={'3Dmol': 'static/3Dmol-min.js'},
|
1377 |
+
inline=True
|
1378 |
)
|
1379 |
|
1380 |
template = pn.template.VanillaTemplate(
|
|
|
1412 |
margin=10)
|
1413 |
)
|
1414 |
|
1415 |
+
template.save(file, title=f'DeepSEQreen {job} Report', resources=INLINE)
|
1416 |
return file
|
1417 |
|
1418 |
|