silterra commited on
Commit
275b482
1 Parent(s): 3ee7677

Add UI inputs for pocket center x/y/z and flexible sidechains.

Browse files
Files changed (4) hide show
  1. README.md +12 -0
  2. main.py +23 -9
  3. requirements.txt +1 -1
  4. run_utils.py +17 -16
README.md CHANGED
@@ -10,3 +10,15 @@ pinned: false
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
+
14
+ ---------
15
+
16
+ ## How to use this space
17
+
18
+ This is a simple app intended to showcase [DiffDock-Pocket](https://github.com/plainerman/DiffDock-Pocket).
19
+ One can upload a protein and ligand, and calculate the predicted structure. The results are visualized in 3D and can be downloaded.
20
+
21
+ * This app is designed to take 1 protein (in PDB format) and 1 ligand (in SDF format) at a time. For bulk inference, use the [command line interface](https://github.com/plainerman/DiffDock-Pocket/blob/main/README.md#running-diffdock-pocket-on-custom-complexes).
22
+
23
+ * Our demonstration space uses a CPU, so it may take a few minutes to run. For faster results, use a GPU.
24
+ One can duplicate this space (at their own expense) by selecting "⋮" -> "Duplicate this space" in the top right corner, and then selecting a GPU in the "Settings" tab.
main.py CHANGED
@@ -2,22 +2,25 @@ import datetime
2
  from typing import Tuple, Optional
3
 
4
  import gradio as gr
 
5
 
6
  import mol_viewer
7
  import run_utils
8
 
9
 
10
- def run_wrapper(protein_file, ligand_file, other_args_file, *args, **kwargs) -> Tuple[str, Optional[str], str]:
 
11
  if protein_file is None:
12
  return "Protein file is missing! Must provide a protein file in PDB format", None, ""
13
  if ligand_file is None:
14
  return "Ligand file is missing! Must provide a ligand file in SDF format", None, ""
15
 
 
16
  if other_args_file is not None:
17
- kwargs["other_arg_file"] = other_args_file.name
18
 
19
  output_file, pdb_text, sdf_text = run_utils.run_cli_command(
20
- protein_file.name, ligand_file.name, *args, **kwargs
21
  )
22
 
23
  output_viz = "No visualisation created"
@@ -38,15 +41,24 @@ def run():
38
  protein_pdb = gr.File(label="Protein PDB (required)", file_types=[".pdb"])
39
  ligand_sdf = gr.File(label="Ligand SDF (required)", file_types=[".sdf"])
40
  with gr.Row():
41
- samples_per_complex = gr.Number(label="Samples Per Complex", value=1, minimum=1, maximum=100, precision=0)
 
42
  with gr.Column():
43
- keep_local_structures = gr.Checkbox(label="Keep Local Structures", value=True)
44
- save_vis = gr.Checkbox(label="Save Visualisation", value=True)
 
 
 
 
 
 
 
 
45
  with gr.Row():
46
  gr.Markdown("""Additional values can be included in "Other arguments", and will be passed
47
  to [inference.py](https://github.com/plainerman/DiffDock-Pocket/blob/main/inference.py).
48
  Must be a YAML file without any nesting. """)
49
- other_args = gr.File(label="Other arguments (Optional, YML)", file_types=[".yml", ".yaml"], value=None)
50
 
51
  with gr.Row():
52
  run_btn = gr.Button("Run DiffDock-Pocket")
@@ -59,9 +71,11 @@ def run():
59
  init_value = "Rank1 Reverse Processed Protein will be visualised here"
60
  viewer = gr.HTML(value=init_value, label="Protein Viewer", show_label=True)
61
 
62
- _inputs = [protein_pdb, ligand_sdf, other_args, samples_per_complex, keep_local_structures, save_vis]
 
 
63
  _outputs = [message, output_file, viewer]
64
- run_btn.click(fn=run_wrapper, inputs=_inputs, outputs=_outputs)
65
 
66
  demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
67
 
 
2
  from typing import Tuple, Optional
3
 
4
  import gradio as gr
5
+ import yaml
6
 
7
  import mol_viewer
8
  import run_utils
9
 
10
 
11
+ def run_wrapper(protein_file, ligand_file, other_args_file, *args) -> Tuple[str, Optional[str], str]:
12
+
13
  if protein_file is None:
14
  return "Protein file is missing! Must provide a protein file in PDB format", None, ""
15
  if ligand_file is None:
16
  return "Ligand file is missing! Must provide a ligand file in SDF format", None, ""
17
 
18
+ other_args_dict = {}
19
  if other_args_file is not None:
20
+ other_args_dict = yaml.safe_load(open(other_args_file['name'], "r"))
21
 
22
  output_file, pdb_text, sdf_text = run_utils.run_cli_command(
23
+ protein_file['name'], ligand_file['name'], other_args_dict, *args,
24
  )
25
 
26
  output_viz = "No visualisation created"
 
41
  protein_pdb = gr.File(label="Protein PDB (required)", file_types=[".pdb"])
42
  ligand_sdf = gr.File(label="Ligand SDF (required)", file_types=[".sdf"])
43
  with gr.Row():
44
+ samples_per_complex = gr.Number(label="Samples Per Complex", value=1, minimum=1, maximum=100, precision=0,
45
+ interactive=True)
46
  with gr.Column():
47
+ keep_local_structures = gr.Checkbox(label="Keep Local Structures", value=True, interactive=True)
48
+ save_vis = gr.Checkbox(label="Save Visualisation", value=True, interactive=True,
49
+ elem_id="save_visualisation")
50
+ with gr.Row():
51
+ # Add fields for pocket_center_x, pocket_center_y, pocket_center_z
52
+ pcx = gr.Number(label="Pocket Center X", value=None, precision=4, interactive=True)
53
+ pcy = gr.Number(label="Pocket Center Y", value=None, precision=4, interactive=True)
54
+ pcz = gr.Number(label="Pocket Center Z", value=None, precision=4, interactive=True)
55
+ flex_sidechains = gr.Textbox(label="Flexible Sidechains", placeholder="A:130-B:140", value=None, interactive=True,
56
+ info="Specify which amino acids will be flexible. E.g., A:130-B:140 will make amino acid with id 130 in chain A, and id 140 in chain B flexible.")
57
  with gr.Row():
58
  gr.Markdown("""Additional values can be included in "Other arguments", and will be passed
59
  to [inference.py](https://github.com/plainerman/DiffDock-Pocket/blob/main/inference.py).
60
  Must be a YAML file without any nesting. """)
61
+ other_args_file = gr.File(label="Other arguments (Optional, YML)", file_types=[".yml", ".yaml"], value=None)
62
 
63
  with gr.Row():
64
  run_btn = gr.Button("Run DiffDock-Pocket")
 
71
  init_value = "Rank1 Reverse Processed Protein will be visualised here"
72
  viewer = gr.HTML(value=init_value, label="Protein Viewer", show_label=True)
73
 
74
+ _inputs = [protein_pdb, ligand_sdf, other_args_file]
75
+ # See run_utils.py:ARG_ORDER for the order of these arguments
76
+ _inputs += [samples_per_complex, keep_local_structures, save_vis, pcx, pcy, pcz, flex_sidechains]
77
  _outputs = [message, output_file, viewer]
78
+ run_btn.click(fn=run_wrapper, inputs=_inputs, outputs=_outputs, preprocess=False)
79
 
80
  demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
81
 
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- gradio==3.50
2
  requests==2.31.0
3
  pyyaml==6.0.1
 
1
+ gradio==3.50.*
2
  requests==2.31.0
3
  pyyaml==6.0.1
run_utils.py CHANGED
@@ -8,7 +8,8 @@ import uuid
8
  import logging
9
  from typing import List
10
 
11
- import yaml
 
12
 
13
 
14
  def set_env_variables():
@@ -51,7 +52,7 @@ def kwargs_to_cli_args(**kwargs) -> List[str]:
51
  if value:
52
  cli_args.append(f"--{key}")
53
  else:
54
- if value is not None:
55
  cli_args.append(f"--{key}={value}")
56
 
57
  return cli_args
@@ -67,10 +68,8 @@ def read_file_lines(fi_path: str):
67
  def run_cli_command(
68
  protein_path: str,
69
  ligand: str,
70
- samples_per_complex: int,
71
- keep_local_structures: bool,
72
- save_visualisation: bool,
73
- other_arg_file: str = None,
74
  work_dir=None,
75
  ):
76
  if work_dir is None:
@@ -78,16 +77,14 @@ def run_cli_command(
78
  "DiffDock-Pocket-Dir", os.path.join(os.environ["HOME"], "DiffDock-Pocket")
79
  )
80
 
81
- all_arg_dict = {}
82
- if other_arg_file:
83
- all_arg_dict = yaml.safe_load(open(other_arg_file, "r"))
84
- logging.debug(f"YAML dict: {all_arg_dict}")
85
 
86
- ui_args = ["protein_path", "ligand", "samples_per_complex",
87
- "keep_local_structures", "save_visualisation"]
88
- for ui_arg in ui_args:
89
- my_str = f"all_arg_dict['{ui_arg}'] = {ui_arg}"
90
- exec(my_str)
 
91
 
92
  command = [
93
  "python3",
@@ -163,7 +160,7 @@ def run_cli_command(
163
  return full_zip_path, pdb_text, sdf_text
164
 
165
 
166
- if __name__ == "__main__":
167
  # Testing code
168
  set_env_variables()
169
  configure_logging()
@@ -182,3 +179,7 @@ if __name__ == "__main__":
182
  save_visualisation=True,
183
  other_arg_file=other_arg_file
184
  )
 
 
 
 
 
8
  import logging
9
  from typing import List
10
 
11
+ ARG_ORDER = ["samples_per_complex", "keep_local_structures", "save_visualisation",
12
+ "pocket_center_x", "pocket_center_y", "pocket_center_z", "flexible_sidechains"]
13
 
14
 
15
  def set_env_variables():
 
52
  if value:
53
  cli_args.append(f"--{key}")
54
  else:
55
+ if value is not None and str(value) != "":
56
  cli_args.append(f"--{key}={value}")
57
 
58
  return cli_args
 
68
  def run_cli_command(
69
  protein_path: str,
70
  ligand: str,
71
+ other_args_dict: dict,
72
+ *args,
 
 
73
  work_dir=None,
74
  ):
75
  if work_dir is None:
 
77
  "DiffDock-Pocket-Dir", os.path.join(os.environ["HOME"], "DiffDock-Pocket")
78
  )
79
 
80
+ assert len(args) == len(ARG_ORDER), f'Expected {len(ARG_ORDER)} arguments, got {len(args)}'
 
 
 
81
 
82
+ all_arg_dict = other_args_dict
83
+ all_arg_dict["protein_path"] = protein_path
84
+ all_arg_dict["ligand"] = ligand
85
+
86
+ for arg_name, arg_val in zip(ARG_ORDER, args):
87
+ all_arg_dict[arg_name] = arg_val
88
 
89
  command = [
90
  "python3",
 
160
  return full_zip_path, pdb_text, sdf_text
161
 
162
 
163
+ def main_test():
164
  # Testing code
165
  set_env_variables()
166
  configure_logging()
 
179
  save_visualisation=True,
180
  other_arg_file=other_arg_file
181
  )
182
+
183
+
184
+ if __name__ == "__main__":
185
+ main_test()