File size: 5,782 Bytes
d21699a
 
 
4a8fef6
8122b27
d21699a
5d1083e
 
d21699a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62b3565
9b85825
d21699a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import os
import py3Dmol
import requests
from pathlib import Path

DEFAULT_SEQ = "MGSSHHHHHHSSGLVPRGSHMRGPNPTAASLEASAGPFTVRSFTVSRPSGYGAGTVYYPTNAGGTVGAIAIVPGYTARQSSIKWWGPRLASHGFVVITIDTNSTLDQPSSRSSQQMAALRQVASLNGTSSSPIYGKVDTARMGVMGWSMGGGGSLISAANNPSLKAAAPQAPWDSSTNFSSVTVPTLIFACENDSIAPVNSSALPIYDSMSRNAKQFLEINGGSHSCANSGNSNQALIGKKGVAWMKRFMDNDTRYSTFACENPNSTRVSDFRTANCSLEDPAANKARKEAELAAATAEQ"

def display_pdb_by_pdb(pdb):
    # function to display pdb in py3dmol
    # ref: https://huggingface.co/spaces/AIGE/A_B

    view = py3Dmol.view(width=500, height=500)
    view.addModel(pdb, "pdb")
    view.setStyle({'cartoon': {'color': 'spectrum'}})
    view.zoomTo()
    output = view._make_html().replace("'", '"')
    x = f"""<!DOCTYPE html><html></center> {output} </center></html>"""  # do not use ' in this input
    
    return f"""<iframe height="500px" width="100%"  name="result" allow="midi; geolocation; microphone; camera;
                            display-capture; encrypted-media;" sandbox="allow-modals allow-forms
                            allow-scripts allow-same-origin allow-popups
                            allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
                            allowpaymentrequest="" frameborder="0" srcdoc='{x}'></iframe>"""

def get_pdb(sequence):
    retries = 0
    pdb_str = None
    url = "https://api.esmatlas.com/foldSequence/v1/pdb/"
    while retries < 3 and pdb_str is None:
        response = requests.post(url, data=sequence, verify=False)
        pdb_str = response.text
        if pdb_str == "INTERNAL SERVER ERROR":
            retries += 1
            time.sleep(0.1)
            pdb = str = None
    return pdb_str

def update(sequence=DEFAULT_SEQ):
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }

    response = requests.post('https://api.esmatlas.com/foldSequence/v1/pdb/', headers=headers, data=sequence, verify=False)  #verify=false jw 0425 work around for SSL certificate 

    pdb_string = get_pdb(sequence) 
    name = sequence[:3] + sequence[-3:] 

    outpath = (
        Path.cwd() / f"PDB-{name}.pdb")
    
    with open(outpath.name, "w") as f:
        f.write(pdb_string)

    outpath_str = str(outpath)

    html_view = display_pdb_by_pdb(pdb_string)

    return outpath_str, html_view

def suggest(option):
   if option == "Plastic degradation protein":
     suggestion = "MGSSHHHHHHSSGLVPRGSHMRGPNPTAASLEASAGPFTVRSFTVSRPSGYGAGTVYYPTNAGGTVGAIAIVPGYTARQSSIKWWGPRLASHGFVVITIDTNSTLDQPSSRSSQQMAALRQVASLNGTSSSPIYGKVDTARMGVMGWSMGGGGSLISAANNPSLKAAAPQAPWDSSTNFSSVTVPTLIFACENDSIAPVNSSALPIYDSMSRNAKQFLEINGGSHSCANSGNSNQALIGKKGVAWMKRFMDNDTRYSTFACENPNSTRVSDFRTANCSLEDPAANKARKEAELAAATAEQ"
   elif option == "Antifreeze protein":
     suggestion = "QCTGGADCTSCTGACTGCGNCPNAVTCTNSQHCVKANTCTGSTDCNTAQTCTNSKDCFEANTCTDSTNCYKATACTNSSGCPGH"
   elif option == "AI Generated protein":
     suggestion = "MSGMKKLYEYTVTTLDEFLEKLKEFILNTSKDKIYKLTITNPKLIKDIGKAIAKAAEIADVDPKEIEEMIKAVEENELTKLVITIEQTDDKYVIKVELENEDGLVHSFEIYFKNKEEMEKFLELLEKLISKLSGS"
   elif option == "7-bladed propeller fold":
     suggestion = "VKLAGNSSLCPINGWAVYSKDNSIRIGSKGDVFVIREPFISCSHLECRTFFLTQGALLNDKHSNGTVKDRSPHRTLMSCPVGEAPSPYNSRFESVAWSASACHDGTSWLTIGISGPDNGAVAVLKYNGIITDTIKSWRNNILRTQESECACVNGSCFTVMTDGPSNGQASYKIFKMEKGKVVKSVELDAPNYHYEECSCYPNAGEITCVCRDNWHGSNRPWVSFNQNLEYQIGYICSGVFGDNPRPNDGTGSCGPVSSNGAYGVKGFSFKYGNGVWIGRTKSTNSRSGFEMIWDPNGWTETDSSFSVKQDIVAITDWSGYSGSFVQHPELTGLDCIRPCFWVELIRGRPKESTIWTSGSSISFCGVNSDTVGWSWPDGAELPFTIDK"
   else:
     suggestion = ""
   return suggestion

demo = gr.Blocks()

with demo:
    gr.HTML("""<div style="text-align: center; max-width: 700px; margin: 0 auto;">
              <div
              style="
                  display: inline-flex;
                  align-items: center;
                  gap: 0.8rem;
                  font-size: 1.75rem;
              "
              >
              <h1 style="font-weight: 900; margin-bottom: 7px; margin-top: 5px;">
                   ESMFold Protein Folding Structure
              </h1>
              </div>
              <p style="margin-bottom: 10px; font-size: 94%">
                  You can input a single protein sequence and you get the predicted protein structure
              </p>
          </div>""")
    name = gr.Dropdown(label="Choose a Sample Protein", value="Plastic degradation protein", choices=["Antifreeze protein", "Plastic degradation protein",  "AI Generated protein", "7-bladed propeller fold", "custom"])
    with gr.Row():
        inp = gr.Textbox(label="Protein sequence", lines=3, value=DEFAULT_SEQ, placeholder="Paste your protein sequence here...")
        btn = gr.Button("Plot Predicted Structure ")
        #btn = gr.Button("🔬 Predict Structure ").style(full_width=False)
    with gr.Row():   
        PDB_string = gr.Textbox(
            lines=4,
            max_lines=120,
            label="PDB_string Output"
        )
    with gr.Row():    
        output_file = gr.File(
            label="Download PDB Structure as Text File",
            file_count="single",
            type="filepath",  
            interactive=False,
        )  
        output_viewer = gr.HTML()
    
    btn.click(fn=update, inputs=inp, outputs=[output_file, output_viewer])
    
    name.change(fn=suggest, inputs=name, outputs=inp)
    inp.change(fn=update, inputs=inp, outputs=output_file)
    
    gr.Markdown("A demo of [ESM](https://esmatlas.com/about) by Meta using the API. You can also use ESM in Hugging Face `transformers` as shown [here](https://github.com/huggingface/notebooks/blob/ab81a52182acf691e6743a50bc47bd1c1622086f/examples/protein_folding.ipynb), which is supported since [v4.24](https://github.com/huggingface/transformers/releases/tag/v4.24.0).")


demo.launch()