arctic3d 0.4.1__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.
- arctic3d/__init__.py +12 -0
- arctic3d/cli.py +339 -0
- arctic3d/cli_blast.py +81 -0
- arctic3d/cli_localise.py +473 -0
- arctic3d/cli_resclust.py +206 -0
- arctic3d/cli_restraints.py +290 -0
- arctic3d/functions.py +16 -0
- arctic3d/modules/__init__.py +0 -0
- arctic3d/modules/blast.py +123 -0
- arctic3d/modules/cluster_interfaces.py +42 -0
- arctic3d/modules/clustering.py +270 -0
- arctic3d/modules/example_clustering.py +12 -0
- arctic3d/modules/example_get_interface.py +16 -0
- arctic3d/modules/example_interface_matrix.py +12 -0
- arctic3d/modules/input.py +12 -0
- arctic3d/modules/interface.py +345 -0
- arctic3d/modules/interface_matrix.py +337 -0
- arctic3d/modules/log.py +70 -0
- arctic3d/modules/output.py +595 -0
- arctic3d/modules/pdb.py +875 -0
- arctic3d/modules/sequence.py +52 -0
- arctic3d/version.py +3 -0
- arctic3d-0.4.1.dist-info/LICENSE +201 -0
- arctic3d-0.4.1.dist-info/METADATA +120 -0
- arctic3d-0.4.1.dist-info/RECORD +27 -0
- arctic3d-0.4.1.dist-info/WHEEL +4 -0
- arctic3d-0.4.1.dist-info/entry_points.txt +6 -0
arctic3d/__init__.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""arctic3d"""
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
log = logging.getLogger(__name__)
|
|
6
|
+
log.handlers.clear()
|
|
7
|
+
log.setLevel(logging.DEBUG)
|
|
8
|
+
handler = logging.StreamHandler(sys.stdout)
|
|
9
|
+
handler.setFormatter(
|
|
10
|
+
logging.Formatter("[%(asctime)s %(module)s %(levelname)s] %(message)s")
|
|
11
|
+
)
|
|
12
|
+
log.addHandler(handler)
|
arctic3d/cli.py
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"""Main CLI."""
|
|
2
|
+
import argparse
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from arctic3d import log
|
|
8
|
+
from arctic3d.modules.blast import run_blast
|
|
9
|
+
from arctic3d.modules.clustering import filter_clusters
|
|
10
|
+
from arctic3d.modules.cluster_interfaces import cluster_interfaces
|
|
11
|
+
from arctic3d.modules.input import Input
|
|
12
|
+
from arctic3d.modules.interface import (
|
|
13
|
+
get_interface_residues,
|
|
14
|
+
read_interface_residues,
|
|
15
|
+
)
|
|
16
|
+
from arctic3d.modules.output import (
|
|
17
|
+
get_init_message,
|
|
18
|
+
make_output,
|
|
19
|
+
create_output_folder,
|
|
20
|
+
setup_output_folder,
|
|
21
|
+
)
|
|
22
|
+
from arctic3d.modules.pdb import get_best_pdb
|
|
23
|
+
from arctic3d.modules.sequence import to_fasta
|
|
24
|
+
from arctic3d.modules.log import add_log_for_CLI
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
argument_parser = argparse.ArgumentParser()
|
|
28
|
+
argument_parser.add_argument(
|
|
29
|
+
"input_arg",
|
|
30
|
+
help="",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
argument_parser.add_argument(
|
|
34
|
+
"--db",
|
|
35
|
+
help="",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
argument_parser.add_argument(
|
|
39
|
+
"--interface_file",
|
|
40
|
+
help="input interface file",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
argument_parser.add_argument(
|
|
44
|
+
"--out_partner",
|
|
45
|
+
help="set of comma-separated partner IDs to exclude from the search",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
argument_parser.add_argument(
|
|
49
|
+
"--out_pdb",
|
|
50
|
+
help="set of comma-separated pdb IDs to exclude from the search",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
argument_parser.add_argument(
|
|
54
|
+
"--pdb_to_use",
|
|
55
|
+
help="pdb file to be used",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
argument_parser.add_argument(
|
|
59
|
+
"--chain_to_use",
|
|
60
|
+
help="the chain to be used",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
argument_parser.add_argument(
|
|
64
|
+
"--run_dir",
|
|
65
|
+
help="directory where to store the run",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
argument_parser.add_argument(
|
|
69
|
+
"--interface_data",
|
|
70
|
+
help=".json file containing the interface data",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
argument_parser.add_argument(
|
|
74
|
+
"--pdb_data",
|
|
75
|
+
help=".json file containing the pdb data",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
argument_parser.add_argument(
|
|
79
|
+
"--full",
|
|
80
|
+
help="consider full uniprot-pdb-chain information in the retrieval",
|
|
81
|
+
action="store_true",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
argument_parser.add_argument(
|
|
85
|
+
"--ligand",
|
|
86
|
+
help="retrieve ligand binding residues",
|
|
87
|
+
default="no",
|
|
88
|
+
choices=["yes", "no", "both"],
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
argument_parser.add_argument(
|
|
92
|
+
"--threshold",
|
|
93
|
+
help="Threshold for clustering",
|
|
94
|
+
type=float,
|
|
95
|
+
required=False,
|
|
96
|
+
default=0.866,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
argument_parser.add_argument(
|
|
100
|
+
"--linkage_strategy",
|
|
101
|
+
help="Linkage strategy for clustering",
|
|
102
|
+
type=str,
|
|
103
|
+
required=False,
|
|
104
|
+
choices=[
|
|
105
|
+
"average",
|
|
106
|
+
"single",
|
|
107
|
+
"complete",
|
|
108
|
+
"median",
|
|
109
|
+
"centroid",
|
|
110
|
+
"ward",
|
|
111
|
+
"weighted",
|
|
112
|
+
],
|
|
113
|
+
default="average",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
argument_parser.add_argument(
|
|
117
|
+
"--min_clust_size",
|
|
118
|
+
help="Minimum number of residues in clusters",
|
|
119
|
+
type=int,
|
|
120
|
+
required=False,
|
|
121
|
+
default=0,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
argument_parser.add_argument(
|
|
125
|
+
"--int_cov_cutoff",
|
|
126
|
+
help="Interface coverage cutoff (%%)",
|
|
127
|
+
type=float,
|
|
128
|
+
required=False,
|
|
129
|
+
default=0.7,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def load_args(arguments):
|
|
134
|
+
"""
|
|
135
|
+
Load argument parser.
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
arguments : argparse.ArgumentParser
|
|
140
|
+
Argument parser.
|
|
141
|
+
|
|
142
|
+
Returns
|
|
143
|
+
-------
|
|
144
|
+
cmd : argparse.Namespace
|
|
145
|
+
Parsed command-line arguments.
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
return arguments.parse_args()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def cli(arguments, main_func):
|
|
152
|
+
"""
|
|
153
|
+
Command-line interface entry point.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
arguments : argparse.ArgumentParser
|
|
158
|
+
Argument parser.
|
|
159
|
+
main_func : function
|
|
160
|
+
Main function.
|
|
161
|
+
|
|
162
|
+
"""
|
|
163
|
+
cmd = load_args(arguments)
|
|
164
|
+
return main_func(**vars(cmd))
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def maincli():
|
|
168
|
+
"""Execute main client."""
|
|
169
|
+
return cli(argument_parser, main)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def main(
|
|
173
|
+
input_arg,
|
|
174
|
+
db,
|
|
175
|
+
interface_file,
|
|
176
|
+
out_partner,
|
|
177
|
+
out_pdb,
|
|
178
|
+
pdb_to_use,
|
|
179
|
+
chain_to_use,
|
|
180
|
+
run_dir,
|
|
181
|
+
interface_data,
|
|
182
|
+
pdb_data,
|
|
183
|
+
full,
|
|
184
|
+
ligand,
|
|
185
|
+
linkage_strategy,
|
|
186
|
+
threshold,
|
|
187
|
+
min_clust_size,
|
|
188
|
+
int_cov_cutoff,
|
|
189
|
+
log_level="DEBUG",
|
|
190
|
+
):
|
|
191
|
+
"""Main function."""
|
|
192
|
+
init_message = get_init_message()
|
|
193
|
+
log.info(init_message)
|
|
194
|
+
st_time = time.time()
|
|
195
|
+
inp = Input(input_arg)
|
|
196
|
+
input_files = {}
|
|
197
|
+
# retrieve uniprot information
|
|
198
|
+
if inp.is_fasta():
|
|
199
|
+
input_files["fasta"] = Path(inp.arg)
|
|
200
|
+
uniprot_id = run_blast(input_files["fasta"], db)
|
|
201
|
+
if inp.is_uniprot():
|
|
202
|
+
uniprot_id = inp.arg.upper()
|
|
203
|
+
if inp.is_pdb():
|
|
204
|
+
input_files["pdb"] = Path(inp.arg)
|
|
205
|
+
if not interface_file:
|
|
206
|
+
fasta_f = to_fasta(input_files["pdb"], temp=False)
|
|
207
|
+
uniprot_id = run_blast(fasta_f.name, db)
|
|
208
|
+
else:
|
|
209
|
+
input_files["interface_file"] = Path(interface_file)
|
|
210
|
+
uniprot_id = None
|
|
211
|
+
|
|
212
|
+
# create output folder
|
|
213
|
+
run_dir_path = create_output_folder(run_dir, uniprot_id)
|
|
214
|
+
# configure logging
|
|
215
|
+
log_file = Path(run_dir_path, "arctic3d.log")
|
|
216
|
+
add_log_for_CLI(log, log_level, log_file)
|
|
217
|
+
|
|
218
|
+
log.info(f"Target UNIPROTID: {uniprot_id}")
|
|
219
|
+
|
|
220
|
+
# save json files
|
|
221
|
+
if interface_data:
|
|
222
|
+
input_files["interface_data"] = Path(interface_data)
|
|
223
|
+
if pdb_data:
|
|
224
|
+
input_files["pdb_data"] = Path(pdb_data)
|
|
225
|
+
|
|
226
|
+
input_files = setup_output_folder(
|
|
227
|
+
run_dir=run_dir_path, input_files=input_files
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
# retrieve interfaces.
|
|
231
|
+
if "interface_file" in input_files:
|
|
232
|
+
log.info(f"input interface file {interface_file}")
|
|
233
|
+
interface_residues = read_interface_residues(
|
|
234
|
+
input_files["interface_file"]
|
|
235
|
+
)
|
|
236
|
+
else:
|
|
237
|
+
if interface_file:
|
|
238
|
+
log.warning(
|
|
239
|
+
"input interface file submitted without pdb. It will be"
|
|
240
|
+
" ignored."
|
|
241
|
+
)
|
|
242
|
+
if interface_data:
|
|
243
|
+
int_data_path = input_files["interface_data"]
|
|
244
|
+
else:
|
|
245
|
+
int_data_path = None
|
|
246
|
+
interface_residues = get_interface_residues(
|
|
247
|
+
uniprot_id=uniprot_id,
|
|
248
|
+
out_partner_string=out_partner,
|
|
249
|
+
out_pdb_string=out_pdb,
|
|
250
|
+
full=full,
|
|
251
|
+
ligand=ligand,
|
|
252
|
+
interface_data=int_data_path,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
log.info(f"Interface Residues: {interface_residues}")
|
|
256
|
+
|
|
257
|
+
if interface_residues:
|
|
258
|
+
# retrieve pdb file
|
|
259
|
+
if inp.is_pdb():
|
|
260
|
+
# interfaces will be filtered later
|
|
261
|
+
pdb_f, filtered_interfaces = input_files["pdb"], None
|
|
262
|
+
if not interface_file:
|
|
263
|
+
log.warning(
|
|
264
|
+
(
|
|
265
|
+
"Input pdb file submitted without interface file. "
|
|
266
|
+
"This assumes the pdb is coherent with the "
|
|
267
|
+
"corresponding uniprot numbering."
|
|
268
|
+
)
|
|
269
|
+
)
|
|
270
|
+
else:
|
|
271
|
+
if pdb_data:
|
|
272
|
+
pdb_data_path = input_files["pdb_data"]
|
|
273
|
+
else:
|
|
274
|
+
pdb_data_path = None
|
|
275
|
+
# get best pdb
|
|
276
|
+
pdb_f, cif_f, filtered_interfaces = get_best_pdb(
|
|
277
|
+
uniprot_id=uniprot_id,
|
|
278
|
+
interface_residues=interface_residues,
|
|
279
|
+
pdb_to_use=pdb_to_use,
|
|
280
|
+
chain_to_use=chain_to_use,
|
|
281
|
+
pdb_data=pdb_data_path,
|
|
282
|
+
int_cov_cutoff=int_cov_cutoff,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
if pdb_f is None:
|
|
286
|
+
log.error(
|
|
287
|
+
"Could not retrieve a valid PDB for the target, please provide"
|
|
288
|
+
" one as the main input argument."
|
|
289
|
+
)
|
|
290
|
+
sys.exit()
|
|
291
|
+
|
|
292
|
+
log.info(f"PDB file: {pdb_f}")
|
|
293
|
+
|
|
294
|
+
# cluster interfaces
|
|
295
|
+
if filtered_interfaces:
|
|
296
|
+
interface_dict = filtered_interfaces
|
|
297
|
+
else:
|
|
298
|
+
interface_dict = interface_residues
|
|
299
|
+
cl_dict, cl_residues, cl_residues_probs = cluster_interfaces(
|
|
300
|
+
interface_dict=interface_dict,
|
|
301
|
+
pdb_path=pdb_f,
|
|
302
|
+
linkage_strategy=linkage_strategy,
|
|
303
|
+
threshold=threshold,
|
|
304
|
+
int_cov_cutoff=int_cov_cutoff,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
log.info(f"Clustered interfaces {cl_dict}")
|
|
308
|
+
log.info(f"Clustered interface residues: {cl_residues}")
|
|
309
|
+
if min_clust_size > 0:
|
|
310
|
+
log.info(
|
|
311
|
+
f"Excluding clusters with less than {min_clust_size} residues"
|
|
312
|
+
)
|
|
313
|
+
cl_dict, cl_residues, cl_residues_probs = filter_clusters(
|
|
314
|
+
cl_dict, cl_residues, cl_residues_probs, min_clust_size
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
make_output(
|
|
318
|
+
interface_residues=interface_residues,
|
|
319
|
+
pdb_f=pdb_f,
|
|
320
|
+
cl_dict=cl_dict,
|
|
321
|
+
cl_residues=cl_residues,
|
|
322
|
+
cl_residues_probs=cl_residues_probs,
|
|
323
|
+
)
|
|
324
|
+
else:
|
|
325
|
+
log.info("No interfaces found.")
|
|
326
|
+
|
|
327
|
+
log.info(
|
|
328
|
+
f"arctic3d run completed in {(time.time() - st_time):.2f} seconds."
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
# check if there's at least one interface
|
|
332
|
+
if Path("clustered_interfaces.out").is_file() is False:
|
|
333
|
+
return 255
|
|
334
|
+
|
|
335
|
+
return 0
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
if __name__ == "__main__":
|
|
339
|
+
sys.exit(maincli())
|
arctic3d/cli_blast.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Main CLI."""
|
|
2
|
+
import argparse
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from arctic3d.modules.blast import run_blast
|
|
8
|
+
from arctic3d.modules.sequence import to_fasta
|
|
9
|
+
|
|
10
|
+
log = logging.getLogger("arctic3dlog")
|
|
11
|
+
ch = logging.StreamHandler()
|
|
12
|
+
formatter = logging.Formatter(
|
|
13
|
+
" [%(asctime)s %(module)s:L%(lineno)d %(levelname)s] %(message)s"
|
|
14
|
+
)
|
|
15
|
+
ch.setFormatter(formatter)
|
|
16
|
+
log.addHandler(ch)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
argument_parser = argparse.ArgumentParser()
|
|
20
|
+
argument_parser.add_argument("input_pdbs", nargs="+", default=[])
|
|
21
|
+
|
|
22
|
+
argument_parser.add_argument(
|
|
23
|
+
"--db",
|
|
24
|
+
help="",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def load_args(arguments):
|
|
29
|
+
"""
|
|
30
|
+
Load argument parser.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
arguments : argparse.ArgumentParser
|
|
35
|
+
Argument parser.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
cmd : argparse.Namespace
|
|
40
|
+
Parsed command-line arguments.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
return arguments.parse_args()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def cli(arguments, main_func):
|
|
47
|
+
"""
|
|
48
|
+
Command-line interface entry point.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
arguments : argparse.ArgumentParser
|
|
53
|
+
Argument parser.
|
|
54
|
+
main_func : function
|
|
55
|
+
Main function.
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
cmd = load_args(arguments)
|
|
59
|
+
main_func(**vars(cmd))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def maincli():
|
|
63
|
+
"""Execute main client."""
|
|
64
|
+
cli(argument_parser, main)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def main(input_pdbs, db):
|
|
68
|
+
"""Main function."""
|
|
69
|
+
log.setLevel("DEBUG")
|
|
70
|
+
|
|
71
|
+
with open("uniprot.csv", "w") as fh:
|
|
72
|
+
for pdb in input_pdbs:
|
|
73
|
+
fasta_f = to_fasta(pdb, temp=True)
|
|
74
|
+
uniprot_id = run_blast(fasta_f.name, db)
|
|
75
|
+
Path(fasta_f.name).unlink()
|
|
76
|
+
log.info(f"pdb: {pdb} uniprot_id: {uniprot_id}")
|
|
77
|
+
fh.write(f"{pdb},{uniprot_id}\n")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == "__main__":
|
|
81
|
+
sys.exit(maincli())
|