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 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())