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.
- drep/VERSION +1 -0
- drep/WorkDirectory.py +355 -0
- drep/__init__.py +101 -0
- drep/argumentParser.py +279 -0
- drep/controller.py +105 -0
- drep/d_adjust.py +272 -0
- drep/d_analyze.py +1613 -0
- drep/d_bonus.py +429 -0
- drep/d_choose.py +362 -0
- drep/d_cluster/__init__.py +0 -0
- drep/d_cluster/cluster_utils.py +126 -0
- drep/d_cluster/compare_utils.py +636 -0
- drep/d_cluster/controller.py +228 -0
- drep/d_cluster/external.py +765 -0
- drep/d_cluster/greedy_clustering.py +181 -0
- drep/d_cluster/parsers.py +0 -0
- drep/d_cluster/union_find.py +543 -0
- drep/d_cluster/utils.py +687 -0
- drep/d_evaluate.py +355 -0
- drep/d_filter.py +831 -0
- drep/d_workflows.py +135 -0
- drep-4.0.2.data/scripts/ScaffoldLevel_dRep.py +1101 -0
- drep-4.0.2.data/scripts/dRep +32 -0
- drep-4.0.2.data/scripts/parse_stb.py +140 -0
- drep-4.0.2.dist-info/METADATA +23 -0
- drep-4.0.2.dist-info/RECORD +28 -0
- drep-4.0.2.dist-info/WHEEL +5 -0
- drep-4.0.2.dist-info/top_level.txt +1 -0
|
@@ -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
|