Gla-AI4BioMed-Lab commited on
Commit
e4d0f40
Β·
verified Β·
1 Parent(s): b7ce511

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +11 -20
app.py CHANGED
@@ -137,12 +137,10 @@ def visualize_attention(model, feats, drug_idx: Optional[int] = None) -> str:
137
  """
138
  Render a Protein β†’ Drug cross-attention heat-map and, optionally, a
139
  Top-30 protein-residue table for a chosen drug-token index.
140
-
141
  The token index shown on the x-axis (and accepted via *drug_idx*) is **the
142
  position of that token in the *original* drug sequence**, *after* the
143
  tokeniser but *before* any pruning or truncation (1-based in the labels,
144
  0-based for the function argument).
145
-
146
  Returns
147
  -------
148
  html : str
@@ -178,6 +176,7 @@ def visualize_attention(model, feats, drug_idx: Optional[int] = None) -> str:
178
  d_indices_full = d_indices_full[: attn.size(1)]
179
  attn = attn[: len(p_tokens_full), : len(d_tokens_full)]
180
 
 
181
  # ── adaptive sparsity pruning ───────────────────────────────────────────
182
  thr = attn.max().item() * 0.05
183
  row_keep = (attn.max(dim=1).values > thr)
@@ -237,7 +236,7 @@ def visualize_attention(model, feats, drug_idx: Optional[int] = None) -> str:
237
 
238
  # ───────────────────── Top-30 tabel ─────────────────────
239
  table_html = ""
240
- if drug_idx is not None:
241
  # map original 0-based drug_idx β†’ current column position
242
  if (drug_idx + 1) in d_indices:
243
  col_pos = d_indices.index(drug_idx + 1)
@@ -254,8 +253,8 @@ def visualize_attention(model, feats, drug_idx: Optional[int] = None) -> str:
254
  res_row = "".join(f"<td>{p_tokens[i]}</td>" for i in topk)
255
  pos_row = "".join(f"<td>{p_indices[i]}</td>"for i in topk)
256
 
257
- drug_tok_text = d_tokens[col_pos]
258
- orig_idx = d_indices[col_pos]
259
 
260
  # 1) build the header row: leading β€œRank”, then 1…30
261
  header_cells = (
@@ -274,7 +273,7 @@ def visualize_attention(model, feats, drug_idx: Optional[int] = None) -> str:
274
  "background:#f7f7f7; text-align:center;'>Residue</th>"
275
  + "".join(
276
  f"<td style='border:1px solid #ccc; padding:6px; "
277
- f"text-align:center'>{p_tokens[i]}</td>"
278
  for i in topk
279
  )
280
  )
@@ -285,7 +284,7 @@ def visualize_attention(model, feats, drug_idx: Optional[int] = None) -> str:
285
  "background:#f7f7f7; text-align:center;'>Position</th>"
286
  + "".join(
287
  f"<td style='border:1px solid #ccc; padding:6px; "
288
- f"text-align:center'>{p_indices[i]}</td>"
289
  for i in topk
290
  )
291
  )
@@ -397,29 +396,24 @@ button, .gr-button { font-family: Inter,sans-serif; font-weight: 600; }
397
  .link-btn.project{background:linear-gradient(to right,#10b981,#059669);}
398
  .link-btn.arxiv {background:linear-gradient(to right,#ef4444,#dc2626);}
399
  .link-btn.github {background:linear-gradient(to right,#3b82f6,#2563eb);}
400
-
401
  /* make *all* gradio buttons a bit taller */
402
  .gr-button { min-height: 10px !important; }
403
-
404
  /* now target just our two big action buttons */
405
  #extract-btn, #inference-btn {
406
  width: 5px !important;
407
  min-height: 36px !important;
408
  margin-top: 12px !important;
409
  }
410
-
411
  /* and make clear button full width but shorter */
412
  #clear-btn {
413
  width: 10px !important;
414
  min-height: 36px !important;
415
  margin-top: 12px !important;
416
  }
417
-
418
  #input-card label {
419
  font-weight: 600 !important; /* make the text bold */
420
  color: var(--text) !important; /* use your standard text color */
421
  }
422
-
423
  .card {
424
  background: var(--card);
425
  border: 1px solid var(--border);
@@ -429,7 +423,6 @@ button, .gr-button { font-family: Inter,sans-serif; font-weight: 600; }
429
  margin: 0 auto 32px;
430
  box-shadow: 0 2px 6px rgba(0,0,0,0.05);
431
  }
432
-
433
  #guidelines-card h2 {
434
  font-size: 1.4rem;
435
  margin-bottom: 16px;
@@ -453,7 +446,9 @@ button, .gr-button { font-family: Inter,sans-serif; font-weight: 600; }
453
 
454
  with gr.Blocks(css=css) as demo:
455
  # ───────────── Title ─────────────
456
- gr.Markdown("<h1>Token-level Visualiser for Drug-Target Interaction</h1>")
 
 
457
 
458
  # ───────────── Project Links ─────────────
459
  gr.Markdown("""
