libokj commited on
Commit
9d27767
·
1 Parent(s): a90339d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -25
app.py CHANGED
@@ -160,14 +160,14 @@ visibility: hidden
160
 
161
 
162
  class View3DmolCell(py3Dmol.view):
163
- def __init__(self, width=640, height=480):
164
  divid = "3dmolviewer_UNIQUEID"
165
  self.uniqueid = None
166
  if isinstance(width, int):
167
  width = '%dpx' % width
168
- if isinstance(width, 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,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
- if 'FP' not in prediction_df.columns:
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', 'Pharmacophore', 'Compound', 'Scaffold', 'X1', 'Scaffold SMILES',
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
- '{ %><a href="https://www.uniprot.org/uniprotkb/<%= value %>" target="_blank"><%= value %></a><%'
1268
- '} else { %><textarea style="width: 60ch;"><%= value %></textarea><% } %>'
 
 
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. Tanimoto Similarity Target Ligand': pubchem_id_formatter,
1288
- 'Max. Sequence Identity Ligand Target': uniprot_id_formatter,
 
 
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
- pn.extension(
1329
- css_files=[
1330
- './static/panel.css',
1331
- ],
1332
- js_files={
1333
- '3Dmol': './static/3Dmol-min.js',
1334
- 'panel_custom': './static/panel.js'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, resources=INLINE, title=f'DeepSEQreen {job} Report')
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