Add hdf5 inference preprocessing

#4
Dockerfile CHANGED
@@ -2,6 +2,12 @@ FROM sab148/misato-dataset:latest
2
  USER root
3
  # Set up time zone.
4
 
 
 
 
 
 
 
5
  #RUN useradd -m -u 1000 user
6
  #USER user
7
  #ENV HOME=/home/user \
@@ -16,38 +22,10 @@ USER root
16
  #
17
  #CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
18
 
19
- # Set up a new user named "user" with user ID 1000
20
-
21
-
22
- RUN mkdir -p /maps
23
- WORKDIR /maps
24
- COPY maps/*pickle .
25
-
26
-
27
- RUN useradd -m -u 1000 user
28
-
29
- # Switch to the "user" user
30
- USER user
31
-
32
- # Set home to the user's home directory
33
- ENV HOME=/home/user \
34
- PATH=/home/user/.local/bin:$PATH
35
-
36
-
37
  WORKDIR $HOME/app
38
 
39
-
40
- #RUN chmod 777 /data
41
- #RUN useradd -m -u 1000 user
42
- #USER user
43
  # Copy the current directory contents into the container at $HOME/app setting the owner to the user
44
  COPY --chown=user . $HOME/app
45
-
46
- ENV AMBERHOME="/usr/bin/amber22"
47
- ENV PATH="$AMBERHOME/bin:$PATH"
48
- ENV PYTHONPATH="$AMBERHOME/lib/python3.8/site-packages"
49
-
50
- RUN pip install -r requirements.txt
51
  CMD ["python", "main.py"]
52
 
53
 
 
2
  USER root
3
  # Set up time zone.
4
 
5
+ RUN pip install gradio
6
+ RUN pip install requests
7
+ RUN pip install py3Dmol
8
+ RUN pip install biopython
9
+ RUN pip install pandas
10
+
11
  #RUN useradd -m -u 1000 user
12
  #USER user
13
  #ENV HOME=/home/user \
 
22
  #
23
  #CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  WORKDIR $HOME/app
26
 
 
 
 
 
27
  # Copy the current directory contents into the container at $HOME/app setting the owner to the user
28
  COPY --chown=user . $HOME/app
 
 
 
 
 
 
29
  CMD ["python", "main.py"]
30
 
31
 
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Adaptability protein dynamics
3
  emoji: 🔥
4
  colorFrom: indigo
5
  colorTo: red
 
1
  ---
2
+ title: Adapt Docker
3
  emoji: 🔥
4
  colorFrom: indigo
5
  colorTo: red
main.py CHANGED
@@ -1,7 +1,7 @@
1
-
2
-
3
  import gradio as gr
 
4
  import py3Dmol
 
5
  from Bio.PDB import *
6
 
7
  import numpy as np
@@ -12,9 +12,6 @@ import os
12
  from MDmodel import GNN_MD
13
  import h5py
14
  from transformMD import GNNTransformMD
15
- import sys
16
- import pytraj as pt
17
- import pickle
18
 
19
  # JavaScript functions
20
  resid_hover = """function(atom,viewer) {{
@@ -49,78 +46,6 @@ model = model.to('cpu')
49
  model.eval()
50
 
51
 
52
- def run_leap(fileName, path):
53
- leapText = """
54
- source leaprc.protein.ff14SB
55
- source leaprc.water.tip3p
56
- exp = loadpdb PATH4amb.pdb
57
- saveamberparm exp PATHexp.top PATHexp.crd
58
- quit
59
- """
60
- with open(path+"leap.in", "w") as outLeap:
61
- outLeap.write(leapText.replace('PATH', path))
62
- os.system("tleap -f "+path+"leap.in >> "+path+"leap.out")
63
-
64
- def convert_to_amber_format(pdbName):
65
- fileName, path = pdbName+'.pdb', ''
66
- os.system("pdb4amber -i "+fileName+" -p -y -o "+path+"4amb.pdb -l "+path+"pdb4amber_protein.log")
67
- run_leap(fileName, path)
68
- traj = pt.iterload(path+'exp.crd', top = path+'exp.top')
69
- pt.write_traj(path+fileName, traj, overwrite= True)
70
- print(path+fileName+' was created. Please always use this file for inspection because the coordinates might get translated during amber file generation and thus might vary from the input pdb file.')
71
- return pt.iterload(path+'exp.crd', top = path+'exp.top')
72
-
73
- def get_maps(mapPath):
74
- residueMap = pickle.load(open(os.path.join(mapPath,'atoms_residue_map_generate.pickle'),'rb'))
75
- nameMap = pickle.load(open(os.path.join(mapPath,'atoms_name_map_generate.pickle'),'rb'))
76
- typeMap = pickle.load(open(os.path.join(mapPath,'atoms_type_map_generate.pickle'),'rb'))
77
- elementMap = pickle.load(open(os.path.join(mapPath,'map_atomType_element_numbers.pickle'),'rb'))
78
- return residueMap, nameMap, typeMap, elementMap
79
-
80
- def get_residues_atomwise(residues):
81
- atomwise = []
82
- for name, nAtoms in residues:
83
- for i in range(nAtoms):
84
- atomwise.append(name)
85
- return atomwise
86
-
87
- def get_begin_atom_index(traj):
88
- natoms = [m.n_atoms for m in traj.top.mols]
89
- molecule_begin_atom_index = [0]
90
- x = 0
91
- for i in range(len(natoms)):
92
- x += natoms[i]
93
- molecule_begin_atom_index.append(x)
94
- print('molecule begin atom index', molecule_begin_atom_index, natoms)
95
- return molecule_begin_atom_index
96
-
97
- def get_traj_info(traj, mapPath):
98
- coordinates = traj.xyz
99
- residueMap, nameMap, typeMap, elementMap = get_maps(mapPath)
100
- types = [typeMap[a.type] for a in traj.top.atoms]
101
- elements = [elementMap[typ] for typ in types]
102
- atomic_numbers = [a.atomic_number for a in traj.top.atoms]
103
- molecule_begin_atom_index = get_begin_atom_index(traj)
104
- residues = [(residueMap[res.name], res.n_atoms) for res in traj.top.residues]
105
- residues_atomwise = get_residues_atomwise(residues)
106
- return coordinates[0], elements, types, atomic_numbers, residues_atomwise, molecule_begin_atom_index
107
-
108
- def write_h5_info(outName, struct, atoms_type, atoms_number, atoms_residue, atoms_element, molecules_begin_atom_index, atoms_coordinates_ref):
109
- if os.path.isfile(outName):
110
- os.remove(outName)
111
- with h5py.File(outName, 'w') as oF:
112
- subgroup = oF.create_group(struct)
113
- subgroup.create_dataset('atoms_residue', data= atoms_residue, compression = "gzip", dtype='i8')
114
- subgroup.create_dataset('molecules_begin_atom_index', data= molecules_begin_atom_index, compression = "gzip", dtype='i8')
115
- subgroup.create_dataset('atoms_type', data= atoms_type, compression = "gzip", dtype='i8')
116
- subgroup.create_dataset('atoms_number', data= atoms_number, compression = "gzip", dtype='i8')
117
- subgroup.create_dataset('atoms_element', data= atoms_element, compression = "gzip", dtype='i8')
118
- subgroup.create_dataset('atoms_coordinates_ref', data= atoms_coordinates_ref, compression = "gzip", dtype='f8')
119
-
120
- def preprocess(pdbid: str = None, ouputfile: str = "inference_for_md.hdf5", mask: str = "!@H=", mappath: str = "/maps/"):
121
- traj = convert_to_amber_format(pdbid)
122
- atoms_coordinates_ref, atoms_element, atoms_type, atoms_number, atoms_residue, molecules_begin_atom_index = get_traj_info(traj[mask], mappath)
123
- write_h5_info(ouputfile, pdbid, atoms_type, atoms_number, atoms_residue, atoms_element, molecules_begin_atom_index, atoms_coordinates_ref)
124
 
125
  def get_pdb(pdb_code="", filepath=""):
126
  try:
@@ -140,37 +65,24 @@ def get_offset(pdb):
140
  return int(line[22:27])
141
 
142
 
143
- def get_pdbid_from_filename(filename: str):
144
- # Assuming the filename would be of the standard form 11GS.pdb
145
- return filename.split(".")[0]
146
-
147
- def predict(pdb_code, pdb_file, topN):
148
- #path_to_pdb = get_pdb(pdb_code=pdb_code, filepath=pdb_file)
149
-
150
- #pdb = open(path_to_pdb, "r").read()
151
- # switch to misato env if not running from container
152
-
153
- pdbid = get_pdbid_from_filename(pdb_file.name)
154
  mdh5_file = "inference_for_md.hdf5"
155
- mappath = "/maps"
156
- mask = "!@H="
157
- preprocess(pdbid=pdbid, ouputfile=mdh5_file, mask=mask, mappath=mappath)
158
-
159
  md_H5File = h5py.File(mdh5_file)
160
 
161
  column_names = ["x", "y", "z", "element"]
162
  atoms_protein = pd.DataFrame(columns = column_names)
163
- cutoff = md_H5File[pdbid]["molecules_begin_atom_index"][:][-1] # cutoff defines protein atoms
164
 
165
- atoms_protein["x"] = md_H5File[pdbid]["atoms_coordinates_ref"][:][:cutoff, 0]
166
- atoms_protein["y"] = md_H5File[pdbid]["atoms_coordinates_ref"][:][:cutoff, 1]
167
- atoms_protein["z"] = md_H5File[pdbid]["atoms_coordinates_ref"][:][:cutoff, 2]
168
 
169
- atoms_protein["element"] = md_H5File[pdbid]["atoms_element"][:][:cutoff]
170
 
171
  item = {}
172
  item["scores"] = 0
173
- item["id"] = pdbid
174
  item["atoms_protein"] = atoms_protein
175
 
176
  transform = GNNTransformMD()
@@ -184,56 +96,30 @@ def predict(pdb_code, pdb_file, topN):
184
  for i in range(adaptability.shape[0]):
185
  data.append([i, atom_mapping[atoms_protein.iloc[i, atoms_protein.columns.get_loc("element")] - 1], atoms_protein.iloc[i, atoms_protein.columns.get_loc("x")],atoms_protein.iloc[i, atoms_protein.columns.get_loc("y")],atoms_protein.iloc[i, atoms_protein.columns.get_loc("z")],adaptability[i]])
186
 
 
187
  topN_ind = np.argsort(adaptability)[::-1][:topN]
188
 
189
- pdb = open(pdb_file.name, "r").read()
190
- pdb2 = pdb
191
-
192
- view = py3Dmol.view(width=1000, height=800)
193
  view.setBackgroundColor('white')
194
  view.addModel(pdb, "pdb")
195
- view.setStyle({'stick': {'colorscheme': {'prop': 'resi', 'C': '#cccccc'}},'cartoon': {'color': '#4c4e9e', 'alpha':"0.6"}})
196
-
197
- #view.addModel(pdb2, "pdb2")
198
- #view.setStyle({'cartoon': {'color': 'gray'}})
199
-
200
-
201
- # Commenting since the visualizer is not rendered
202
- # view.addLight([0, 0, 10], [1, 1, 1], 1) # Add directional light from the z-axis
203
- # view.setSpecular(0.5) # Adjust the specular lighting effect
204
- # view.setAmbient(0.5) # Adjust the ambient lighting effect
205
-
206
  for i in range(topN):
207
- adaptability_value = adaptability[topN_ind[i]]
208
- color = '#a0210f'
209
- view.addSphere({
210
- 'center': {
211
- 'x': atoms_protein.iloc[topN_ind[i], atoms_protein.columns.get_loc("x")],
212
- 'y': atoms_protein.iloc[topN_ind[i], atoms_protein.columns.get_loc("y")],
213
- 'z': atoms_protein.iloc[topN_ind[i], atoms_protein.columns.get_loc("z")]
214
- },
215
- 'radius': adaptability_value / 1.5,
216
- 'color': color,
217
- 'alpha': 0.75
218
- })
219
-
220
-
221
  view.zoomTo()
222
 
223
  output = view._make_html().replace("'", '"')
224
 
225
  x = f"""<!DOCTYPE html><html> {output} </html>""" # do not use ' in this input
226
-
227
- return f"""<iframe style="width: 100%; height:820px" name="result" allow="midi; geolocation; microphone; camera;
228
  display-capture; encrypted-media;" sandbox="allow-modals allow-forms
229
  allow-scripts allow-same-origin allow-popups
230
  allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
231
  allowpaymentrequest="" frameborder="0" srcdoc='{x}'></iframe>""", pd.DataFrame(data, columns=['index','element','x','y','z','Adaptability'])
232
 
233
- def export_csv(d):
234
- d.to_csv("adaptabilities.csv")
235
- return gr.File.update(value="adaptabilities.csv", visible=True)
236
-
237
 
238
  callback = gr.CSVLogger()
239
 
@@ -244,11 +130,7 @@ def run():
244
  #text_input = gr.Textbox()
245
  #text_output = gr.Textbox()
246
  #text_button = gr.Button("Flip")
247
- inp = gr.Textbox(placeholder="Upload PDB file below", label="Input structure")
248
- #inp = ""
249
- topN = gr.Slider(value=100,
250
- minimum=1, maximum=1000, label="Number of highest adaptability values to visualize", step=1
251
- )
252
  pdb_file = gr.File(label="PDB File Upload")
253
  #with gr.Row():
254
  # helix = gr.ColorPicker(label="helix")
@@ -257,21 +139,14 @@ def run():
257
  single_btn = gr.Button(label="Run")
258
  with gr.Row():
259
  html = gr.HTML()
260
- with gr.Row():
261
- Dbutton = gr.Button("Download adaptability values")
262
- csv = gr.File(interactive=False, visible=False)
263
  with gr.Row():
264
  dataframe = gr.Dataframe()
265
 
266
- single_btn.click(fn=predict, inputs=[inp, pdb_file, topN], outputs=[html, dataframe])
267
-
268
- Dbutton.click(export_csv, dataframe, csv)
269
-
270
-
271
 
272
 
273
  demo.launch(server_name="0.0.0.0", server_port=7860)
274
 
275
 
276
  if __name__ == "__main__":
277
- run()
 
 
 
1
  import gradio as gr
2
+
3
  import py3Dmol
4
+
5
  from Bio.PDB import *
6
 
7
  import numpy as np
 
12
  from MDmodel import GNN_MD
13
  import h5py
14
  from transformMD import GNNTransformMD
 
 
 
15
 
16
  # JavaScript functions
17
  resid_hover = """function(atom,viewer) {{
 
46
  model.eval()
47
 
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  def get_pdb(pdb_code="", filepath=""):
51
  try:
 
65
  return int(line[22:27])
66
 
67
 
68
+ def predict(pdb_code, pdb_file):
69
+ path_to_pdb = get_pdb(pdb_code=pdb_code, filepath=pdb_file)
 
 
 
 
 
 
 
 
 
70
  mdh5_file = "inference_for_md.hdf5"
 
 
 
 
71
  md_H5File = h5py.File(mdh5_file)
72
 
73
  column_names = ["x", "y", "z", "element"]
74
  atoms_protein = pd.DataFrame(columns = column_names)
75
+ cutoff = md_H5File["11GS"]["molecules_begin_atom_index"][:][-1] # cutoff defines protein atoms
76
 
77
+ atoms_protein["x"] = md_H5File["11GS"]["atoms_coordinates_ref"][:][:cutoff, 0]
78
+ atoms_protein["y"] = md_H5File["11GS"]["atoms_coordinates_ref"][:][:cutoff, 1]
79
+ atoms_protein["z"] = md_H5File["11GS"]["atoms_coordinates_ref"][:][:cutoff, 2]
80
 
81
+ atoms_protein["element"] = md_H5File["11GS"]["atoms_element"][:][:cutoff]
82
 
83
  item = {}
84
  item["scores"] = 0
85
+ item["id"] = "11GS"
86
  item["atoms_protein"] = atoms_protein
87
 
88
  transform = GNNTransformMD()
 
96
  for i in range(adaptability.shape[0]):
97
  data.append([i, atom_mapping[atoms_protein.iloc[i, atoms_protein.columns.get_loc("element")] - 1], atoms_protein.iloc[i, atoms_protein.columns.get_loc("x")],atoms_protein.iloc[i, atoms_protein.columns.get_loc("y")],atoms_protein.iloc[i, atoms_protein.columns.get_loc("z")],adaptability[i]])
98
 
99
+ topN = 100
100
  topN_ind = np.argsort(adaptability)[::-1][:topN]
101
 
102
+ pdb = open(path_to_pdb, "r").read()
103
+
104
+ view = py3Dmol.view(width=600, height=400)
 
105
  view.setBackgroundColor('white')
106
  view.addModel(pdb, "pdb")
107
+ view.setStyle({'stick': {'colorscheme': {'prop': 'resi', 'C': 'turquoise'}}})
108
+
 
 
 
 
 
 
 
 
 
109
  for i in range(topN):
110
+ view.addSphere({'center':{'x':atoms_protein.iloc[topN_ind[i], atoms_protein.columns.get_loc("x")], 'y':atoms_protein.iloc[topN_ind[i], atoms_protein.columns.get_loc("y")],'z':atoms_protein.iloc[topN_ind[i], atoms_protein.columns.get_loc("z")]},'radius':adaptability[topN_ind[i]]/1.5,'color':'orange','alpha':0.75})
111
+
 
 
 
 
 
 
 
 
 
 
 
 
112
  view.zoomTo()
113
 
114
  output = view._make_html().replace("'", '"')
115
 
116
  x = f"""<!DOCTYPE html><html> {output} </html>""" # do not use ' in this input
117
+ return f"""<iframe style="width: 100%; height:420px" name="result" allow="midi; geolocation; microphone; camera;
 
118
  display-capture; encrypted-media;" sandbox="allow-modals allow-forms
119
  allow-scripts allow-same-origin allow-popups
120
  allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
121
  allowpaymentrequest="" frameborder="0" srcdoc='{x}'></iframe>""", pd.DataFrame(data, columns=['index','element','x','y','z','Adaptability'])
122
 
 
 
 
 
123
 
124
  callback = gr.CSVLogger()
125
 
 
130
  #text_input = gr.Textbox()
131
  #text_output = gr.Textbox()
132
  #text_button = gr.Button("Flip")
133
+ inp = gr.Textbox(placeholder="PDB Code or upload file below", label="Input structure")
 
 
 
 
134
  pdb_file = gr.File(label="PDB File Upload")
135
  #with gr.Row():
136
  # helix = gr.ColorPicker(label="helix")
 
139
  single_btn = gr.Button(label="Run")
140
  with gr.Row():
141
  html = gr.HTML()
 
 
 
142
  with gr.Row():
143
  dataframe = gr.Dataframe()
144
 
145
+ single_btn.click(fn=predict, inputs=[inp, pdb_file], outputs=[html, dataframe])
 
 
 
 
146
 
147
 
148
  demo.launch(server_name="0.0.0.0", server_port=7860)
149
 
150
 
151
  if __name__ == "__main__":
152
+ run()
maps/atoms_name_map_for_pdb.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:43312dc497c280abd0aa8aa5ca5e70cb33aef74348d880eabef62e919c8fa04c
3
- size 26765
 
 
 
 
maps/atoms_name_map_generate.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:16d45a0c1413b2ef3f1e5f044dd13234d5f1fadb5cf5f09b4af528872b83808b
3
- size 4264
 
 
 
 
maps/atoms_name_map_new.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:becf7b36cb63e74072d0218d19ee8c1187e19e6d7f7189409e95b00e6bf5c4a8
3
- size 4264
 
 
 
 
maps/atoms_residue_map.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e8cc11f197830509123ba01140796a8a032ca0630e0e93962391dcdeed38a40a
3
- size 284
 
 
 
 
maps/atoms_residue_map_generate.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:a10a0235a59670f8891c5d4d6dc47c474625fc3d5fbeb7161d3a34341ba23f7a
3
- size 284
 
 
 
 
maps/atoms_type_map.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:3dedc6173b3889c25bb05dacc5ea90d057b6ac7758181eb9465f85c79aafca5d
3
- size 1207
 
 
 
 
maps/atoms_type_map_generate.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:98a595ca5369902304c7c10a3d2c4d97c754d40f70d88b6aa9f725f186587c96
3
- size 1207
 
 
 
 
maps/map_atomType_element_names.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5c1900a90db246fee15e600a30c5ae40879f04f67d7d42326dd8680df7f74383
3
- size 356
 
 
 
 
maps/map_atomType_element_numbers.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:bb6cf66a0f83ff33af562a8c1d6f716abb857b99a3137313fe86e24936afe39c
3
- size 448
 
 
 
 
maps/map_elements_numbers_number.pickle DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:67cc394f5216b325880af8cdb3919b0634fe5a5bf1598bbfb1985a66d111f7f6
3
- size 110
 
 
 
 
mock_download.py DELETED
@@ -1,23 +0,0 @@
1
- import gradio as gr
2
-
3
- def mock_ocr(f):
4
- return [[1, 2, 3], [4, 5, 6]]
5
-
6
- def export_csv(d):
7
- d.to_csv("output.csv")
8
- return gr.File.update(value="output.csv", visible=True)
9
-
10
- with gr.Blocks() as demo:
11
- with gr.Row():
12
- file = gr.File(label="PDF file", file_types=[".pdf"])
13
- dataframe = gr.Dataframe()
14
-
15
- with gr.Column():
16
- button = gr.Button("Export")
17
- csv = gr.File(interactive=False, visible=False)
18
-
19
-
20
- file.change(mock_ocr, file, dataframe)
21
- button.click(export_csv, dataframe, csv)
22
-
23
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
old_main.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import requests
4
+ from torchvision import transforms
5
+
6
+ model = torch.hub.load("pytorch/vision:v0.6.0", "resnet18", pretrained=True).eval()
7
+ response = requests.get("https://git.io/JJkYN")
8
+ labels = response.text.split("\n")
9
+
10
+
11
+ def predict(inp):
12
+ inp = transforms.ToTensor()(inp).unsqueeze(0)
13
+ with torch.no_grad():
14
+ prediction = torch.nn.functional.softmax(model(inp)[0], dim=0)
15
+ confidences = {labels[i]: float(prediction[i]) for i in range(1000)}
16
+ return confidences
17
+
18
+
19
+ def run():
20
+ demo = gr.Interface(
21
+ fn=predict,
22
+ inputs=gr.inputs.Image(type="pil"),
23
+ outputs=gr.outputs.Label(num_top_classes=3),
24
+ )
25
+
26
+ demo.launch(server_name="0.0.0.0", server_port=7860)
27
+
28
+
29
+ if __name__ == "__main__":
30
+ run()
requirements.txt CHANGED
@@ -1,6 +1,3 @@
1
  gradio
2
  torchvision
3
- requests
4
- py3Dmol
5
- biopython
6
- pandas
 
1
  gradio
2
  torchvision
3
+ requests