IAmKarthik commited on
Commit
e6a0ebc
·
verified ·
1 Parent(s): 3e1cff0

Deploy ESM-2, MoLFormer, and affinity ONNX application

Browse files
Files changed (1) hide show
  1. app.py +95 -5
app.py CHANGED
@@ -2,6 +2,8 @@ from __future__ import annotations
2
 
3
  import html
4
  import os
 
 
5
  from functools import lru_cache
6
  from pathlib import Path
7
 
@@ -42,6 +44,41 @@ ATOM_COLORS = {
42
  "BR": "#92400e",
43
  "I": "#7e22ce",
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
 
47
  def validate_protein(sequence: str) -> str:
@@ -131,6 +168,11 @@ def predict(sequence: str, smiles: str):
131
  )
132
 
133
 
 
 
 
 
 
134
  def prediction_card(prediction: float) -> str:
135
  return (
136
  "<div class='score-card'>"
@@ -275,11 +317,9 @@ def molecule_3d(smiles: str) -> Image.Image:
275
  return image
276
 
277
 
278
- def protein_3d(pdb_file) -> Image.Image:
279
- if pdb_file is None:
280
- raise gr.Error("Upload a PDB file. A sequence alone has no 3D coordinates.")
281
  coordinates = []
282
- for line in Path(pdb_file).read_text(encoding="utf-8", errors="replace").splitlines():
283
  if line.startswith(("ATOM ", "HETATM")) and line[12:16].strip() == "CA":
284
  try:
285
  coordinates.append(
@@ -315,6 +355,30 @@ def protein_3d(pdb_file) -> Image.Image:
315
  return image
316
 
317
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  EXAMPLE_PROTEIN = "MAVMKNYLLPILVLFLAYYYYSTNEEFRPEMLQGKKVIVTGASKGIGREMAYHLSKMGAHVVLTARSEEGLQK"
319
  EXAMPLE_SMILES = "C1CC1(C2=CC=C(C=C2)F)C(=O)N3CC4CC4(C3)C5=CNC6=C5C=CC=N6"
320
 
@@ -367,6 +431,11 @@ with gr.Blocks(title="Protein-Compound Affinity Explorer", css=CSS) as demo:
367
  value=EXAMPLE_SMILES,
368
  )
369
  run = gr.Button("Predict affinity and render inputs", variant="primary", size="lg")
 
 
 
 
 
370
 
371
  with gr.Column(visible=False) as results:
372
  score = gr.HTML()
@@ -386,14 +455,35 @@ with gr.Blocks(title="Protein-Compound Affinity Explorer", css=CSS) as demo:
386
  [score, image, view_3d, molecule_data, protein_view, protein_data],
387
  ).then(lambda: gr.update(visible=True), outputs=results)
388
 
 
 
 
 
 
 
 
 
 
 
389
  with gr.Accordion("Optional protein 3D viewer", open=False):
390
  gr.Markdown(
391
  "A protein sequence does not contain 3D coordinates. Upload a PDB file "
392
- "to inspect an experimentally determined or predicted structure."
393
  )
394
  pdb = gr.File(label="PDB file", file_types=[".pdb"], type="filepath")
395
  pdb_view = gr.Image(label="Protein backbone projection", height=520)
396
  gr.Button("Render PDB structure").click(protein_3d, pdb, pdb_view)
 
 
 
 
 
 
 
 
 
 
 
397
  gr.Markdown(
398
  html.escape(
399
  "Research demonstration only. Predictions are not medical or drug-development advice."
 
2
 
3
  import html
4
  import os
5
+ import urllib.error
6
+ import urllib.request
7
  from functools import lru_cache
8
  from pathlib import Path
9
 
 
44
  "BR": "#92400e",
45
  "I": "#7e22ce",
46
  }
47
+ PAIR_EXAMPLES = [
48
+ {
49
+ "name": "Ubiquitin + caffeine",
50
+ "protein": (
51
+ "MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTL"
52
+ "SDYNIQKESTLHLVLRLRGG"
53
+ ),
54
+ "smiles": "CN1C=NC2=C1C(=O)N(C(=O)N2C)C",
55
+ },
56
+ {
57
+ "name": "Lysozyme + ibuprofen",
58
+ "protein": (
59
+ "KVFGRCELAAAMKRHGLDNYRGYSLGNWVCAAKFESNFNTQATNRNTDGSTDYGIL"
60
+ "QINSRWWCNDGRTPGSRNLCNIPCSALLSSDITASVNCAKKIVSDGNGMNAWVAWR"
61
+ "NRCKGTDVQAWIRGCRL"
62
+ ),
63
+ "smiles": "CC(C)CC1=CC=C(C=C1)C(C)C(=O)O",
64
+ },
65
+ {
66
+ "name": "Insulin B chain + aspirin",
67
+ "protein": "FVNQHLCGSHLVEALYLVCGERGFFYTPKT",
68
+ "smiles": "CC(=O)OC1=CC=CC=C1C(=O)O",
69
+ },
70
+ {
71
+ "name": "Villin headpiece + acetaminophen",
72
+ "protein": "LSDEDFKAVFGMTRSAFANLPLWKQQNLKKEKGLF",
73
+ "smiles": "CC(=O)NC1=CC=C(C=C1)O",
74
+ },
75
+ ]
76
+ PDB_EXAMPLES = [
77
+ ("1UBQ", "Ubiquitin"),
78
+ ("1LYZ", "Lysozyme"),
79
+ ("1CRN", "Crambin"),
80
+ ("1L2Y", "Trp-cage"),
81
+ ]
82
 
83
 
84
  def validate_protein(sequence: str) -> str:
 
168
  )