@@ -477,22 +472,18 @@ with gr.Blocks(css=css) as demo:
477
  based on 3D structures from
478
  <a href="https://alphafold.ebi.ac.uk" target="_blank">AlphaFold&nbsp;DB</a> or the
479
  <a href="https://www.rcsb.org" target="_blank">Protein Data Bank (PDB)</a>.</li>
480
-
481
  <li><strong>If you only have an amino acid sequence or a UniProt ID,</strong>
482
  you must first visit the
483
  <a href="https://www.rcsb.org" target="_blank">Protein Data Bank (PDB)</a>
484
  or <a href="https://alphafold.ebi.ac.uk" target="_blank">AlphaFold&nbsp;DB</a>
485
  to search and download the corresponding <code>.cif</code> or <code>.pdb</code> file.</li>
486
-
487
  <li><strong>Drug input supports both SELFIES and SMILES:</strong><br>
488
  You can enter a SELFIES string directly, or paste a SMILES string.
489
  SMILES will be automatically converted to SELFIES using
490
  <a href="https://github.com/aspuru-guzik-group/selfies" target="_blank">SELFIES encoder</a>.
491
  If conversion fails, a red error message will be displayed.</li>
492
-
493
  <li>Optionally enter a <strong>1-based</strong> drug atom or substructure index
494
- to highlight the Top-10 interacting protein residues.</li>
495
-
496
  <li>After inference, you can use the
497
  β€œDownload PDF” link to export a high-resolution vector version.</li>
498
  </ul>
@@ -565,4 +556,4 @@ with gr.Blocks(css=css) as demo:
565
  )
566
 
567
  if __name__ == "__main__":
568
- demo.launch(server_name="0.0.0.0", server_port=7860, share=True)
 
