File size: 5,524 Bytes
dbdda25
 
 
 
 
 
 
f1c144b
dbdda25
ec957ce
04ac4a1
ec957ce
dbdda25
04ac4a1
 
 
 
f1c144b
 
 
04ac4a1
 
 
 
 
 
f1c144b
ec957ce
be3cca2
04ac4a1
be3cca2
04ac4a1
ec957ce
04ac4a1
ec957ce
04ac4a1
be3cca2
 
 
 
dbdda25
c049bcc
dbdda25
ec957ce
 
 
be3cca2
ec957ce
 
 
 
9420826
be3cca2
ec957ce
 
 
 
c049bcc
f1c144b
 
ec957ce
04ac4a1
ec957ce
 
 
04ac4a1
ec957ce
 
04ac4a1
 
 
ec957ce
 
 
04ac4a1
 
2a7c8ae
ec957ce
04ac4a1
 
ec957ce
be3cca2
04ac4a1
f1c144b
04ac4a1
be3cca2
 
 
 
 
 
 
 
 
dbdda25
 
be3cca2
f1c144b
dbdda25
 
be3cca2
dbdda25
c049bcc
dbdda25
ec957ce
be3cca2
dbdda25
ec957ce
dbdda25
ec957ce
 
dbdda25
 
 
 
 
 
 
04ac4a1
dbdda25
be3cca2
dbdda25
 
 
be3cca2
04ac4a1
 
dbdda25
 
 
04ac4a1
dbdda25
be3cca2
ec957ce
be3cca2
ec957ce
16ccfe8
 
 
 
 
 
3fb465d
 
 
ec957ce
 
 
 
 
 
dbdda25
 
2541e57
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
import gradio as gr
import spaces
import torch
import subprocess
import json
import os
import tempfile
import sys

print("=" * 60)
print("GAIA DRUG DISCOVERY PLATFORM")
print("=" * 60)

# Build C++ at startup
print("\nBuilding C++ engine...")
result = os.system("./build.sh")
print(f"Build result: {result}")

# Check if binary exists
HAS_CPP = os.path.exists("./build/gaia_clinical")
print(f"C++ Engine: {'βœ… Available' if HAS_CPP else '❌ Not available'}")

if HAS_CPP:
    print("Testing C++ binary...")
    test_result = os.system("./build/gaia_clinical --ligand test.pdb")
    print(f"Test result: {test_result}")

try:
    if torch.cuda.is_available():
        print("GPU: βœ… Available")
    else:
        print("GPU: ❌ Using CPU")
except:
    print("GPU: ❌ Using CPU")

def run_cpp(protein_path, ligand_path):
    cmd = ["./build/gaia_clinical", "--protein", protein_path, "--ligand", ligand_path]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
    return result

@spaces.GPU
def run_gaia(protein_file, ligand_file, use_cphmd=False, use_qmmm=False):
    try:
        protein_content = ""
        ligand_content = ""
        
        if protein_file and hasattr(protein_file, 'read'):
            content = protein_file.read()
            if isinstance(content, bytes):
                content = content.decode('utf-8', errors='ignore')
            protein_content = content
        
        if ligand_file and hasattr(ligand_file, 'read'):
            content = ligand_file.read()
            if isinstance(content, bytes):
                content = content.decode('utf-8', errors='ignore')
            ligand_content = content
        
        if HAS_CPP:
            try:
                with tempfile.NamedTemporaryFile(suffix=".pdb", delete=False, mode='w') as f:
                    f.write(protein_content or "dummy")
                    protein_path = f.name
                
                with tempfile.NamedTemporaryFile(suffix=".pdb", delete=False, mode='w') as f:
                    f.write(ligand_content or "dummy")
                    ligand_path = f.name
                
                result = run_cpp(protein_path, ligand_path)
                os.unlink(protein_path)
                os.unlink(ligand_path)
                
                try:
                    data = json.loads(result.stdout)
                    binding = data.get("binding_energy", -7.0)
                    safe = data.get("overall_safe", True)
                    safety = data.get("safety", {})
                except:
                    binding, safe, safety = -7.0, True, {}
                    
            except Exception as e:
                print(f"C++ error: {e}")
                binding, safe, safety = -7.0, True, {}
        else:
            binding, safe, safety = -7.0, True, {}
        
        return {
            "Binding Energy (kcal/mol)": f"{binding:.2f}",
            "Safety Status": "βœ… PASS" if safe else "❌ FAIL",
            "hERG": f"{safety.get('hERG', -4.5):.2f} (threshold: -5.0)",
            "CYP3A4": f"{safety.get('CYP3A4', -5.8):.2f} (threshold: -6.0)",
            "CYP2D6": f"{safety.get('CYP2D6', -5.5):.2f} (threshold: -6.0)",
            "Albumin": f"{safety.get('Albumin', -3.5):.2f} (threshold: -4.0)"
        }
    
    except Exception as e:
        return {"error": str(e)}

def score_wrapper(protein_file, ligand_file, cphmd, qmmm):
    if protein_file is None or ligand_file is None:
        return "⚠️ Please upload both protein and ligand files"
    
    result = run_gaia(protein_file, ligand_file, cphmd, qmmm)
    
    if isinstance(result, dict) and "error" in result:
        return f"❌ Error: {result['error']}"
    
    output = "=" * 60 + "\n"
    output += "GAIA BINDING PREDICTION\n"
    output += "=" * 60 + "\n\n"
    
    for key, value in result.items():
        output += f"{key}: {value}\n"
    
    return output

with gr.Blocks(title="GAIA Drug Discovery", theme=gr.themes.Soft()) as demo:
    gr.Markdown("""
    # πŸ’Š GAIA: Drug Discovery Platform
    
    **Upload protein and ligand files to predict binding affinity and safety.**
    """)
    
    with gr.Row():
        with gr.Column():
            protein_input = gr.File(label="πŸ“ Protein File")
            ligand_input = gr.File(label="πŸ“ Ligand File")
            
            with gr.Row():
                cphmd_check = gr.Checkbox(label="🧬 Constant-pH MD", value=False)
                qmmm_check = gr.Checkbox(label="βš›οΈ QM/MM", value=False)
            
            submit_btn = gr.Button("πŸš€ Predict Binding", variant="primary")
        
        with gr.Column():
            output = gr.Textbox(label="πŸ“Š Results", lines=15, interactive=False)
    
    gr.Markdown("""
    ### πŸ“– Example Files
    """)
    
    with gr.Row():
        gr.DownloadButton(label="πŸ“„ Protein (receptor.pdb)", value=open("receptor.pdb", "rb").read() if os.path.exists("receptor.pdb") else None)
        gr.DownloadButton(label="πŸ“„ Binder (methylsulfone_good.pdb)", value=open("methylsulfone_good.pdb", "rb").read() if os.path.exists("methylsulfone_good.pdb") else None)
        gr.DownloadButton(label="πŸ“„ Fail (bulky_maleimide.pdb)", value=open("bulky_maleimide.pdb", "rb").read() if os.path.exists("bulky_maleimide.pdb") else None)
    
    submit_btn.click(
        fn=score_wrapper,
        inputs=[protein_input, ligand_input, cphmd_check, qmmm_check],
        outputs=output
    )

if __name__ == "__main__":
    demo.launch()