Spaces:
Sleeping
Sleeping
File size: 7,829 Bytes
7a081f6 73ac8c4 985d408 3f6b5d5 9d0b7c6 cb10cd7 985d408 555ec33 985d408 b9cf7a5 12e552b 0eafe37 12e552b f3f0119 890a1ee a470b92 985d408 69f3090 73ac8c4 985d408 cb10cd7 73ac8c4 985d408 73ac8c4 8b5a02b 69f3090 73ac8c4 a470b92 51cb03c dfa6270 51cb03c a470b92 51cb03c 40a5916 0724f2d 985d408 0724f2d 985d408 0724f2d 40a5916 0724f2d 40a5916 b9cf7a5 0724f2d 2948e20 f3f0119 0724f2d f3f0119 0724f2d f3f0119 0724f2d f3f0119 0724f2d f3f0119 0724f2d f3f0119 0724f2d f3f0119 de9e615 890a1ee 829bdf3 890a1ee 985d408 40a5916 985d408 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | import gradio as gr
import os
import subprocess
from pathlib import Path
import shutil
import spaces
# Function to check that the files are in the same directory
def check_files_in_same_directory(file1, file2):
if file1 is None or file2 is None:
raise ValueError("Both the YAML config and target PDB/CIF files must be provided.")
if Path(file1.name).parent != Path(file2.name).parent:
raise ValueError("YAML config and target PDB/CIF must be in the same directory.")
def move_file_to_output(file, output_dir):
if file is None:
return None
src_path = Path(file.name) # path to the temp-uploaded file
dest_path = Path(output_dir) / src_path.name
dest_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src_path, dest_path) # preserves metadata
return dest_path
def move_files_to_output(yaml_file, target_file, output_dir):
yaml_path_dest = move_file_to_output(yaml_file, output_dir)
target_path_dest = move_file_to_output(target_file, output_dir)
check_files_in_same_directory(yaml_path_dest, target_path_dest)
return yaml_path_dest, target_path_dest
def download_results(results_dir, zip_name):
"""
Creates a ZIP of `results_dir` and returns (zip_path or None, message).
"""
results_dir = Path(results_dir)
if not results_dir.exists() or not results_dir.is_dir():
return None, "No results available for download."
# Ensure zip_name is a Path and has .zip extension
zip_path = Path(zip_name)
if zip_path.suffix != ".zip":
zip_path = zip_path.with_suffix(".zip")
# Make parent directory if needed
if zip_path.parent != Path(""):
zip_path.parent.mkdir(parents=True, exist_ok=True)
# shutil.make_archive wants base_name without extension
base_name = str(zip_path.with_suffix(""))
shutil.make_archive(
base_name=base_name,
format="zip",
root_dir=str(results_dir),
)
zip_path = Path(base_name + ".zip")
return str(zip_path), "Download ready!"
def find_log_file(output_dir):
# log files start with "boltzgen" and end with ".log"
log_files = list(Path(output_dir).glob("boltzgen*.log"))
if log_files:
# return the most recently modified log file
return max(log_files, key=lambda f: f.stat().st_mtime)
return None
@spaces.GPU(duration=300)
def run_boltzgen(yaml_file, target_file, protocol, num_designs, budget):
output_dir = "/tmp/output"
os.makedirs(output_dir, exist_ok=True)
# Move config and target files to the output directory
yaml_path_dest, target_path_dest = move_files_to_output(yaml_file, target_file, output_dir)
cmd = [
"boltzgen", "run", str(yaml_path_dest),
"--output", output_dir,
"--protocol", protocol,
"--num_designs", str(num_designs),
"--budget", str(budget),
"--cache", "/tmp/cache"
]
try:
result = subprocess.run(cmd, capture_output=True, text=True, cwd=output_dir, timeout=300)
if result.returncode == 0:
final_designs_dir = Path(output_dir) / "final_ranked_designs"
if final_designs_dir.exists() and final_designs_dir.is_dir():
return f"Success!\nDesigns saved to {final_designs_dir}/"
else:
return "No designs passed the filtering criteria."
return f"Error:\n{result.stderr}"
except subprocess.TimeoutExpired:
return "Timeout (300s limit)"
except Exception as e:
return f"Failed: {str(e)}"
# Interface
with gr.Blocks() as demo:
# Markdown with image at the beginning
gr.Markdown(""" <h1 style="font-size: 48px;">BoltzGen Design Space</h1>""")
gr.Markdown(
"""
<span style="font-size:20px">
**Design novel protein, peptide, and nanobody binders** against any biomolecular target (proteins, DNA, small molecules) using the BoltzGen diffusion model.
**BoltzGen** unifies structure prediction and binder design in a single all-atom generative model with flexible design constraints.
Developed by Hannes Stärk and team at MIT: [description](https://jclinic.mit.edu/boltzgen/) [git](https://github.com/HannesStark/boltzgen)
</span>
""")
gr.Markdown(
"""
### Instructions
1. Prepare a YAML config file specifying your design task. See [BoltzGen Docs](https://github.com/HannesStark/boltzgen/tree/main/example) for examples.
2. Upload the target structure file (PDB or CIF) corresponding to your design as needed (by the YAML config).
3. Select the design protocol (chose "protein-anything" for general results).
4. Specify the number of designs to generate. !Warning: high numbers may take longer to compute than your session allows.
5. Specify your budget (# of designs wanted in the final diversified set). Note that the budget must be less than or equal to the number of designs.
6. Click "Run BoltzGen" and wait for the results!
7. Download your results using the buttons at the bottom:
- Final Ranked Designs: structures, metrics and report summary of the best designs after filtering and ranking (interaction score and diversity).
- Intermediate Designs: all generated trajectories before filtering/ranking.
"""
)
with gr.Row():
yaml_file = gr.File(
label="Design YAML Config",
file_types=[".yaml", ".yml"],
file_count="single"
)
target_file = gr.File(
label="Target PDB/CIF",
file_types=[".pdb", ".cif"],
file_count="single"
)
with gr.Row():
num_designs = gr.Number(
value=10,
label="Number of Designs",
precision=0,
minimum=1,
maximum=1000
)
budget = gr.Number(
value=5,
label="Budget (in tokens)",
precision=0,
minimum=1,
maximum=1000
)
protocol = gr.Dropdown(
choices=["protein-anything", "peptide-anything", "nanobody-anything"],
value="protein-anything",
label="Protocol"
)
run_button = gr.Button("Run BoltzGen", variant="primary")
output_text = gr.Textbox(label="Run Status", lines=2)
run_button.click(
run_boltzgen,
inputs=[yaml_file, target_file, protocol, num_designs, budget],
outputs=[output_text]
)
gr.Markdown("## Download the results")
with gr.Row():
download_final_ranked_designs_button = gr.Button("Download Final Results")
download_intermediate_results_button = gr.Button("Download Intermediate Designs")
with gr.Row():
download_final_ranked_designs_button.click(
download_results,
inputs=[
gr.State("/tmp/output/final_ranked_designs"),
gr.State("final_ranked_designs.zip")
],
outputs=[
gr.File(label="Download Final Ranked Designs")
]
)
download_intermediate_results_button.click(
download_results,
inputs=[
gr.State("/tmp/output"),
gr.State("intermediate_results.zip")
],
outputs=[
gr.File(label="Download Intermediate Designs")
]
)
# Show the log output in a textbox for debugging
with gr.Row():
log_output = gr.Textbox(label="BoltzGen Log Output", lines=10)
run_button.click(
lambda: find_log_file("/tmp").read_text() if find_log_file("/tmp") else "No log file found.",
inputs=[],
outputs=log_output
)
demo.queue()
demo.launch() |