File size: 3,068 Bytes
1ab89f3
 
 
 
0ead2b3
 
2036f44
1ab89f3
 
5b16fe3
 
0ead2b3
5b16fe3
0ead2b3
29599c4
 
 
e2396c3
 
5b16fe3
1ab89f3
 
5b16fe3
29599c4
2036f44
 
 
 
 
 
 
 
 
 
 
 
e2396c3
 
 
 
 
 
2036f44
29599c4
1ab89f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97b425a
5b16fe3
 
 
 
 
 
614d786
5b16fe3
 
 
1ab89f3
 
 
5b16fe3
 
1a7c51c
1ab89f3
7d4eb19
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
import py3Dmol
import requests
from pathlib import Path

import Bio.PDB

def display_pdb_by_pdb(pdb_string,pdb_filename,color_map="pLDDT"):
    # function to display pdb in py3dmol
    # ref: https://huggingface.co/spaces/AIGE/A_B

    #get pdb column values
    p = Bio.PDB.PDBParser()
    structure = p.get_structure('myStructureName', pdb_filename)
    ids = [a.get_id() for a in structure.get_atoms()]
    pLDDTs = [a.get_bfactor() for a in structure.get_atoms()]
    
    plddt_bands = ['#FF7D45','#FFDB13','#65CBF3','#0053D6']
    style = "cartoon"
    
    #plot 3D structure
    view = py3Dmol.view(width=500, height=500)
    view.setBackgroundColor('black');
    view.addModel(pdb_string, "pdb")

    if color_map == "spectrum":
        view.setStyle({'cartoon': {'color': 'spectrum'}})
    else:
        for i,plddt in enumerate(pLDDTs):
            if plddt >0.90:
                color = plddt_bands[3]
            elif plddt >0.70:
                color = plddt_bands[2]
            elif plddt >0.50:
                color = plddt_bands[1]
            else:
                color = plddt_bands[0]
            '''    
            if style == "cartoon" and show_sidechains == True:
                view.setStyle({'model': -1, 'serial': i+1}, {style: {'color': color},"stick":{}})
            else:
               view.setStyle({'model': -1, 'serial': i+1}, {style: {'color': color}})
            '''
            view.setStyle({'model': -1, 'serial': i+1}, {style:{'color': color}})

    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 = None #pdb = str = None

    #save a pdb format file
    name = sequence[:3] + sequence[-3:]  #combine the firt and last 3 AAs of sequence as a filename.
    outpath = (
        Path.cwd() / f"PDB-{name}.pdb")
    with open(outpath.name, "w") as f:
        f.write(pdb_str)
    outpath_str = str(outpath)
    
    return pdb_str, outpath_str

def plot_struc(sequence):

    pdb_string, pdb_filename = get_pdb(sequence) 
    
    html_view = display_pdb_by_pdb(pdb_string, pdb_filename, color_map = "spectrum")

    return pdb_filename, html_view