File size: 8,330 Bytes
e33b6c9
 
 
 
 
 
 
34886ef
e33b6c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34886ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543ad41
 
 
 
 
 
 
 
 
 
 
e33b6c9
 
 
 
 
 
34886ef
e33b6c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BioBinding AI Vis</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/css/styles.css" rel="stylesheet">
</head>
<body>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-3 sidebar p-4">
            <h3 class="mb-4 text-primary">🧪 BioBind AI</h3>

            <form action="/predict" method="post">
                <div class="mb-3">
                    <label class="form-label fw-bold">Ligand (SMILES)</label>
                    <textarea class="form-control" name="smiles_ligand" rows="3" required>{{ smiles_ligand if smiles_ligand else 'COc1ccc(S(=O)(=O)N(CC(C)C)C[C@@H](O)[C@H](Cc2ccccc2)NC(=O)O[C@@H]2C[C@@H]3NC(=O)O[C@@H]3C2)cc1' }}</textarea>
                </div>

                <div class="mb-3">
                    <label class="form-label fw-bold">Protein Sequence</label>
                    <textarea class="form-control" name="sequence_protein" rows="3" required>{{ sequence_protein if sequence_protein else 'PQITLWKRPLVTIKIGGQLKEALLDTGADDTVIEEMSLPGRWKPKMIGGIGGFIKVRQYDQIIIEIAGHKAIGTVLVGPTPVNIIGRNLLTQIGATLNF' }}</textarea>
                </div>

                <button type="submit" class="btn btn-primary w-100 py-2">🔮 Calculate Binding</button>
            </form>

            {% if result_ready %}
            <hr class="my-4">
            <h5 class="mb-3">Top Important Atoms</h5>
            <div class="list-group">
                {% for atom in atom_list %}
                <div class="list-group-item d-flex justify-content-between align-items-center">
                    <span>
                        <span class="fw-bold">#{{ atom.id }}</span> {{ atom.symbol }}
                    </span>
                    <span>
                        <span class="badge bg-light text-dark border">{{ atom.score }}</span>
                        <span>{{ atom.icon }}</span>
                    </span>
                </div>
                {% endfor %}
            </div>
            {% endif %}
        </div>

        <div class="col-md-9 p-4">
            {% if result_ready %}
                <div class="card result-card p-4 text-center">
                    <h2 class="text-muted">Predicted Binding Affinity (pKd)</h2>
                    <div class="affinity-score">{{ affinity }}</div>
                </div>

                <div class="card shadow-sm mb-4">
                    <div class="card-header bg-light d-flex justify-content-between align-items-center">
                        <b>💊 Drug-Likeness (Lipinski's Rule of 5)</b>
                        <span class="badge bg-{{ lipinski.css_class }}" style="font-size: 0.9em;">
                            {{ lipinski.status_text }}
                        </span>
                    </div>
                    <div class="card-body p-0">
                        <table class="table table-bordered mb-0 text-center">
                            <thead class="table-light">
                                <tr>
                                    <th title="Molecular Weight (< 500 Da)">Mass (MW)</th>
                                    <th title="Lipophilicity (< 5)">LogP</th>
                                    <th title="H-Bond Donors (< 5)">H-Donors</th>
                                    <th title="H-Bond Acceptors (< 10)">H-Acceptors</th>
                                    <th title="Polar Surface Area (Permeability)">TPSA</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td class="{{ 'table-danger' if lipinski.MW > 500 else '' }}">{{ lipinski.MW }}</td>
                                    <td class="{{ 'table-danger' if lipinski.LogP > 5 else '' }}">{{ lipinski.LogP }}</td>
                                    <td class="{{ 'table-danger' if lipinski.HBD > 5 else '' }}">{{ lipinski.HBD }}</td>
                                    <td class="{{ 'table-danger' if lipinski.HBA > 10 else '' }}">{{ lipinski.HBA }}</td>
                                    <td>{{ lipinski.TPSA }} Ų</td>
                                </tr>
                            </tbody>
                        </table>

                        {% if lipinski.violations > 0 %}
                        <div class="p-2 text-center text-muted small bg-light border-top">
                            ⚠️ Violations: {{ lipinski.bad_params }}
                        </div>
                        {% endif %}
                    </div>
                </div>
                <div class="card shadow-sm mb-4 border-primary">
                    <div class="card-header bg-primary text-white d-flex align-items-center">
                        <svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="20" height="20" fill="currentColor" class="bi bi-stars me-2" viewBox="0 0 16 16">
                            <path d="M7.657 6.247c.11-.33.576-.33.686 0l.645 1.937a2.89 2.89 0 0 0 1.829 1.828l1.936.645c.33.11.33.576 0 .686l-1.937.645a2.89 2.89 0 0 0-1.828 1.829l-.645 1.936a.361.361 0 0 1-.686 0l-.645-1.937a2.89 2.89 0 0 0-1.828-1.828l-1.937-.645a.361.361 0 0 1 0-.686l1.937-.645a2.89 2.89 0 0 0 1.828-1.828l.645-1.937zM3.794 1.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387A1.734 1.734 0 0 0 4.593 5.69l-.387 1.162a.217.217 0 0 1-.412 0L3.407 5.69A1.734 1.734 0 0 0 2.31 4.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387A1.734 1.734 0 0 0 3.407 2.31l.387-1.162zM10.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a.968.968 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a.968.968 0 0 0-.732-.732L9.1 2.137a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L10.863.1z"/>
                        </svg>
                        <b>Gemini Analysis</b>
                    </div>
                    <div class="card-body bg-white">
                        {{ ai_explanation | safe }}
                    </div>
                </div>
                <div class="card result-card p-3">
                    <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
                        <li class="nav-item" role="presentation">
                            <button class="nav-link active" id="pills-py3dmol-tab" data-bs-toggle="pill" data-bs-target="#pills-py3dmol" type="button">🧬 Py3Dmol (High Contrast)</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" id="pills-ngl-tab" data-bs-toggle="pill" data-bs-target="#pills-ngl" type="button">🔬 NGLView (Interactive)</button>
                        </li>
                    </ul>

                    <div class="tab-content" id="pills-tabContent">
                        <div class="tab-pane fade show active" id="pills-py3dmol" role="tabpanel">
                            <div class="mol-container">
                                <iframe srcdoc="{{ html_py3dmol }}" style="width: 100%; height: 100%; border: none;"></iframe>
                            </div>
                        </div>

                        <div class="tab-pane fade" id="pills-ngl" role="tabpanel">
                            <div class="mol-container">
                                <iframe src="{{ url_ngl }}" style="width: 100%; height: 100%; border: none;"></iframe>
                            </div>
                        </div>
                    </div>
                </div>
            {% else %}
                <div class="d-flex align-items-center justify-content-center h-100 text-muted">
                    <div class="text-center">
                        <h1>🧬 Ready to Analyze</h1>
                        <p>Enter SMILES and Protein sequence on the left to start.</p>
                    </div>
                </div>
            {% endif %}
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>