169
 
170
 
171
+ def pair_example(index: int) -> tuple[str, str]:
172
+ example = PAIR_EXAMPLES[index]
173
+ return example["protein"], example["smiles"]
174
+
175
+
176
  def prediction_card(prediction: float) -> str:
177
  return (
178
  "<div class='score-card'>"
 
317
  return image
318
 
319
 
320
+ def protein_backbone_image(pdb_text: str) -> Image.Image:
 
 
321
  coordinates = []
322
+ for line in pdb_text.splitlines():
323
  if line.startswith(("ATOM ", "HETATM")) and line[12:16].strip() == "CA":
324
  try:
325
  coordinates.append(
 
355
  return image
356
 
357
 
358
+ def protein_3d(pdb_file) -> Image.Image:
359
+ if pdb_file is None:
360
+ raise gr.Error("Upload a PDB file. A sequence alone has no 3D coordinates.")
361
+ pdb_text = Path(pdb_file).read_text(encoding="utf-8", errors="replace")
362
+ return protein_backbone_image(pdb_text)
363
+
364
+
365
+ @lru_cache(maxsize=len(PDB_EXAMPLES))
366
+ def load_sample_pdb(pdb_id: str) -> Image.Image:
367
+ valid_ids = {identifier for identifier, _ in PDB_EXAMPLES}
368
+ if pdb_id not in valid_ids:
369
+ raise gr.Error("Unknown sample PDB identifier.")
370
+ request = urllib.request.Request(
371
+ f"https://files.rcsb.org/download/{pdb_id}.pdb",
372
+ headers={"User-Agent": "protein-compound-affinity-space/1.0"},
373
+ )
374
+ try:
375
+ with urllib.request.urlopen(request, timeout=30) as response:
376
+ pdb_text = response.read().decode("utf-8", errors="replace")
377
+ except (urllib.error.URLError, TimeoutError) as error:
378
+ raise gr.Error(f"Could not download {pdb_id} from RCSB PDB: {error}") from error
379
+ return protein_backbone_image(pdb_text)
380
+
381
+
382
  EXAMPLE_PROTEIN = "MAVMKNYLLPILVLFLAYYYYSTNEEFRPEMLQGKKVIVTGASKGIGREMAYHLSKMGAHVVLTARSEEGLQK"
383
  EXAMPLE_SMILES = "C1CC1(C2=CC=C(C=C2)F)C(=O)N3CC4CC4(C3)C5=CNC6=C5C=CC=N6"
384
 
 
431
  value=EXAMPLE_SMILES,
432
  )
433
  run = gr.Button("Predict affinity and render inputs", variant="primary", size="lg")
434
+ gr.Markdown("#### One-click examples")
435
+ with gr.Row():
436
+ example_buttons = [
437
+ gr.Button(example["name"], size="sm") for example in PAIR_EXAMPLES
438
+ ]
439
 
440
  with gr.Column(visible=False) as results:
441
  score = gr.HTML()
 
455
  [score, image, view_3d, molecule_data, protein_view, protein_data],
456
  ).then(lambda: gr.update(visible=True), outputs=results)
457
 
458
+ for index, button in enumerate(example_buttons):
459
+ button.click(
460
+ lambda selected=index: pair_example(selected),
461
+ outputs=[protein, smiles],
462
+ ).then(
463
+ predict,
464
+ [protein, smiles],
465
+ [score, image, view_3d, molecule_data, protein_view, protein_data],
466
+ ).then(lambda: gr.update(visible=True), outputs=results)
467
+
468
  with gr.Accordion("Optional protein 3D viewer", open=False):
469
  gr.Markdown(
470
  "A protein sequence does not contain 3D coordinates. Upload a PDB file "
471
+ "or select one of the four RCSB PDB examples."
472
  )
473
  pdb = gr.File(label="PDB file", file_types=[".pdb"], type="filepath")
474
  pdb_view = gr.Image(label="Protein backbone projection", height=520)
475
  gr.Button("Render PDB structure").click(protein_3d, pdb, pdb_view)
476
+ gr.Markdown("#### Sample PDB structures")
477
+ with gr.Row():
478
+ pdb_buttons = [
479
+ gr.Button(f"{pdb_id} · {name}", size="sm")
480
+ for pdb_id, name in PDB_EXAMPLES
481
+ ]
482
+ for (pdb_id, _), button in zip(PDB_EXAMPLES, pdb_buttons):
483
+ button.click(
484
+ lambda selected=pdb_id: load_sample_pdb(selected),
485
+ outputs=pdb_view,
486
+ )
487
  gr.Markdown(
488
  html.escape(
489
  "Research demonstration only. Predictions are not medical or drug-development advice."