|
import gradio as gr |
|
import os |
|
import py3Dmol |
|
import requests |
|
from pathlib import Path |
|
|
|
DEFAULT_SEQ = "MGSSHHHHHHSSGLVPRGSHMRGPNPTAASLEASAGPFTVRSFTVSRPSGYGAGTVYYPTNAGGTVGAIAIVPGYTARQSSIKWWGPRLASHGFVVITIDTNSTLDQPSSRSSQQMAALRQVASLNGTSSSPIYGKVDTARMGVMGWSMGGGGSLISAANNPSLKAAAPQAPWDSSTNFSSVTVPTLIFACENDSIAPVNSSALPIYDSMSRNAKQFLEINGGSHSCANSGNSNQALIGKKGVAWMKRFMDNDTRYSTFACENPNSTRVSDFRTANCSLEDPAANKARKEAELAAATAEQ" |
|
|
|
def display_pdb_by_pdb(pdb): |
|
|
|
|
|
|
|
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>""" |
|
|
|
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) |
|
|
|
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...", scale = 8) |
|
btn = gr.Button(value = "Plot Predicted Structure ", scale = 2) |
|
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) |
|
|
|
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() |