drep 4.0.2__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.
@@ -0,0 +1,181 @@
1
+ import glob
2
+ import logging
3
+ import os
4
+ import shutil
5
+ import sys
6
+ import pandas as pd
7
+
8
+ import drep.d_cluster.external
9
+ import drep.d_cluster.compare_utils
10
+
11
+ def greedy_secondary_clustering(Bdb, Cdb, algorithm, data_folder, **kwargs):
12
+ ndbs = []
13
+ cdbs = []
14
+ c2ret = {}
15
+ for bdb, name in drep.d_cluster.compare_utils.iteratre_clusters(Bdb, Cdb, id='primary_cluster'):
16
+ logging.debug('running cluster {0} with {1} genomes'.format(name, len(bdb)))
17
+ # logging.debug('total memory - {0:.2f} Mbp'.format(int(process.memory_info().rss)/1000000))
18
+ ndb, cdb, ret = drep.d_cluster.compare_utils.compare_genomes(bdb, algorithm, data_folder, **kwargs)
19
+
20
+ if len(ndb) == 0:
21
+ logging.error("CRITICAL ERROR WITH PRIMARY CLUSTER {0}; TRYING AGAIN".format(name))
22
+ ndb, cdb, ret = drep.d_cluster.compare_utils.compare_genomes(bdb, algorithm, data_folder, **kwargs)
23
+
24
+ if len(ndb) > 0:
25
+ ndb['primary_cluster'] = name
26
+ cdb['primary_cluster'] = name
27
+ cdb['secondary_cluster'] = ["{0}{1}".format(name, y) for y in cdb['secondary_cluster']]
28
+ ndbs.append(ndb)
29
+ cdbs.append(cdb)
30
+ c2ret[name] = ret
31
+ else:
32
+ logging.error("DOUBLE CRITICAL ERROR AGAIN WITH PRIMARY CLUSTER {0}; SKIPPING".format(name))
33
+
34
+ Ndb = pd.concat(ndbs).reset_index(drop=True)
35
+ Cdb = pd.concat(cdbs).reset_index(drop=True)
36
+ return Ndb, Cdb, c2ret
37
+
38
+
39
+ def compare_genomes_greedy(bdb, algorithm, data_folder, **kwargs):
40
+ ani_thresh = float(kwargs.get('S_ani', .99))
41
+ cov_thresh = float(kwargs.get('cov_thresh', 0.5))
42
+
43
+ assert (ani_thresh <= 1) & (ani_thresh > 0)
44
+
45
+ # Set genome order
46
+ odb = order_genomes_for_greedy(bdb, **kwargs)
47
+
48
+ # Set up
49
+ cluster = kwargs.get('cluster', '')
50
+ genome_rep_file = os.path.join(data_folder + 'representative_genome_locations.txt')
51
+ genome_reps = []
52
+ rep2cluster = {}
53
+ genome2cluster = {}
54
+ ndbs = []
55
+
56
+ if os.path.exists(genome_rep_file):
57
+ os.remove(genome_rep_file)
58
+
59
+ # Prepare for greedy clustering
60
+ kwargs = prepare_for_greedy(algorithm, data_folder, **kwargs)
61
+
62
+ # Iterate
63
+ j = 1
64
+ for i, row in odb.iterrows():
65
+ if len(genome_reps) == 0:
66
+ make_new_cluster = True
67
+
68
+ else:
69
+ ndb = genome_vs_reps(row['location'], genome_reps, genome_rep_file, algorithm, data_folder, **kwargs)
70
+ ndbs.append(ndb)
71
+
72
+ cluster_rep = get_cluster_rep(ndb, ani_thresh, cov_thresh)
73
+
74
+ if cluster_rep is not False:
75
+ make_new_cluster = False
76
+ assert cluster_rep in rep2cluster, [cluster_rep, rep2cluster]
77
+ genome2cluster[row['genome']] = rep2cluster[cluster_rep]
78
+ else:
79
+ make_new_cluster = True
80
+
81
+ if make_new_cluster:
82
+ new_cluster = "{0}_{1}".format(cluster,j)
83
+ j += 1
84
+
85
+ genome_reps.append(row['location'])
86
+ rep2cluster[row['genome']] = new_cluster
87
+ genome2cluster[row['genome']] = new_cluster
88
+ with open(genome_rep_file, "a") as myfile:
89
+ myfile.write(row['location'] + '\n')
90
+ add_genome_as_rep(row['location'], algorithm, **kwargs)
91
+
92
+ if len(ndbs) > 0:
93
+ Ndb = pd.concat(ndbs)
94
+
95
+ else:
96
+ # Add self-comparisons if there is only one genome
97
+ Table = {'querry': [], 'reference': [], 'ani': [], 'alignment_coverage': []}
98
+ for g in odb['location'].tolist():
99
+ Table['reference'].append(drep.d_cluster.utils._get_genome_name_from_fasta(g))
100
+ Table['querry'].append(drep.d_cluster.utils._get_genome_name_from_fasta(g))
101
+ Table['ani'].append(1)
102
+ Table['alignment_coverage'].append(1)
103
+ Ndb = pd.DataFrame(Table)
104
+
105
+ Cdb, cluster_ret = generate_greedy_cdb(bdb, rep2cluster, genome2cluster, algorithm, ani_thresh, cov_thresh, **kwargs)
106
+ return Ndb, Cdb, cluster_ret
107
+
108
+ def genome_vs_reps(new_genome, genome_reps, genome_rep_file, algorithm, data_folder, **kwargs):
109
+ if algorithm == 'fastANI':
110
+ # NOTE: this spawns a subprocess that re-sketches every representative on
111
+ # every call, so sketching is O(N*R). Greedy exists to avoid O(n^2)
112
+ # comparisons within a primary cluster; --primary_algorithm skani avoids
113
+ # that quadratic in the first place by only ever producing
114
+ # above-threshold pairs, and is usually the better answer at scale.
115
+ return drep.d_cluster.external.fastani_one_vs_many(new_genome, genome_reps, genome_rep_file, data_folder, **kwargs)
116
+ else:
117
+ logging.error("{0} algorithm is not yet supported for greedy clustering; sorry!".format(algorithm))
118
+ assert False
119
+
120
+
121
+ def add_genome_as_rep(location, algorithm, **kwargs):
122
+ """
123
+ Register a genome as a new cluster representative.
124
+
125
+ Subprocess-based algorithms read the representative list from a file, which
126
+ compare_genomes_greedy has already written, so there is nothing to do here.
127
+ Kept as a hook for backends that need to index representatives as they appear.
128
+ """
129
+ return
130
+
131
+
132
+ def prepare_for_greedy(algorithm, data_folder, **kwargs):
133
+ # Every algorithm writes the running list of representatives here, so the
134
+ # folder has to exist regardless of which one is in use.
135
+ if not os.path.exists(data_folder):
136
+ os.makedirs(data_folder)
137
+
138
+ if algorithm == 'fastANI':
139
+ # Make folders
140
+ tmp_dir = os.path.join(data_folder, 'tmp/')
141
+ if not os.path.exists(tmp_dir):
142
+ os.makedirs(tmp_dir)
143
+
144
+ # Handle log directory
145
+ if ('wd' in kwargs) and (kwargs.get('debug', False)):
146
+ logdir = kwargs.get('wd').get_dir('cmd_logs')
147
+ else:
148
+ logdir = False
149
+
150
+ kwargs['tmp_dir'] = tmp_dir
151
+ kwargs['logdir'] = logdir
152
+ kwargs['current_exe'] = drep.get_exe('fastANI')
153
+
154
+ return kwargs
155
+
156
+ def order_genomes_for_greedy(bdb, **kwargs):
157
+ return bdb.sort_values('length', ascending=False)
158
+
159
+ def get_cluster_rep(ndb, ani_thresh, cov_thresh):
160
+ fdb = ndb[(ndb['ani'] >= ani_thresh) & (ndb['alignment_coverage'] >= cov_thresh)]
161
+ if len(fdb) > 0:
162
+ return fdb['querry'].iloc[0]
163
+ else:
164
+ return False
165
+
166
+ def generate_greedy_cdb(bdb, rep2cluster, genome2cluster, algorithm, ani_thresh, c_thresh, **kwargs):
167
+ reps = set(list(rep2cluster.keys()))
168
+
169
+ cdb = bdb[['genome']]
170
+ cdb['secondary_cluster'] = cdb['genome'].map(genome2cluster)
171
+ cdb['threshold'] = 1 - ani_thresh
172
+ cdb['cluster_method'] = 'greedy'
173
+ cdb['comparison_algorithm'] = algorithm
174
+ cdb['greedy_representative'] = [g in reps for g in cdb['genome']]
175
+
176
+ arguments = {'linkage_method': 'greedy', 'linkage_cutoff': ani_thresh,
177
+ 'comparison_algorithm': algorithm, 'minimum_coverage': c_thresh}
178
+ cluster_ret = [None, pd.DataFrame(), arguments]
179
+
180
+ return cdb, cluster_ret
181
+
File without changes