|
import gradio as gr |
|
from igfold import IgFoldRunner |
|
import os |
|
import random |
|
import base64 |
|
import socket |
|
|
|
|
|
def read_mol(molpath): |
|
with open(molpath, "r") as fp: |
|
lines = fp.readlines() |
|
mol = "" |
|
for l in lines: |
|
mol += l |
|
return mol |
|
|
|
|
|
def molecule(input_pdb, h_seq, l_seq): |
|
|
|
mol = read_mol(input_pdb) |
|
|
|
byte_content = mol.encode('utf-8') |
|
base64_content = base64.b64encode(byte_content).decode('utf-8') |
|
|
|
|
|
x = ( |
|
"""<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> |
|
<style> |
|
body{ |
|
font-family:sans-serif |
|
} |
|
.mol-container { |
|
width: 100%; |
|
height: 600px; |
|
position: relative; |
|
} |
|
.mol-container select{ |
|
background-image:None; |
|
} |
|
</style> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> |
|
<script src="https://3Dmol.csb.pitt.edu/build/3Dmol-min.js"></script> |
|
</head> |
|
<body> |
|
<div id="container" class="mol-container"></div> |
|
|
|
<script> |
|
|
|
let h_seq = `""" |
|
+ h_seq |
|
+ """` |
|
|
|
let l_seq = `""" |
|
+ l_seq |
|
+ """` |
|
|
|
let pdb = `""" |
|
+ mol |
|
+ """` |
|
$(document).ready(function () { |
|
let element = $("#container"); |
|
let config = { backgroundColor: "white" }; |
|
let viewer = $3Dmol.createViewer(element, config); |
|
viewer.addModel(pdb, "pdb"); |
|
viewer.getModel(0).setStyle({chain: "H"}, {cartoon:{color:"red"}}); |
|
viewer.getModel(0).setStyle({chain: "L"}, {cartoon:{color:"blue"}}); |
|
viewer.addSurface($3Dmol.SurfaceType.VDW, {opacity: 0.4, color: "lightblue"}); |
|
viewer.zoomTo(); |
|
viewer.render(); |
|
viewer.zoom(0.8, 2000); |
|
}) |
|
</script> |
|
</body></html>""" |
|
) |
|
|
|
return f"""<iframe style="width: 100%; height: 600px" 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> |
|
<div style="position: absolute; top: 10px; right: 10px; background-color: white; padding: 10px; border: 1px solid black;"> |
|
<div style="width: 20px; height: 20px; background-color: red; display: inline-block;"></div> |
|
<span style="margin-left: 3px;">Heavy chain</span><br> |
|
<div style="width: 20px; height: 20px; background-color: blue; display: inline-block;"></div> |
|
<span style="margin-left: 3px;">Light chain</span> |
|
<div style="display: flex; justify-content: space-between; margin-top: 5px;"> |
|
<a href="data:application/octet-stream;base64,{base64_content}" download="structure.pdb">Download File</a> |
|
</div> |
|
</div> |
|
""" |
|
|
|
def validate(seq): |
|
alphabet = set('ACDEFGHIKLMNPQRSTVWY') |
|
leftover = set(seq.upper()) - alphabet |
|
return not leftover |
|
|
|
def pred_seq(h_seq, l_seq): |
|
h_seq = h_seq.upper().replace(' ', '') |
|
l_seq = l_seq.upper().replace(' ', '') |
|
|
|
print("Logs","___"*10) |
|
print(h_seq) |
|
print(l_seq) |
|
hostname = socket.gethostname() |
|
ip_address = socket.gethostbyname(hostname) |
|
print(f"Hostname: {hostname}") |
|
print(f"IP Address: {ip_address}") |
|
print("___"*10) |
|
|
|
h_is_valid = validate(h_seq) |
|
l_is_valid = validate(l_seq) |
|
if h_is_valid and l_is_valid: |
|
sequences = { |
|
"H": h_seq, |
|
"L": l_seq |
|
} |
|
|
|
f_name = ''.join([random.choice("ACDEFGHIKLMNPQRSTVWY") for _ in range(15)]) |
|
|
|
pred_pdb = f"{f_name}.pdb" |
|
|
|
igfold = IgFoldRunner(num_models = 1) |
|
igfold.fold( |
|
pred_pdb, |
|
sequences=sequences, |
|
do_refine=False, |
|
do_renum=False |
|
) |
|
|
|
html = molecule(pred_pdb, h_seq, l_seq) |
|
|
|
else: |
|
html = "<p>ERROR! Not valid sequence</p>" |
|
return (html) |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown('# Antibody Structure Prediction') |
|
gr.Markdown("## Examples") |
|
html = """ |
|
<p> |
|
<strong>H-chain:</strong> <tt>QVQLKESGPGLVAPSQSLSITCTVSGFSLSSYGVSWVRQPPGKGLEWLGVIWGDGSTNYHPNLMSRLSISKDISKSQVLFKLNSLQTDDTATYYCVTLDYWGQGTSVTVSS</tt> |
|
<br/> |
|
<strong>L-chain: </strong> <tt>DVVMTQTPLSLPVSLGDQASISCRSSQSLVHRNGNTYLHWYLQKPGQSPKLLIYKVSNRFSGVPDRFSGSGSGTDFTLKISRVEAEDLGLYFCFQTTYVPNTFGGGTKLEIK</tt> |
|
</p> |
|
|
|
<p> |
|
<strong>H-chain:</strong> <tt>EVQLLESGGGLVQPGGSLRLSCAASGFTFSLYWMGWVRQAPGKGLEWVSSISSSGGVTPYADSVKGRFTISRDNSKNTLYLQMNSLRAEDTAVYYCAKLGELGWFDPWGQGTLVTVSS</tt> |
|
<br/> |
|
<strong>L-chain: </strong> <tt>DIQMTQSPSSLSASVGDRVTITCRASQGISSYLNWYQQKPGKAPKLLIYYASNLQNGVPSRFSGSGSGTDFTLTISSLQPEDFATYYCQQSYSTPLTFGGGTKVEIK</tt> |
|
</p> |
|
|
|
<p> |
|
<strong>H-chain:</strong> <tt>EVQLVQSGPEVKKPGTSVKVSCKASGFTFMSSAVQWVRQARGQRLEWIGWIVIGSGNTNYAQKFQERVTITRDMSTSTAYMELSSLRSEDTAVYYCAAPYCSSISCNDGFDIWGQGTMVTVS</tt> |
|
<br/> |
|
<strong>L-chain: </strong> <tt>EIVLTQSPATLSLSPGERATLSCRASQSVSSYLAWYQQKPGQAPRLLIYDASNRATGIPARFSGSGSGTDFTLTISSLEPEDFAVYYCQQRSNWPITFGQGTKLEIK</tt> |
|
</p> |
|
""" |
|
gr.HTML(value = html) |
|
h_text = gr.Textbox(lines=5, label="Heavy chain") |
|
l_text = gr.Textbox(lines=5, label="Light chain") |
|
btn = gr.Button(value="Submit") |
|
btn.click(pred_seq, inputs=[h_text, l_text], outputs=gr.HTML()) |
|
if __name__ == "__main__": |
|
demo.launch() |
|
|