gemmi-protools 0.1.8__py3-none-any.whl → 0.1.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gemmi-protools might be problematic. Click here for more details.
- gemmi_protools/io/cif_opts.py +8 -0
- gemmi_protools/io/parser.py +33 -25
- gemmi_protools/io/reader.py +13 -0
- gemmi_protools/utils/fixer.py +101 -85
- {gemmi_protools-0.1.8.dist-info → gemmi_protools-0.1.10.dist-info}/METADATA +1 -1
- {gemmi_protools-0.1.8.dist-info → gemmi_protools-0.1.10.dist-info}/RECORD +9 -9
- {gemmi_protools-0.1.8.dist-info → gemmi_protools-0.1.10.dist-info}/WHEEL +1 -1
- {gemmi_protools-0.1.8.dist-info → gemmi_protools-0.1.10.dist-info}/licenses/LICENSE +0 -0
- {gemmi_protools-0.1.8.dist-info → gemmi_protools-0.1.10.dist-info}/top_level.txt +0 -0
gemmi_protools/io/cif_opts.py
CHANGED
|
@@ -135,6 +135,14 @@ def _cif_entity_info(block: gemmi.cif.Block) -> Entity:
|
|
|
135
135
|
def _cif_block_for_output(structure: gemmi.Structure, entity: Entity) -> gemmi.cif.Block:
|
|
136
136
|
block = structure.make_mmcif_block()
|
|
137
137
|
|
|
138
|
+
reflns = block.find_mmcif_category(category="_reflns.")
|
|
139
|
+
if "_reflns.d_resolution_high" not in list(reflns.tags) or "_reflns.d_resolution_low" not in list(reflns.tags):
|
|
140
|
+
reflns.erase()
|
|
141
|
+
|
|
142
|
+
resolution = "%.2f" % structure.resolution
|
|
143
|
+
reflns_loop = block.init_loop(prefix="_reflns.", tags=["d_resolution_high", "d_resolution_low"])
|
|
144
|
+
reflns_loop.add_row([resolution, resolution])
|
|
145
|
+
|
|
138
146
|
ta = block.find_mmcif_category(category="_entity.")
|
|
139
147
|
da = pd.DataFrame(list(ta), columns=list(ta.tags))
|
|
140
148
|
if "_entity.id" in da.columns:
|
gemmi_protools/io/parser.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
@Author: Luo Jiejian
|
|
3
3
|
"""
|
|
4
4
|
import pathlib
|
|
5
|
-
from collections import
|
|
5
|
+
from collections import Counter
|
|
6
6
|
from typing import Union, Optional, Dict, List
|
|
7
7
|
|
|
8
8
|
import gemmi
|
|
@@ -114,6 +114,19 @@ def _update_entity_names(entity: Entity, mapper: Dict[str, str]):
|
|
|
114
114
|
tmp[mapper[key]] = entity[super_key][key]
|
|
115
115
|
entity.__setattr__(super_key, tmp)
|
|
116
116
|
|
|
117
|
+
new_polymer2eid = dict()
|
|
118
|
+
for c, old_eid in entity.polymer2eid.items():
|
|
119
|
+
new_polymer2eid[c] = mapper[old_eid]
|
|
120
|
+
entity.__setattr__(name="polymer2eid", value=new_polymer2eid)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _melt_dict(inputs: dict):
|
|
124
|
+
outputs = dict()
|
|
125
|
+
for keys, val in inputs.items():
|
|
126
|
+
for k in keys.split(","):
|
|
127
|
+
outputs[k] = val
|
|
128
|
+
return outputs
|
|
129
|
+
|
|
117
130
|
|
|
118
131
|
@typechecked
|
|
119
132
|
def pdb_parser(path: Union[str, pathlib.Path]):
|
|
@@ -126,39 +139,34 @@ def pdb_parser(path: Union[str, pathlib.Path]):
|
|
|
126
139
|
struct = gemmi.read_structure(str(path))
|
|
127
140
|
struct.resolution = _get_pdb_resolution(struct.raw_remarks)
|
|
128
141
|
ent_0 = _pdb_entity_info(path)
|
|
142
|
+
ch2desc = _melt_dict(ent_0.eid2desc)
|
|
143
|
+
ch2specie = _melt_dict(ent_0.eid2specie)
|
|
144
|
+
ch2taxid = _melt_dict(ent_0.eid2taxid)
|
|
129
145
|
|
|
130
146
|
struct.setup_entities()
|
|
131
|
-
|
|
132
|
-
# pdb have "A,B,C" chains
|
|
133
|
-
# after setup, entities will merge
|
|
134
147
|
block = struct.make_mmcif_block()
|
|
135
148
|
ent_t = _cif_entity_info(block)
|
|
136
|
-
rec = defaultdict(list)
|
|
137
|
-
|
|
138
|
-
for cn, middle_eid in ent_t.polymer2eid.items():
|
|
139
|
-
rec[middle_eid].append(cn)
|
|
140
149
|
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
# set non-polymer entity names
|
|
151
|
+
non_polymer_entities = [e.name for e in struct.entities if e.polymer_type.name == "Unknown"]
|
|
152
|
+
for k in non_polymer_entities:
|
|
153
|
+
assert k in ent_t.eid2desc
|
|
154
|
+
if ent_t.eid2desc[k] == "?":
|
|
155
|
+
ent_t.eid2desc[k] = k
|
|
143
156
|
|
|
144
|
-
for
|
|
145
|
-
if
|
|
146
|
-
|
|
147
|
-
mid.sort()
|
|
148
|
-
old_eid = str(",".join(mid))
|
|
149
|
-
_mapper_n[old_eid] = new_eid
|
|
157
|
+
for k in ent_t.eid2desc.keys():
|
|
158
|
+
if k not in non_polymer_entities:
|
|
159
|
+
ent_t.eid2desc[k] = ch2desc.get(k, "?")
|
|
150
160
|
|
|
151
|
-
|
|
152
|
-
|
|
161
|
+
polymer_chs_used_as_eid = set(ch2specie.keys()).intersection(ent_t.eid2desc.keys())
|
|
162
|
+
for k in polymer_chs_used_as_eid:
|
|
163
|
+
ent_t.eid2specie[k] = ch2specie.get(k, "?")
|
|
164
|
+
ent_t.eid2taxid[k] = ch2taxid.get(k, "?")
|
|
153
165
|
|
|
154
|
-
|
|
166
|
+
m = _assign_digital_entity_names(struct)
|
|
167
|
+
_update_entity_names(ent_t, m)
|
|
155
168
|
|
|
156
|
-
|
|
157
|
-
for super_key in ["eid2desc", "polymer2eid"]:
|
|
158
|
-
for key, val in ent_1[super_key].items():
|
|
159
|
-
if key not in ent_0[super_key]:
|
|
160
|
-
ent_0[super_key][key] = val
|
|
161
|
-
return struct, ent_0
|
|
169
|
+
return struct, ent_t
|
|
162
170
|
else:
|
|
163
171
|
raise ValueError("Only support .pdb or .pdb.gz file, but got %s" % path)
|
|
164
172
|
|
gemmi_protools/io/reader.py
CHANGED
|
@@ -83,6 +83,19 @@ class StructureParser(object):
|
|
|
83
83
|
def to_pdb(self, outfile: str, write_minimal_pdb=False):
|
|
84
84
|
compound_source = _compound_source_string(self.ENTITY)
|
|
85
85
|
struct = self.STRUCT.clone()
|
|
86
|
+
|
|
87
|
+
rs = "REMARK 2 RESOLUTION. %.2f ANGSTROMS." % struct.resolution
|
|
88
|
+
resolution_remarks = ["%-80s" % "REMARK 2",
|
|
89
|
+
"%-80s" % rs]
|
|
90
|
+
|
|
91
|
+
resolution_remark_exist = False
|
|
92
|
+
for line in struct.raw_remarks:
|
|
93
|
+
if "REMARK 2 RESOLUTION" in line:
|
|
94
|
+
resolution_remark_exist = True
|
|
95
|
+
|
|
96
|
+
if not resolution_remark_exist:
|
|
97
|
+
struct.raw_remarks = resolution_remarks + struct.raw_remarks
|
|
98
|
+
|
|
86
99
|
struct.raw_remarks = compound_source + struct.raw_remarks
|
|
87
100
|
if write_minimal_pdb:
|
|
88
101
|
struct.write_minimal_pdb(outfile)
|
gemmi_protools/utils/fixer.py
CHANGED
|
@@ -6,33 +6,35 @@ import gzip
|
|
|
6
6
|
import io
|
|
7
7
|
import os
|
|
8
8
|
import pathlib
|
|
9
|
+
import re
|
|
9
10
|
import shutil
|
|
10
11
|
import subprocess
|
|
11
12
|
import time
|
|
12
13
|
import uuid
|
|
13
|
-
from typing import Union
|
|
14
|
+
from typing import Union
|
|
14
15
|
|
|
16
|
+
import openmm
|
|
15
17
|
import pdbfixer
|
|
16
18
|
from openmm import app
|
|
17
|
-
import openmm
|
|
18
19
|
from typeguard import typechecked
|
|
19
20
|
|
|
21
|
+
from gemmi_protools import StructureParser
|
|
20
22
|
from gemmi_protools.io.cif_opts import _is_cif
|
|
21
23
|
from gemmi_protools.io.pdb_opts import _is_pdb
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
@typechecked
|
|
25
|
-
def _load_by_pbdfixer(path: Union[str, pathlib.Path],
|
|
27
|
+
def _load_by_pbdfixer(path: Union[str, pathlib.Path], cpu_platform=True) -> pdbfixer.PDBFixer:
|
|
26
28
|
"""
|
|
27
29
|
|
|
28
30
|
Args:
|
|
29
31
|
path:
|
|
30
|
-
|
|
32
|
+
cpu_platform: default True, if False, auto select platform
|
|
31
33
|
|
|
32
34
|
Returns:
|
|
33
35
|
|
|
34
36
|
"""
|
|
35
|
-
if
|
|
37
|
+
if cpu_platform:
|
|
36
38
|
platform = openmm.Platform.getPlatformByName('CPU')
|
|
37
39
|
else:
|
|
38
40
|
platform = None
|
|
@@ -66,9 +68,8 @@ def clean_structure(input_file: Union[str, pathlib.Path],
|
|
|
66
68
|
keep_heterogens: str = "all",
|
|
67
69
|
replace_nonstandard: bool = True,
|
|
68
70
|
ph: Union[float, int] = 7.0,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
use_platform=True
|
|
71
|
+
cpu_platform=True,
|
|
72
|
+
clean_connect=True
|
|
72
73
|
):
|
|
73
74
|
"""
|
|
74
75
|
|
|
@@ -87,9 +88,8 @@ def clean_structure(input_file: Union[str, pathlib.Path],
|
|
|
87
88
|
none: remove all heterogens
|
|
88
89
|
:param replace_nonstandard: default True, replace all non-standard residues to standard ones
|
|
89
90
|
:param ph: default 7.0, ph values to add missing hydrogen atoms
|
|
90
|
-
:param
|
|
91
|
-
:param
|
|
92
|
-
:param use_platform: default True to use CPU platform, if False, auto select platform
|
|
91
|
+
:param cpu_platform: default True to use CPU platform, if False, auto select platform
|
|
92
|
+
:param clean_connect: default True to clean CONECT lines in output pdb
|
|
93
93
|
|
|
94
94
|
:return:
|
|
95
95
|
str, status message of fixing
|
|
@@ -102,16 +102,14 @@ def clean_structure(input_file: Union[str, pathlib.Path],
|
|
|
102
102
|
######################################################
|
|
103
103
|
# load structure
|
|
104
104
|
######################################################
|
|
105
|
-
fixer = _load_by_pbdfixer(input_file,
|
|
105
|
+
fixer = _load_by_pbdfixer(input_file, cpu_platform)
|
|
106
106
|
|
|
107
107
|
######################################################
|
|
108
108
|
# check
|
|
109
109
|
######################################################
|
|
110
110
|
fixer.findMissingResidues()
|
|
111
111
|
fixer.findMissingAtoms()
|
|
112
|
-
ratio = len(fixer.missingAtoms) / fixer.topology.getNumResidues()
|
|
113
|
-
if ratio > threshold:
|
|
114
|
-
return dict(input=input_file, msg="Too many residues with missing atoms: %.2f" % ratio)
|
|
112
|
+
ratio = "%.2f" % (len(fixer.missingAtoms) / fixer.topology.getNumResidues(),)
|
|
115
113
|
|
|
116
114
|
######################################################
|
|
117
115
|
# replace non-standard residues
|
|
@@ -166,73 +164,94 @@ def clean_structure(input_file: Union[str, pathlib.Path],
|
|
|
166
164
|
msg_str = "Finished"
|
|
167
165
|
except Exception as e:
|
|
168
166
|
msg_str = str(e)
|
|
167
|
+
ratio = "*"
|
|
168
|
+
else:
|
|
169
|
+
if clean_connect:
|
|
170
|
+
output_lines = []
|
|
171
|
+
with open(output_file, "r") as in_handle:
|
|
172
|
+
for line in in_handle:
|
|
173
|
+
if not re.match("CONECT", line):
|
|
174
|
+
output_lines.append(line)
|
|
175
|
+
with open(output_file, "w") as out_handle:
|
|
176
|
+
print("".join(output_lines), file=out_handle)
|
|
169
177
|
|
|
170
|
-
return dict(input=input_file, msg=msg_str)
|
|
178
|
+
return dict(input=input_file, msg=msg_str, res_ratio_with_missing_atoms=ratio)
|
|
171
179
|
|
|
172
180
|
|
|
173
181
|
@typechecked
|
|
174
|
-
def
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if os.path.exists(dst_path):
|
|
182
|
-
os.remove(dst_path)
|
|
183
|
-
shutil.move(src_path, dst_folder)
|
|
184
|
-
|
|
182
|
+
def repair_structure(input_file: str,
|
|
183
|
+
output_file: str,
|
|
184
|
+
complex_with_dna: bool = False,
|
|
185
|
+
complex_with_rna: bool = False,
|
|
186
|
+
timeout: Union[int, float] = 3600):
|
|
187
|
+
"""
|
|
185
188
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
:param input_file: .pdb or .cif or .pdb.gz or .cif.gz
|
|
190
|
+
:param output_file: .pdb file
|
|
191
|
+
:param complex_with_dna: bool, default False, not debug yet
|
|
192
|
+
:param complex_with_rna: bool, default False, not debug yet
|
|
193
|
+
:param timeout: float or int
|
|
194
|
+
:return:
|
|
195
|
+
"""
|
|
196
|
+
############################################################
|
|
197
|
+
# Check and convert input_file to .pdb if not
|
|
198
|
+
############################################################
|
|
199
|
+
assert os.path.splitext(output_file)[1] == ".pdb", "output_file Not .pdb: %s" % output_file
|
|
200
|
+
assert _is_cif(input_file) or _is_pdb(input_file), "Not .pdb or .cif or .pdb.gz or .cif.gz: %s" % input_file
|
|
201
|
+
|
|
202
|
+
# input_file and output_file can't be the same path
|
|
203
|
+
p_in = pathlib.Path(input_file).expanduser().resolve()
|
|
204
|
+
p_out = pathlib.Path(output_file).expanduser().resolve()
|
|
205
|
+
|
|
206
|
+
assert str(p_in) != str(p_out), "input_file and output_file can't be the same path"
|
|
207
|
+
############################################################
|
|
208
|
+
# Config Path
|
|
209
|
+
############################################################
|
|
210
|
+
file_name = os.path.basename(input_file)
|
|
211
|
+
stem_name = os.path.splitext(file_name)[0]
|
|
212
|
+
|
|
213
|
+
in_dir = os.path.dirname(input_file)
|
|
214
|
+
out_dir = os.path.dirname(output_file)
|
|
192
215
|
if not os.path.isdir(out_dir):
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
os.makedirs(out_dir)
|
|
217
|
+
|
|
218
|
+
temp_dir = os.path.join(out_dir, "_RepairTemp_%s" % str(uuid.uuid4()))
|
|
219
|
+
if os.path.isdir(temp_dir):
|
|
220
|
+
shutil.rmtree(temp_dir)
|
|
221
|
+
os.makedirs(temp_dir)
|
|
222
|
+
|
|
223
|
+
if os.path.splitext(input_file)[1] != ".pdb":
|
|
224
|
+
# convert to .pdb
|
|
225
|
+
st = StructureParser()
|
|
226
|
+
st.load_from_file(input_file)
|
|
227
|
+
file_name_r = "%s.pdb" % stem_name
|
|
228
|
+
in_dir_r = temp_dir
|
|
229
|
+
st.to_pdb(os.path.join(in_dir_r, file_name_r))
|
|
230
|
+
else:
|
|
231
|
+
file_name_r = file_name
|
|
232
|
+
in_dir_r = in_dir
|
|
210
233
|
|
|
211
|
-
|
|
212
|
-
|
|
234
|
+
foldx_path = shutil.which("foldx")
|
|
235
|
+
if foldx_path is None:
|
|
236
|
+
raise RuntimeError("path of foldx is not set or found in PATH")
|
|
213
237
|
|
|
214
|
-
os.
|
|
238
|
+
cwd_dir = os.getcwd()
|
|
215
239
|
|
|
216
|
-
|
|
217
|
-
|
|
240
|
+
repair_cmd = [foldx_path,
|
|
241
|
+
"-c RepairPDB",
|
|
242
|
+
"--pdb %s" % file_name_r,
|
|
243
|
+
"--pdb-dir %s" % in_dir_r,
|
|
244
|
+
"--output-dir %s" % temp_dir
|
|
245
|
+
]
|
|
246
|
+
if complex_with_dna:
|
|
247
|
+
repair_cmd.append("--complexWithDNA true")
|
|
218
248
|
|
|
219
|
-
if
|
|
220
|
-
|
|
249
|
+
if complex_with_rna:
|
|
250
|
+
repair_cmd.append("--complexWithRNA true")
|
|
221
251
|
|
|
222
|
-
|
|
223
|
-
command_settings = ["cd %s" % sub_temp_dir,
|
|
224
|
-
"&&",
|
|
225
|
-
foldx_path,
|
|
226
|
-
"-c RepairPDB",
|
|
227
|
-
"--pdb %s" % pdb_file,
|
|
228
|
-
"--pdb-dir %s" % pdb_dir,
|
|
229
|
-
"--output-dir %s" % sub_temp_dir,
|
|
230
|
-
"&&",
|
|
231
|
-
"cd %s" % old_dir
|
|
232
|
-
]
|
|
252
|
+
command_settings = ["cd %s &&" % temp_dir] + repair_cmd + ["&& cd %s" % cwd_dir]
|
|
233
253
|
|
|
234
254
|
start = time.time()
|
|
235
|
-
|
|
236
255
|
try:
|
|
237
256
|
result = subprocess.run(" ".join(command_settings), shell=True, check=True,
|
|
238
257
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
@@ -241,22 +260,19 @@ def repair_structure(input_file: Union[str, pathlib.Path],
|
|
|
241
260
|
if result.returncode == 0:
|
|
242
261
|
msg_str = "Finished"
|
|
243
262
|
else:
|
|
244
|
-
msg_str = result.stderr
|
|
245
|
-
|
|
246
|
-
result_file = os.path.join(sub_temp_dir, "%s_Repair.pdb" % stem_name)
|
|
247
|
-
fxout_file = os.path.join(sub_temp_dir, "%s_Repair.fxout" % stem_name)
|
|
248
|
-
if os.path.exists(result_file) and os.path.exists(fxout_file):
|
|
249
|
-
move_with_overwrite(sub_temp_dir, out_dir, "%s_Repair.pdb" % stem_name)
|
|
250
|
-
move_with_overwrite(sub_temp_dir, out_dir, "%s_Repair.fxout" % stem_name)
|
|
251
|
-
except subprocess.CalledProcessError as e:
|
|
252
|
-
# Handle errors in the called executable
|
|
253
|
-
msg_str = e.stderr
|
|
263
|
+
msg_str = str(result.stderr)
|
|
254
264
|
except Exception as e:
|
|
255
|
-
|
|
256
|
-
|
|
265
|
+
msg_str = str(e)
|
|
266
|
+
else:
|
|
267
|
+
if msg_str == "Finished":
|
|
268
|
+
# just keep .pdb, ignore .fxout
|
|
269
|
+
result_file = os.path.join(temp_dir, "%s_Repair.pdb" % stem_name)
|
|
270
|
+
if os.path.exists(result_file):
|
|
271
|
+
shutil.move(result_file, output_file)
|
|
272
|
+
else:
|
|
273
|
+
msg_str = "result file not found"
|
|
257
274
|
finally:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
shutil.rmtree(sub_temp_dir)
|
|
275
|
+
if os.path.isdir(temp_dir):
|
|
276
|
+
shutil.rmtree(temp_dir)
|
|
261
277
|
end = time.time()
|
|
262
|
-
return dict(input=input_file, msg=msg_str, use_time=round(end - start, 1))
|
|
278
|
+
return dict(input=input_file, output=output_file, msg=msg_str, use_time=round(end - start, 1))
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
gemmi_protools/__init__.py,sha256=hwUw-EieCG0kwzHjTjzHF9Bc3D-J5R_l6G8PCcFegkw,331
|
|
2
2
|
gemmi_protools/io/__init__.py,sha256=F6e1xNT_7lZAWQgNIneH06o2qtWYrHNr_xPUPTwwx5E,29
|
|
3
|
-
gemmi_protools/io/cif_opts.py,sha256=
|
|
3
|
+
gemmi_protools/io/cif_opts.py,sha256=ZSZTbey3SvHyHaJ1T7m432Vg9oraYB1Jgay6ikIvWeQ,6779
|
|
4
4
|
gemmi_protools/io/convert.py,sha256=780sQcwhslUD4Hj5UZMVlQdbicniJ6jNjncTl_7jaMk,3841
|
|
5
5
|
gemmi_protools/io/parse_pdb_header.py,sha256=UOGMsE3-d3APhO7zaAEE0NT31n-iqt55VpDh_RPOicI,14223
|
|
6
|
-
gemmi_protools/io/parser.py,sha256=
|
|
6
|
+
gemmi_protools/io/parser.py,sha256=HFc4Kovr6rxEpLAEDUtF_e-RnA5OsWMeMFjuVNm7UYY,9507
|
|
7
7
|
gemmi_protools/io/pdb_opts.py,sha256=laUqxlecOe6goax12q8EJGZuZbHyIGsXVucMV3gVrgg,5741
|
|
8
8
|
gemmi_protools/io/peptide.py,sha256=a2wiEutJmvhl6gDCIzzqRCbmyknk2mwgy2FZ53lXclU,750
|
|
9
|
-
gemmi_protools/io/reader.py,sha256=
|
|
9
|
+
gemmi_protools/io/reader.py,sha256=lI9JTXqsct3D719qVN7Dsvg-zHudElojpW5-odtXa8A,16527
|
|
10
10
|
gemmi_protools/io/struct_info.py,sha256=9nBj1Zer03S8_Wks7L7uRlc9PlbfCKzoaT32pKR58X8,2769
|
|
11
11
|
gemmi_protools/utils/__init__.py,sha256=F6e1xNT_7lZAWQgNIneH06o2qtWYrHNr_xPUPTwwx5E,29
|
|
12
12
|
gemmi_protools/utils/align.py,sha256=CZcrvjy-ZbX2u7OAn-YGblbxaj9YFUDX4CFZcpbpnB8,6959
|
|
13
13
|
gemmi_protools/utils/dockq.py,sha256=XmMwVEy-H4p6sH_HPcDWA3TP77OWdih0fE_BQJDr4pU,4189
|
|
14
|
-
gemmi_protools/utils/fixer.py,sha256=
|
|
14
|
+
gemmi_protools/utils/fixer.py,sha256=RDmpoZpTrGdwuJQTTK1eif132MHV1I-T6Nt47ezgxTM,10236
|
|
15
15
|
gemmi_protools/utils/ppi.py,sha256=VWYsdxWwQoS1xwEYj5KB96Zz3F8r5Eyuw6NT3ReD-wc,2330
|
|
16
|
-
gemmi_protools-0.1.
|
|
17
|
-
gemmi_protools-0.1.
|
|
18
|
-
gemmi_protools-0.1.
|
|
19
|
-
gemmi_protools-0.1.
|
|
20
|
-
gemmi_protools-0.1.
|
|
16
|
+
gemmi_protools-0.1.10.dist-info/licenses/LICENSE,sha256=JuQvKcgj6n11y5y6nXr9rABv3gJSswc4eTCd5WZBtSY,1062
|
|
17
|
+
gemmi_protools-0.1.10.dist-info/METADATA,sha256=0xlRghvF1tEfCJi6OxLEGCIsJctUat4y2Sgt18tSrU0,568
|
|
18
|
+
gemmi_protools-0.1.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
gemmi_protools-0.1.10.dist-info/top_level.txt,sha256=P12mYJi5O5EKIn5u-RFaWxuix431CgLacSRD7rBid_U,15
|
|
20
|
+
gemmi_protools-0.1.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|