137
  """
138
  Render a Protein β†’ Drug cross-attention heat-map and, optionally, a
139
  Top-30 protein-residue table for a chosen drug-token index.
 
140
  The token index shown on the x-axis (and accepted via *drug_idx*) is **the
141
  position of that token in the *original* drug sequence**, *after* the
142
  tokeniser but *before* any pruning or truncation (1-based in the labels,
143
  0-based for the function argument).
 
144
  Returns
145
  -------
146
  html : str
 
176
  d_indices_full = d_indices_full[: attn.size(1)]
177
  attn = attn[: len(p_tokens_full), : len(d_tokens_full)]
178
 
179
+ orig_attn = attn.clone()
180
  # ── adaptive sparsity pruning ───────────────────────────────────────────
181
  thr = attn.max().item() * 0.05
182
  row_keep = (attn.max(dim=1).values > thr)
 
236
 
237
  # ───────────────────── Top-30 tabel ─────────────────────
238
  table_html = ""
239
+ if drug_idx is not None and 0 <= drug_idx < orig_attn.size(1):
240
  # map original 0-based drug_idx β†’ current column position
241
  if (drug_idx + 1) in d_indices:
242
  col_pos = d_indices.index(drug_idx + 1)
 
253
  res_row = "".join(f"<td>{p_tokens[i]}</td>" for i in topk)
254
  pos_row = "".join(f"<td>{p_indices[i]}</td>"for i in topk)
255
 
256
+ drug_tok_text = d_tokens_full[col_pos]
257
+ orig_idx = d_indices_full[col_pos]
258
 
259
  # 1) build the header row: leading β€œRank”, then 1…30
260
  header_cells = (
 
273
  "background:#f7f7f7; text-align:center;'>Residue</th>"
274
  + "".join(
275
  f"<td style='border:1px solid #ccc; padding:6px; "
276
+ f"text-align:center'>{p_tokens_full[i]}</td>"
277
  for i in topk
278
  )
279
  )
 
284
  "background:#f7f7f7; text-align:center;'>Position</th>"
285
  + "".join(
286
  f"<td style='border:1px solid #ccc; padding:6px; "
287
+ f"text-align:center'>{p_indices_full[i]}</td>"
288
  for i in topk
289
  )
290
  )
 
396
  .link-btn.project{background:linear-gradient(to right,#10b981,#059669);}
397
  .link-btn.arxiv {background:linear-gradient(to right,#ef4444,#dc2626);}
398
  .link-btn.github {background:linear-gradient(to right,#3b82f6,#2563eb);}
 
399
  /* make *all* gradio buttons a bit taller */
400
  .gr-button { min-height: 10px !important; }
 
401
  /* now target just our two big action buttons */
402
  #extract-btn, #inference-btn {
403
  width: 5px !important;
404
  min-height: 36px !important;
405
  margin-top: 12px !important;
406
  }
 
407
  /* and make clear button full width but shorter */
408
  #clear-btn {
409
  width: 10px !important;
410
  min-height: 36px !important;
411
  margin-top: 12px !important;
412
  }
 
413
  #input-card label {
414
  font-weight: 600 !important; /* make the text bold */
415
  color: var(--text) !important; /* use your standard text color */
416
  }
 
417
  .card {
418
  background: var(--card);
419
  border: 1px solid var(--border);
 
423
  margin: 0 auto 32px;
424
  box-shadow: 0 2px 6px rgba(0,0,0,0.05);
425
  }
 
426
  #guidelines-card h2 {
427
  font-size: 1.4rem;
428
  margin-bottom: 16px;
 
446
 
447
  with gr.Blocks(css=css) as demo:
448
  # ───────────── Title ─────────────
449
+ gr.Markdown(
450
+ "<h1 style='text-align: center;'>Token-level Visualiser for Drug-Target Interaction</h1>"
451
+ )
452
 
453
  # ───────────── Project Links ─────────────
454
  gr.Markdown("""
 
472
  based on 3D structures from
473
  <a href="https://alphafold.ebi.ac.uk" target="_blank">AlphaFold&nbsp;DB</a> or the
474
  <a href="https://www.rcsb.org" target="_blank">Protein Data Bank (PDB)</a>.</li>
 
475
  <li><strong>If you only have an amino acid sequence or a UniProt ID,</strong>
476
  you must first visit the
477
  <a href="https://www.rcsb.org" target="_blank">Protein Data Bank (PDB)</a>
478
  or <a href="https://alphafold.ebi.ac.uk" target="_blank">AlphaFold&nbsp;DB</a>
479
  to search and download the corresponding <code>.cif</code> or <code>.pdb</code> file.</li>
 
480
  <li><strong>Drug input supports both SELFIES and SMILES:</strong><br>
481
  You can enter a SELFIES string directly, or paste a SMILES string.
482
  SMILES will be automatically converted to SELFIES using
483
  <a href="https://github.com/aspuru-guzik-group/selfies" target="_blank">SELFIES encoder</a>.
484
  If conversion fails, a red error message will be displayed.</li>
 
485
  <li>Optionally enter a <strong>1-based</strong> drug atom or substructure index
486
+ to highlight the Top-30 interacting protein residues.</li>
 
487
  <li>After inference, you can use the
488
  β€œDownload PDF” link to export a high-resolution vector version.</li>
489
  </ul>
 
556
  )
557
 
558
  if __name__ == "__main__":
559
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=True)