Spaces:
Sleeping
Sleeping
Update demo.py
Browse files
demo.py
CHANGED
@@ -24,17 +24,23 @@ tqdm.__init__ = partialmethod(tqdm.__init__, leave=False)
|
|
24 |
|
25 |
import streamlit as st
|
26 |
from stmol import *
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
29 |
btn = st.download_button(
|
30 |
label=description,
|
31 |
data=file,
|
32 |
-
file_name=
|
33 |
)
|
|
|
|
|
|
|
34 |
import pandas as pd
|
35 |
def display(output,style,resn):
|
36 |
# imformation
|
37 |
-
protein=Protein.from_PDB(output
|
38 |
st.subheader("Protein Information:")
|
39 |
st.write(f"Device: {protein.device}")
|
40 |
st.write(f"Protein Length: {len(protein)} residues")
|
@@ -54,16 +60,19 @@ def display(output,style,resn):
|
|
54 |
# 使用 stmol 展示蛋白质结构
|
55 |
st.subheader("Protein Structure:")
|
56 |
traj_output = output.replace(".pdb", "_trajectory.pdb")
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
60 |
obj = render_pdb_resn(obj ,resn_lst =resn)
|
61 |
showmol(obj, width=1800)
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
-
def render(protein, trajectories, output="./output
|
67 |
protein.to_PDB(output)
|
68 |
traj_output = output.replace(".pdb", "_trajectory.pdb")
|
69 |
trajectories["trajectory"].to_PDB(traj_output)
|
@@ -77,27 +86,26 @@ locale.getpreferredencoding = lambda: "UTF-8"
|
|
77 |
from chroma import Chroma, Protein, conditioners
|
78 |
from chroma.models import graph_classifier, procap
|
79 |
from chroma.utility.api import register_key
|
80 |
-
from
|
81 |
|
82 |
register_key(api_key)
|
83 |
-
|
|
|
|
|
84 |
with contextlib.redirect_stdout(None):
|
85 |
chroma = Chroma(device=device)
|
86 |
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
def proteinSample(length,steps,output):
|
92 |
protein, trajectories = chroma.sample(
|
93 |
chain_lengths=[length], steps=steps, full_output=True,
|
94 |
)
|
95 |
render(protein, trajectories, output=output)
|
96 |
-
def
|
97 |
-
st.sidebar.title("
|
98 |
-
st.sidebar.header("
|
99 |
-
length=st.sidebar.number_input("
|
100 |
-
steps_protein=st.sidebar.number_input("steps",min_value=150,max_value=500,step=50,value=200,key='steps_protein')
|
101 |
|
102 |
output="./output/protein.pdb"
|
103 |
if st.sidebar.button("Run Code with Button",key="protein"):
|
@@ -116,14 +124,14 @@ def complexSample(chain1_length,chain2_length,chain3_length,chain4_length,steps,
|
|
116 |
)
|
117 |
render(protein, trajectories, output=output)
|
118 |
def complexSampleDemo(style,resn):
|
119 |
-
st.sidebar.title("
|
120 |
-
st.sidebar.header("
|
121 |
st.caption("Given the lengths of individual chains, Chroma can generate a complex.")
|
122 |
chain1_length=st.sidebar.number_input("chain1_length,step=10",min_value=100,max_value=500,step=10,value=400,key='chain1_length')
|
123 |
chain2_length=st.sidebar.number_input("chain2_length,step=10",min_value=0,max_value=200,step=10,value=100,key='chain2_length')
|
124 |
chain3_length=st.sidebar.number_input("chain3_length,step=1",min_value=0,max_value=200,step=10,value=100,key='chain3_length')
|
125 |
chain4_length=st.sidebar.number_input("chain4_length,step=1",min_value=0,max_value=200,step=10,value=100,key='chain4_length')
|
126 |
-
steps_complex=st.sidebar.number_input("steps",min_value=150,max_value=500,step=50,value=200,key='steps_complex')
|
127 |
|
128 |
output="./output/complex.pdb"
|
129 |
if st.sidebar.button("Run Code with Button",key="complex"):
|
@@ -144,12 +152,12 @@ def symmetricSample(subunit_size,conditioner,output):
|
|
144 |
)
|
145 |
render(symmetric_protein, trajectories, output=output)
|
146 |
def symmetricSampleDemo(style,resn):
|
147 |
-
st.sidebar.title("
|
148 |
-
st.sidebar.header(" Symmetry")
|
149 |
st.caption(" Specify the desired symmetry type and the size of a single subunit.")
|
150 |
output="./output/symmetric_protein.pdb"
|
151 |
symmetry_group=st.sidebar.text_input('symmetry_group:@param ["C_2", "C_3", "C_4", "C_5", "C_6", "C_7", "C_8", "D_2", "D_3", "D_4", "D_5", "D_6", "D_7", "D_8", "T", "O", "I"]',"C_7")
|
152 |
-
subunit_size=st.sidebar.number_input("subunit_size,step=5",min_value=10,max_value=150,step=5,value=100,key='subunit_size')
|
153 |
knbr=st.sidebar.number_input("knbr,step=1",min_value=1,max_value=10,step=1,value=2,key='knbr')
|
154 |
conditioner = conditioners.SymmetryConditioner(
|
155 |
G=symmetry_group, num_chain_neighbors=knbr
|
@@ -168,16 +176,16 @@ def shapeSample(length,conditioner,output):
|
|
168 |
|
169 |
render(shaped_protein, trajectories, output=output)
|
170 |
def shapeSampleDemo(style,resn):
|
171 |
-
st.sidebar.title("
|
172 |
-
st.sidebar.header(" Shape")
|
173 |
-
st.caption("
|
174 |
|
175 |
output="./output/shaped_protein.pdb"
|
176 |
-
character=st.sidebar.text_input('character
|
177 |
if len(character) > 1:
|
178 |
character = character[:1]
|
179 |
print(f"Keeping only first character ({character})!")
|
180 |
-
length=st.sidebar.number_input('
|
181 |
|
182 |
if st.sidebar.button("Run Code with Button",key="shape"):
|
183 |
letter_point_cloud = letter_to_point_cloud(character)
|
@@ -197,13 +205,13 @@ def foldSample(length,conditioner,output):
|
|
197 |
)
|
198 |
render(cath_conditioned_protein, trajectories, output=output)
|
199 |
def foldSampleDemo(style,resn):
|
200 |
-
st.sidebar.title("
|
201 |
-
st.sidebar.header("
|
202 |
st.caption("Input a [CATH number](https://cathdb.info/browse) to get chain-level conditioning, e.g. `3.40.50` for a Rossmann fold or `2` for mainly beta.")
|
203 |
|
204 |
output="./output/cath_conditioned_protein.pdb"
|
205 |
-
CATH=st.sidebar.text_input('CATH
|
206 |
-
length=st.sidebar.number_input('
|
207 |
|
208 |
proclass_model = graph_classifier.load_model("named:public", device=device)
|
209 |
conditioner = conditioners.ProClassConditioner("cath", CATH, model=proclass_model,device=device)
|
@@ -219,8 +227,8 @@ def ssSample(conditioner,SS,output):
|
|
219 |
)
|
220 |
render(ss_conditioned_protein, trajectories, output=output)
|
221 |
def ssSampleDemo(style,resn):
|
222 |
-
st.sidebar.title("
|
223 |
-
st.sidebar.header(" Secondary
|
224 |
st.caption("Enter a string to specify residue-level secondary structure conditioning: H = helix, E = strand, T = turn.")
|
225 |
|
226 |
output="./output/ss_conditioned_protein.pdb"
|
@@ -251,8 +259,8 @@ def substructureSample(protein,conditioner,output):
|
|
251 |
)
|
252 |
render(infilled_protein, trajectories, output=output)
|
253 |
def substructureSampleDemo(style,resn):
|
254 |
-
st.sidebar.title("
|
255 |
-
st.sidebar.header(" Substructure ")
|
256 |
st.caption("Enter a PDB ID and a selection string corresponding to designable positions.")
|
257 |
st.caption("Using a substructure conditioner, Chroma can design at these positions while holding the rest of the structure fixed.")
|
258 |
st.caption("The default selection cuts the protein in half and fills it in.")
|
@@ -293,4 +301,81 @@ def substructureSampleDemo(style,resn):
|
|
293 |
substructureSample(protein,conditioner,output)
|
294 |
display(output,style,resn)
|
295 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
import streamlit as st
|
26 |
from stmol import *
|
27 |
+
|
28 |
+
def download_callback(newFileName):
|
29 |
+
st.success(f"{newFileName}: successfully downloaded ")
|
30 |
+
def download(outputFile,newFileName,description):
|
31 |
+
with open(outputFile, "rb") as file:
|
32 |
btn = st.download_button(
|
33 |
label=description,
|
34 |
data=file,
|
35 |
+
file_name=newFileName,
|
36 |
)
|
37 |
+
|
38 |
+
|
39 |
+
|
40 |
import pandas as pd
|
41 |
def display(output,style,resn):
|
42 |
# imformation
|
43 |
+
protein=Protein.from_PDB(output)
|
44 |
st.subheader("Protein Information:")
|
45 |
st.write(f"Device: {protein.device}")
|
46 |
st.write(f"Protein Length: {len(protein)} residues")
|
|
|
60 |
# 使用 stmol 展示蛋白质结构
|
61 |
st.subheader("Protein Structure:")
|
62 |
traj_output = output.replace(".pdb", "_trajectory.pdb")
|
63 |
+
|
64 |
+
protein_newName = st.text_input("The specified file name. Default is {}.".format(output[output.rfind("/") + 1:])+"Please press [Enter] to confirm the change before download.", value=output[output.rfind("/") + 1:], key='protein_newName')
|
65 |
+
download(output,protein_newName,"Download sample")
|
66 |
+
traj_newName = st.text_input("The specified file name. Default is {}.".format(traj_output[traj_output.rfind("/") + 1:])+"Please press [Enter] to confirm the change before download.", value=traj_output[traj_output.rfind("/") + 1:], key='traj_newName')
|
67 |
+
download(traj_output,traj_newName,"Download trajectory")
|
68 |
+
if resn !='*':
|
69 |
obj = render_pdb_resn(obj ,resn_lst =resn)
|
70 |
showmol(obj, width=1800)
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
+
def render(protein, trajectories, output="./output/protein.pdb"):
|
76 |
protein.to_PDB(output)
|
77 |
traj_output = output.replace(".pdb", "_trajectory.pdb")
|
78 |
trajectories["trajectory"].to_PDB(traj_output)
|
|
|
86 |
from chroma import Chroma, Protein, conditioners
|
87 |
from chroma.models import graph_classifier, procap
|
88 |
from chroma.utility.api import register_key
|
89 |
+
from chroma.utility.chroma import letter_to_point_cloud, plane_split_protein
|
90 |
|
91 |
register_key(api_key)
|
92 |
+
|
93 |
+
# device = 'cuda:2' if torch.cuda.is_available() else 'cpu'
|
94 |
+
device='cuda:0'
|
95 |
with contextlib.redirect_stdout(None):
|
96 |
chroma = Chroma(device=device)
|
97 |
|
98 |
|
|
|
|
|
|
|
99 |
def proteinSample(length,steps,output):
|
100 |
protein, trajectories = chroma.sample(
|
101 |
chain_lengths=[length], steps=steps, full_output=True,
|
102 |
)
|
103 |
render(protein, trajectories, output=output)
|
104 |
+
def GenerateProteinDemo(style,resn):
|
105 |
+
#st.sidebar.title("Unconditional Generation")
|
106 |
+
st.sidebar.header("Generate a Protein Backbone")
|
107 |
+
length=st.sidebar.number_input("chain_length:The lengths of the protein chains.Default is [160],step=10.",min_value=50,max_value=250,step=10,value=160,key='length')
|
108 |
+
steps_protein=st.sidebar.number_input("sde_steps:The number of integration steps for the SDE.Default is 200,step=50.",min_value=150,max_value=500,step=50,value=200,key='steps_protein')
|
109 |
|
110 |
output="./output/protein.pdb"
|
111 |
if st.sidebar.button("Run Code with Button",key="protein"):
|
|
|
124 |
)
|
125 |
render(protein, trajectories, output=output)
|
126 |
def complexSampleDemo(style,resn):
|
127 |
+
#st.sidebar.title("Generate a Protein Complex")
|
128 |
+
st.sidebar.header("Generate a Protein Complex")
|
129 |
st.caption("Given the lengths of individual chains, Chroma can generate a complex.")
|
130 |
chain1_length=st.sidebar.number_input("chain1_length,step=10",min_value=100,max_value=500,step=10,value=400,key='chain1_length')
|
131 |
chain2_length=st.sidebar.number_input("chain2_length,step=10",min_value=0,max_value=200,step=10,value=100,key='chain2_length')
|
132 |
chain3_length=st.sidebar.number_input("chain3_length,step=1",min_value=0,max_value=200,step=10,value=100,key='chain3_length')
|
133 |
chain4_length=st.sidebar.number_input("chain4_length,step=1",min_value=0,max_value=200,step=10,value=100,key='chain4_length')
|
134 |
+
steps_complex=st.sidebar.number_input("sde_steps:The number of integration steps for the SDE.Default is 200,step=50.",min_value=150,max_value=500,step=50,value=200,key='steps_complex')
|
135 |
|
136 |
output="./output/complex.pdb"
|
137 |
if st.sidebar.button("Run Code with Button",key="complex"):
|
|
|
152 |
)
|
153 |
render(symmetric_protein, trajectories, output=output)
|
154 |
def symmetricSampleDemo(style,resn):
|
155 |
+
#st.sidebar.title("Generate a Symmetric Protein Backbone")
|
156 |
+
st.sidebar.header("Conditional Generation on Symmetry")
|
157 |
st.caption(" Specify the desired symmetry type and the size of a single subunit.")
|
158 |
output="./output/symmetric_protein.pdb"
|
159 |
symmetry_group=st.sidebar.text_input('symmetry_group:@param ["C_2", "C_3", "C_4", "C_5", "C_6", "C_7", "C_8", "D_2", "D_3", "D_4", "D_5", "D_6", "D_7", "D_8", "T", "O", "I"]',"C_7")
|
160 |
+
subunit_size=st.sidebar.number_input("subunit_size:the size of a single subunit.Default is 100,step=5.",min_value=10,max_value=150,step=5,value=100,key='subunit_size')
|
161 |
knbr=st.sidebar.number_input("knbr,step=1",min_value=1,max_value=10,step=1,value=2,key='knbr')
|
162 |
conditioner = conditioners.SymmetryConditioner(
|
163 |
G=symmetry_group, num_chain_neighbors=knbr
|
|
|
176 |
|
177 |
render(shaped_protein, trajectories, output=output)
|
178 |
def shapeSampleDemo(style,resn):
|
179 |
+
#st.sidebar.title("Generate a Shapped Protein Backbone")
|
180 |
+
st.sidebar.header("Conditional Generation on Shape")
|
181 |
+
st.caption("create a protein in the shape of a desired character of arbitrary length.")
|
182 |
|
183 |
output="./output/shaped_protein.pdb"
|
184 |
+
character=st.sidebar.text_input('character:a desired character for the shape of protein. @param {type:"string"}','G',key='character')
|
185 |
if len(character) > 1:
|
186 |
character = character[:1]
|
187 |
print(f"Keeping only first character ({character})!")
|
188 |
+
length=st.sidebar.number_input('chain_length:The lengths of the protein chains.Default is 500,step=100.',min_value=100,max_value=1500,step=100,value=500,key='length_shape')
|
189 |
|
190 |
if st.sidebar.button("Run Code with Button",key="shape"):
|
191 |
letter_point_cloud = letter_to_point_cloud(character)
|
|
|
205 |
)
|
206 |
render(cath_conditioned_protein, trajectories, output=output)
|
207 |
def foldSampleDemo(style,resn):
|
208 |
+
#st.sidebar.title("Generate a Chain-level Conditioned Protein")
|
209 |
+
st.sidebar.header("Conditional Generation on Chain-level Properties")
|
210 |
st.caption("Input a [CATH number](https://cathdb.info/browse) to get chain-level conditioning, e.g. `3.40.50` for a Rossmann fold or `2` for mainly beta.")
|
211 |
|
212 |
output="./output/cath_conditioned_protein.pdb"
|
213 |
+
CATH=st.sidebar.text_input('CATH:protein domain annotations from <https://www.cathdb.info/>. Annotation examples include 2, 2.40, 2.40.155.','3.40.50',key='CATH')
|
214 |
+
length=st.sidebar.number_input('chain_length:The lengths of the protein chains.Default is 130,step=10.',min_value=50,max_value=250,step=10,value=130,key='length_fold')
|
215 |
|
216 |
proclass_model = graph_classifier.load_model("named:public", device=device)
|
217 |
conditioner = conditioners.ProClassConditioner("cath", CATH, model=proclass_model,device=device)
|
|
|
227 |
)
|
228 |
render(ss_conditioned_protein, trajectories, output=output)
|
229 |
def ssSampleDemo(style,resn):
|
230 |
+
#st.sidebar.title("Generate a Secondary Structure Conditioned Protein")
|
231 |
+
st.sidebar.header(" Conditional Generation on Secondary Structure Properties")
|
232 |
st.caption("Enter a string to specify residue-level secondary structure conditioning: H = helix, E = strand, T = turn.")
|
233 |
|
234 |
output="./output/ss_conditioned_protein.pdb"
|
|
|
259 |
)
|
260 |
render(infilled_protein, trajectories, output=output)
|
261 |
def substructureSampleDemo(style,resn):
|
262 |
+
st.sidebar.title("Generate a Sub-Structure Conditioned Protein")
|
263 |
+
#st.sidebar.header(" Conditional Generation on Substructure Properties")
|
264 |
st.caption("Enter a PDB ID and a selection string corresponding to designable positions.")
|
265 |
st.caption("Using a substructure conditioner, Chroma can design at these positions while holding the rest of the structure fixed.")
|
266 |
st.caption("The default selection cuts the protein in half and fills it in.")
|
|
|
301 |
substructureSample(protein,conditioner,output)
|
302 |
display(output,style,resn)
|
303 |
|
304 |
+
def natureLanguageSample(conditioner,output):
|
305 |
+
caption_conditioned_protein,trajectories = chroma.sample(steps=200, chain_lengths=[110], conditioner=conditioner)
|
306 |
+
render(caption_conditioned_protein, trajectories, output=output)
|
307 |
+
|
308 |
+
def natureLanguageSampleDemo(style,resn):
|
309 |
+
st.sidebar.title("Generate a Caption Guided Protein")
|
310 |
+
st.caption("Here, we demonstrate backbone generation conditioned on natural language prompts.")
|
311 |
+
st.caption(" The sampling is guided by the gradients of a structure to text model.")
|
312 |
+
CAPTION=st.sidebar.text_input('a caption:natural language prompts.',value='Crystal structure of SH2 domain',key='caption')
|
313 |
+
torch.manual_seed(0)
|
314 |
+
conditioner = conditioners.ProCapConditioner(CAPTION, -1).to(device)
|
315 |
+
output='./output/caption_conditioned_protein.pdb'
|
316 |
+
if st.sidebar.button("Run Code with Button",key="substructure"):
|
317 |
+
natureLanguageSample(conditioner,output)
|
318 |
+
|
319 |
+
display(output,style,resn)
|
320 |
|
321 |
+
# Combining Symmetry and Secondary Structure
|
322 |
+
def cSSStructureSample(composedConditioner,output):
|
323 |
+
symm_beta_protein,trajectories = chroma.sample(chain_lengths=[100],
|
324 |
+
conditioner=composedConditioner,
|
325 |
+
langevin_factor=8,
|
326 |
+
inverse_temperature=8,
|
327 |
+
sde_func="langevin",
|
328 |
+
steps=500,full_output=True,)
|
329 |
+
render(symm_beta_protein,trajectories,output=output)
|
330 |
+
|
331 |
+
def cSSStructureSampleDemo(style,resn):
|
332 |
+
st.sidebar.title("Generate a Combined Symmetry and Secondary Structure Protein")
|
333 |
+
st.caption("In this scenario, we initially apply guidance for secondary structure to condition the content accordingly.")
|
334 |
+
st.caption("This is followed by incorporating Cyclic symmetry.")
|
335 |
+
st.caption("This approach involves adding a secondary structure classifier to conditionally sample an Asymmetric unit (AU) that is beta-rich, followed by symmetrization.")
|
336 |
+
output='./output/symm_beta.pdb'
|
337 |
+
CATH=st.sidebar.text_input('CATH:protein domain annotations from <https://www.cathdb.info/>. Annotation examples include 2, 2.40, 2.40.155.','2',key='CATH_beta')
|
338 |
+
beta = conditioners.ProClassConditioner('cath', CATH, weight=5, max_norm=20)
|
339 |
+
c_symmetry = conditioners.SymmetryConditioner(G="C_3", num_chain_neighbors=2)
|
340 |
+
composed_cond = conditioners.ComposedConditioner([beta, c_symmetry])
|
341 |
+
if st.sidebar.button("Run Code with Button",key="substructure"):
|
342 |
+
cSSStructureSample(composed_cond,output)
|
343 |
+
|
344 |
+
display(output,style,resn)
|
345 |
+
|
346 |
+
# Merging Symmetry and Substructure
|
347 |
+
def mSSubstructureSample(composedCondtioner,output):
|
348 |
+
protein, trajectories = chroma.sample(
|
349 |
+
protein_init=protein,
|
350 |
+
conditioner=composedCondtioner,
|
351 |
+
langevin_factor=4.0,
|
352 |
+
langevin_isothermal=True,
|
353 |
+
inverse_temperature=8.0,
|
354 |
+
sde_func='langevin',
|
355 |
+
steps=500,
|
356 |
+
full_output=True,
|
357 |
+
)
|
358 |
+
render(protein,trajectories,output)
|
359 |
+
|
360 |
+
def mSSubstructureSampleDemo(style,resn):
|
361 |
+
st.sidebar.title("Generate a Merged Symmetry and Substructure Protein")
|
362 |
+
st.caption("Here, our goal is to construct symmetric assemblies from a single-chain protein, partially redesigning it to merge three identical AUs into a Cyclic complex.")
|
363 |
+
st.caption("We begin by defining the backbones targeted for redesign and then reposition the AU to prevent clashes during symmetrization.")
|
364 |
+
st.caption("This is followed by the symmetrization operation itself.")
|
365 |
+
output='./output/mss_protein.pdb'
|
366 |
+
pdb_id=st.sidebar.text_input("pdb_id@param ['5SV5', '6QAZ', '3BDI'] {allow-input:true}",'3BDI',key='pdb_id_mss')
|
367 |
+
protein = Protein(pdb_id, canonicalize=True, device=device)
|
368 |
+
# regenerate residues with X coord < 25 A and y coord < 25 A
|
369 |
+
substruct_conditioner = conditioners.SubstructureConditioner(
|
370 |
+
protein, backbone_model=chroma.backbone_network, selection="x < 25 and y < 25")
|
371 |
+
|
372 |
+
# C_3 symmetry
|
373 |
+
c_symmetry = conditioners.SymmetryConditioner(G="C_3", num_chain_neighbors=3)
|
374 |
+
|
375 |
+
# Composing
|
376 |
+
composed_cond = conditioners.ComposedConditioner([substruct_conditioner, c_symmetry])
|
377 |
+
|
378 |
+
if st.sidebar.button("Run Code with Button",key="substructure"):
|
379 |
+
mSSubstructureSample(composed_cond,output)
|
380 |
+
|
381 |
+
display(output,style,resn)
|