| import gradio as gr | |
| from igfold import IgFoldRunner | |
| import os | |
| import random | |
| import base64 | |
| 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): | |
| 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 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({}, {cartoon:{color:"spectrum"}}); | |
| viewer.addSurface($3Dmol.SurfaceType.VDW, {opacity: 0.7, 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> | |
| <a href="data:application/octet-stream;base64,{base64_content}" download="structure.pdb">Download File</a> | |
| """ | |
| 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(h_seq) | |
| 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() | |
| igfold.fold( | |
| pred_pdb, | |
| sequences=sequences, | |
| do_refine=False, | |
| do_renum=False, | |
| ) | |
| html = molecule(pred_pdb) | |
| else: | |
| html = "<p>ERROR! Not valid sequence</p>" | |
| return (html) | |
| h_chain_example = "EVQLVQSGPEVKKPGTSVKVSCKASGFTFMSSAVQWVRQARGQRLEWIGWIVIGSGNTNYAQKFQERVTITRDMSTSTAYMELSSLRSEDTAVYYCAAPYCSSISCNDGFDIWGQGTMVTVS" | |
| l_chain_example = "DVVMTQTPFSLPVSLGDQASISCRSSQSLVHSNGNTYLHWYLQKPGQSPKLLIYKVSNRFSGVPDRFSGSGSGTDFTLKISRVEAEDLGVYFCSQSTHVPYTFGGGTKLEIK" | |
| inputs = [gr.Textbox(lines=5, label="Heavy chain"), | |
| gr.Textbox(lines=5, label="Light chain") | |
| ] | |
| iface = gr.Interface(fn=pred_seq, | |
| inputs=inputs, | |
| outputs=gr.HTML(), | |
| title="Antibody structure prediction") | |
| iface.launch() |