-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbindmaster.py
More file actions
executable file
·143 lines (115 loc) · 5.18 KB
/
bindmaster.py
File metadata and controls
executable file
·143 lines (115 loc) · 5.18 KB
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
#!/usr/bin/env python3
"""
BindMaster — unified CLI entry point (system Python, stdlib only)
Dispatches sub-commands to their respective scripts:
(no args) → interactive TUI menu (tui/app.py)
install → bash install/install.sh
configure → python configurator/configurator.py
evaluate → Mosaic/.venv/bin/python evaluator_legacy/evaluator.py
Usage:
bindmaster Interactive menu (TUI)
bindmaster install [--tool bindcraft|boltzgen|mosaic|all] [--cuda VERSION] [--skip-examples]
bindmaster configure [options passed through to configurator.py]
bindmaster evaluate <run-dir> [--metric METRIC] [--top N] [--refold N]
bindmaster --help
"""
import os
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parent
MOSAIC_VENV_PYTHON = REPO / "Mosaic" / ".venv" / "bin" / "python"
BOLD = "\033[1m"
CYAN = "\033[0;36m"
GREEN = "\033[0;32m"
RED = "\033[0;31m"
RESET = "\033[0m"
USAGE = f"""{BOLD}BindMaster{RESET} — GPU-accelerated protein binder design toolkit
{BOLD}Usage:{RESET}
bindmaster Interactive menu (TUI)
bindmaster install [--tool bindcraft|boltzgen|mosaic|all] [--cuda VERSION] [--skip-examples]
bindmaster configure [options passed through]
bindmaster evaluate <run-dir> [--metric METRIC] [--top N] [--refold N]
bindmaster --help
{BOLD}Commands:{RESET}
{CYAN}(no args){RESET} Launch interactive menu — install, configure, run, evaluate
{CYAN}install{RESET} Install BindCraft, BoltzGen, and/or Mosaic
{CYAN}configure{RESET} Interactive wizard to set up a run (target, tools, parameters)
{CYAN}evaluate{RESET} Parse outputs, rank designs, optionally re-fold top candidates
{BOLD}Environments:{RESET}
install → bash {REPO}/install/install.sh
configure → system python {REPO}/configurator/configurator.py
evaluate → Mosaic venv {REPO}/evaluator_legacy/evaluator.py
{BOLD}Clone:{RESET}
git clone https://github.com/damborik22/BindMaster.git
# aarch64 (DGX Spark): use install/install_aarch.sh instead of install.sh
"""
def _install_bindmaster_shortcut() -> None:
"""Write BindMaster/bin/bindmaster pointing at this script (idempotent)."""
local_bin = REPO / "bin"
script = Path(__file__).resolve()
target_line = f'exec python3 "{script}" "$@"\n'
shortcut_content = f"#!/usr/bin/env bash\n# BindMaster shortcut — auto-generated by bindmaster.py\n{target_line}"
# Primary: BindMaster/bin/ (always writable, fully local)
local_bin.mkdir(exist_ok=True)
shortcut = local_bin / "bindmaster"
if not shortcut.exists() or target_line not in shortcut.read_text():
shortcut.write_text(shortcut_content)
shortcut.chmod(0o755)
print(f"{GREEN}✓{RESET} Shortcut installed: {shortcut}")
# Secondary: ~/.local/bin/ (convenience, non-fatal if not writable)
try:
home_bin = Path.home() / ".local" / "bin"
home_bin.mkdir(parents=True, exist_ok=True)
home_shortcut = home_bin / "bindmaster"
if not home_shortcut.exists() or target_line not in home_shortcut.read_text():
home_shortcut.write_text(shortcut_content)
home_shortcut.chmod(0o755)
except OSError:
pass # ~/.local/bin not writable — BindMaster/bin/ is the primary location
def _dispatch(cmd: str, args: list) -> None:
"""Resolve and exec the appropriate sub-command. Never returns."""
if cmd == "install":
script = REPO / "install" / "install.sh"
if not script.exists():
print(f"{RED}✗ install.sh not found: {script}{RESET}", file=sys.stderr)
sys.exit(1)
print(f"{BOLD}BindMaster → install{RESET}")
os.execv("/bin/bash", ["/bin/bash", str(script)] + args)
elif cmd == "configure":
script = REPO / "configurator" / "configurator.py"
if not script.exists():
print(f"{RED}✗ configurator.py not found: {script}{RESET}", file=sys.stderr)
sys.exit(1)
print(f"{BOLD}BindMaster → configure{RESET}")
os.execv(sys.executable, [sys.executable, str(script)] + args)
elif cmd == "evaluate":
if not MOSAIC_VENV_PYTHON.exists():
print(
f"{RED}✗ Mosaic must be installed first (`bindmaster install --tool mosaic`){RESET}",
file=sys.stderr,
)
sys.exit(1)
script = REPO / "evaluator" / "evaluator.py"
if not script.exists():
print(f"{RED}✗ evaluator.py not found: {script}{RESET}", file=sys.stderr)
sys.exit(1)
print(f"{BOLD}BindMaster → evaluate{RESET}")
os.execv(str(MOSAIC_VENV_PYTHON), [str(MOSAIC_VENV_PYTHON), str(script)] + args)
else:
print(f"{RED}✗ Unknown command: {cmd!r}{RESET}", file=sys.stderr)
print(USAGE, file=sys.stderr)
sys.exit(1)
def main() -> None:
_install_bindmaster_shortcut()
args = sys.argv[1:]
if not args:
from tui.app import launch_tui
launch_tui(REPO)
return
if args[0] in ("-h", "--help"):
print(USAGE)
sys.exit(0)
cmd, rest = args[0], args[1:]
_dispatch(cmd, rest)
if __name__ == "__main__":
main()