folding-studio-demo / molecule.py
jfaustin's picture
refact: remove useless stuff
86d28da
raw
history blame
12.1 kB
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
]
)
logger = logging.getLogger(__name__)
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, lenSeqs, num_res, selectedResidues, allSeqs, sequences
):
options = ""
pred_mol = "["
seqdata = "{"
selected = "selected"
for i in range(lenSeqs):
seqdata += (
str(i)
+ ': { "score": '
+ str(sequences[i]["Score"])
+ ', "rmsd": '
+ str(sequences[i]["RMSD"])
+ ', "recovery": '
+ str(sequences[i]["Recovery"])
+ ', "plddt": '
+ str(sequences[i]["Mean pLDDT"])
+ ', "seq":"'
+ allSeqs[i]
+ '"}'
)
options += f'<option {selected} value="{i}">sequence {i} </option>' # RMSD {sequences[i]["RMSD"]}, score {sequences[i]["Score"]}, recovery {sequences[i]["Recovery"]} pLDDT {sequences[i]["Mean pLDDT"]}
p = input_pdb
pred_mol += f"`{read_mol(p)}`"
selected = ""
if i != lenSeqs - 1:
pred_mol += ","
seqdata += ","
pred_mol += "]"
seqdata += "}"
logger.info(seqdata)
x = (
"""<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/flowbite.min.css" />
<style>
body{
font-family:sans-serif
}
.mol-container {
width: 100%;
height: 700px;
position: relative;
}
.space-x-2 > * + *{
margin-left: 0.5rem;
}
.p-1{
padding:0.5rem;
}
.w-4{
width:1rem;
}
.h-4{
height:1rem;
}
.mt-4{
margin-top:1rem;
}
.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 class="font-mono bg-gray-100 py-3 px-2 font-sm rounded">
<p id="seqText" class="max-w-4xl font-xs block" style="word-break: break-all;">
</p>
</div>
<div id="container" class="mol-container"></div>
<div class="flex items-center">
<div class="px-4 pt-2">
<label for="sidechain" class="relative inline-flex items-center mb-4 cursor-pointer ">
<input id="sidechain" type="checkbox" class="sr-only peer">
<div class="w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
<span class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">Show side chains</span>
</label>
</div>
<button type="button" class="text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-gray-600 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:bg-gray-700 mr-2 mb-2" id="download">
<svg class="w-6 h-6 mr-2 -ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
Download predicted structure
</button>
</div>
<div class="text-sm">
<div class="text-sm flex items-start">
<div class="w-1/2">
<div class="font-medium mt-4 flex items-center space-x-2"><b>Boltz-1 model of redesigned sequence</b></div>
<div>Boltz-1 model confidence:</div>
<div class="flex space-x-2 py-1"><span class="w-4 h-4" style="background-color: rgb(0, 83, 214);">&nbsp;</span><span class="legendlabel">Very high
(pLDDT &gt; 90)</span></div>
<div class="flex space-x-2 py-1"><span class="w-4 h-4" style="background-color: rgb(101, 203, 243);">&nbsp;</span><span class="legendlabel">Confident
(90 &gt; pLDDT &gt; 70)</span></div>
<div class="flex space-x-2 py-1"><span class="w-4 h-4" style="background-color: rgb(255, 219, 19);">&nbsp;</span><span class="legendlabel">Low (70 &gt;
pLDDT &gt; 50)</span></div>
<div class="flex space-x-2 py-1"><span class="w-4 h-4" style="background-color: rgb(255, 125, 69);">&nbsp;</span><span class="legendlabel">Very low
(pLDDT &lt; 50)</span></div>
<div class="row column legendDesc"> Boltz-1 produces a per-residue confidence
score (pLDDT) between 0 and 100. Some regions below 50 pLDDT may be unstructured in isolation.
</div>
</div>
</div>
<script>
function drawStructures(i, selectedResidues) {
$("#rmsd").text(seqs[i]["rmsd"])
$("#seqText").text(seqs[i]["seq"])
$("#seqrmsd").text(seqs[i]["rmsd"])
$("#id").text(i)
$("#score").text(seqs[i]["score"])
$("#recovery").text(seqs[i]["recovery"])
$("#plddt").text(seqs[i]["plddt"])
viewer = $3Dmol.createViewer(element, config);
viewer.addModel(data[i], "pdb");
viewer.getModel(0).setStyle({}, { cartoon: { colorfunc: colorAlpha } });
viewer.zoomTo();
viewer.render();
viewer.zoom(0.8, 2000);
viewer.getModel(0).setHoverable({}, true,
function (atom, viewer, event, container) {
if (!atom.label) {
atom.label = viewer.addLabel(atom.resn + atom.resi + " pLDDT=" + atom.b, { position: atom, backgroundColor: "mintcream", fontColor: "black" });
}
},
function (atom, viewer) {
if (atom.label) {
viewer.removeLabel(atom.label);
delete atom.label;
}
}
);
}
let viewer = null;
let voldata = null;
let element = null;
let config = null;
let currentIndex = 0;
let seqs = """
+ seqdata
+ """
let data = """
+ pred_mol
+ """
var selectedResidues = """
+ f"{selectedResidues}"
+ """
//AlphaFold code from https://gist.github.com/piroyon/30d1c1099ad488a7952c3b21a5bebc96
let colorAlpha = function (atom) {
if (atom.b < 50) {
return "OrangeRed";
} else if (atom.b < 70) {
return "Gold";
} else if (atom.b < 90) {
return "MediumTurquoise";
} else {
return "Blue";
}
};
let colors = {}
for (let i=0; i<"""
+ str(num_res)
+ """;i++){
if (selectedResidues.includes(i)){
colors[i]="hotpink"
}else{
colors[i]="lightgray"
}}
let colorFixedSidechain = function(atom){
if (selectedResidues.includes(atom.resi)){
return "hotpink"
}else if (atom.elem == "O"){
return "red"
}else if (atom.elem == "N"){
return "blue"
}else if (atom.elem == "S"){
return "yellow"
}else{
return "lightgray"
}
}
$(document).ready(function () {
element = $("#container");
config = { backgroundColor: "white" };
//viewer.ui.initiateUI();
drawStructures(currentIndex, selectedResidues)
$("#sidechain").change(function () {
if (this.checked) {
BB = ["C", "O", "N"]
if ($("#startstructure").prop("checked")) {
viewer.getModel(0).setStyle( {"and": [{resn: ["GLY", "PRO"], invert: true},{atom: BB, invert: true},]},{stick: {colorscheme: "WhiteCarbon", radius: 0.3}, cartoon: { colorfunc: colorAlpha }});
}else{
viewer.getModel(0).setStyle( {"and": [{resn: ["GLY", "PRO"], invert: true},{atom: BB, invert: true},]},{stick: {colorscheme: "WhiteCarbon", radius: 0.3}, cartoon: { colorfunc: colorAlpha }});
}
viewer.render()
} else {
if ($("#startstructure").prop("checked")) {
viewer.getModel(0).setStyle({cartoon: { colorfunc: colorAlpha }});
}else{
viewer.getModel(0).setStyle({cartoon: { colorfunc: colorAlpha }});
}
viewer.render()
}
});
$("#seq").change(function () {
drawStructures(this.value, selectedResidues)
currentIndex = this.value
$("#sidechain").prop( "checked", false );
$("#startstructure").prop( "checked", true );
});
$("#startstructure").change(function () {
if (this.checked) {
$("#sidechain").prop( "checked", false );
viewer.getModel(0).setStyle({}, { cartoon: { colorfunc: colorAlpha } });
viewer.render()
} else {
$("#sidechain").prop( "checked", false );
viewer.getModel(0).setStyle({}, { cartoon: { colorfunc: colorAlpha } });
viewer.render()
}
});
$("#download").click(function () {
download("outputs/out_" + currentIndex + "_aligned.pdb", data[currentIndex]);
})
});
function download(filename, text) {
var element = document.createElement("a");
element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
</script>
</body></html>"""
)
return x