drep 3.4.5__tar.gz → 3.6.1__tar.gz
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-3.4.5 → drep-3.6.1}/PKG-INFO +9 -1
- {drep-3.4.5 → drep-3.6.1}/README.md +1 -1
- drep-3.6.1/drep/VERSION +1 -0
- {drep-3.4.5 → drep-3.6.1}/drep/__init__.py +1 -1
- {drep-3.4.5 → drep-3.6.1}/drep/argumentParser.py +8 -2
- {drep-3.4.5 → drep-3.6.1}/drep/d_analyze.py +10 -10
- {drep-3.4.5 → drep-3.6.1}/drep/d_bonus.py +1 -1
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/cluster_utils.py +58 -19
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/compare_utils.py +10 -1
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/external.py +104 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/utils.py +3 -1
- {drep-3.4.5 → drep-3.6.1}/drep/d_filter.py +38 -24
- {drep-3.4.5 → drep-3.6.1}/drep.egg-info/PKG-INFO +9 -1
- {drep-3.4.5 → drep-3.6.1}/drep.egg-info/SOURCES.txt +3 -1
- {drep-3.4.5 → drep-3.6.1}/helper_scripts/ScaffoldLevel_dRep.py +106 -45
- {drep-3.4.5 → drep-3.6.1}/helper_scripts/parse_stb.py +48 -39
- drep-3.6.1/pyproject.toml +3 -0
- drep-3.6.1/tests/test_suite.py +30 -0
- drep-3.4.5/drep/VERSION +0 -1
- {drep-3.4.5 → drep-3.6.1}/bin/dRep +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/WorkDirectory.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/controller.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_adjust.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_choose.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/__init__.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/controller.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/greedy_clustering.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_cluster/parsers.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_evaluate.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep/d_workflows.py +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep.egg-info/dependency_links.txt +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep.egg-info/not-zip-safe +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep.egg-info/requires.txt +0 -0
- {drep-3.4.5 → drep-3.6.1}/drep.egg-info/top_level.txt +0 -0
- {drep-3.4.5 → drep-3.6.1}/setup.cfg +0 -0
- {drep-3.4.5 → drep-3.6.1}/setup.py +0 -0
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: drep
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.1
|
|
4
4
|
Summary: De-replication of microbial genomes assembled from multiple samples
|
|
5
5
|
Home-page: https://github.com/MrOlm/drep
|
|
6
6
|
Author: Matt Olm
|
|
7
7
|
Author-email: mattolm@berkeley.edu
|
|
8
8
|
License: MIT
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: pandas
|
|
11
|
+
Requires-Dist: seaborn
|
|
12
|
+
Requires-Dist: matplotlib
|
|
13
|
+
Requires-Dist: biopython
|
|
14
|
+
Requires-Dist: scikit-learn
|
|
15
|
+
Requires-Dist: tqdm
|
|
16
|
+
Requires-Dist: pytest
|
|
@@ -9,7 +9,7 @@ Manual, installation instructions, and API are at available at
|
|
|
9
9
|
[ReadTheDocs](https://drep.readthedocs.io/en/latest/)
|
|
10
10
|
|
|
11
11
|
Publication is available at
|
|
12
|
-
[ISMEJ](
|
|
12
|
+
[ISMEJ](https://doi.org/10.1038/ismej.2017.126)
|
|
13
13
|
|
|
14
14
|
Open source pre-print publication is available at
|
|
15
15
|
[bioRxiv](https://doi.org/10.1101/108142)
|
drep-3.6.1/drep/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.6.1
|
|
@@ -44,7 +44,7 @@ def printHelp():
|
|
|
44
44
|
print(' ...::: dRep v' + VERSION + ' :::...''')
|
|
45
45
|
print('''\
|
|
46
46
|
|
|
47
|
-
Matt Olm. MIT License. Banfield Lab, UC Berkeley. 2017 (last updated
|
|
47
|
+
Matt Olm. MIT License. Banfield Lab, UC Berkeley. 2017 (last updated 2025)
|
|
48
48
|
|
|
49
49
|
See https://drep.readthedocs.io/en/latest/index.html for documentation
|
|
50
50
|
Choose one of the operations below for more detailed help.
|
|
@@ -115,16 +115,20 @@ def parse_args(args):
|
|
|
115
115
|
Clustflags = cluster_parent.add_argument_group('GENOME COMPARISON OPTIONS')
|
|
116
116
|
Clustflags.add_argument("--S_algorithm", help="R|Algorithm for secondary clustering comaprisons:\n" \
|
|
117
117
|
+ "fastANI = Kmer-based approach; very fast\n" \
|
|
118
|
+
+ "skani = Even faster Kmer-based approacht\n" \
|
|
118
119
|
+ "ANImf = (DEFAULT) Align whole genomes with nucmer; filter alignment; compare aligned regions\n" \
|
|
119
120
|
+ "ANIn = Align whole genomes with nucmer; compare aligned regions\n" \
|
|
120
121
|
+ "gANI = Identify and align ORFs; compare aligned ORFS\n" \
|
|
121
122
|
+ "goANI = Open source version of gANI; requires nsmimscan\n",
|
|
122
|
-
default='fastANI', choices={'ANIn', 'gANI', 'ANImf', 'goANI', 'fastANI'})
|
|
123
|
+
default='fastANI', choices={'ANIn', 'gANI', 'ANImf', 'goANI', 'fastANI', 'skani'})
|
|
123
124
|
Clustflags.add_argument("-ms", "--MASH_sketch", help="MASH sketch size", default=1000)
|
|
124
125
|
Clustflags.add_argument("--SkipMash", help="Skip MASH clustering,\
|
|
125
126
|
just do secondary clustering on all genomes", action='store_true')
|
|
126
127
|
Clustflags.add_argument("--SkipSecondary", help="Skip secondary clustering, just perform MASH\
|
|
127
128
|
clustering", action='store_true')
|
|
129
|
+
Clustflags.add_argument("--skani_extra",
|
|
130
|
+
help="Extra arguments to pass to skani triangle",
|
|
131
|
+
default="", type=str)
|
|
128
132
|
Clustflags.add_argument("--n_PRESET", help="R|Presets to pass to nucmer\n" \
|
|
129
133
|
+ "tight = only align highly conserved regions\n" \
|
|
130
134
|
+ "normal = default ANIn parameters", choices=['normal', 'tight'],
|
|
@@ -145,6 +149,8 @@ def parse_args(args):
|
|
|
145
149
|
Compflags.add_argument("--clusterAlg", help="Algorithm used to cluster genomes (passed\
|
|
146
150
|
to scipy.cluster.hierarchy.linkage", default='average',
|
|
147
151
|
choices={'single', 'complete', 'average', 'weighted', 'centroid', 'median', 'ward'})
|
|
152
|
+
Compflags.add_argument("--low_ram_primary_clustering", help="Use a memory-efficient algorithm for primary clustering. This only affects primary clustering and not secondary clustering.",
|
|
153
|
+
action='store_true', default=False)
|
|
148
154
|
|
|
149
155
|
GRflags = cluster_parent.add_argument_group('GREEDY CLUSTERING OPTIONS\n'
|
|
150
156
|
'These decrease RAM use and runtime at the expense of a minor loss in '
|
|
@@ -728,11 +728,11 @@ def plot_winner_scoring_complex(Wdb, Sdb, Cdb, Gdb, plot_dir= False, **kwargs):
|
|
|
728
728
|
for variable in x['variable'].unique():
|
|
729
729
|
vals += [v for v in x['value'][x['variable'] == variable].tolist()]
|
|
730
730
|
|
|
731
|
-
# Add un-normalized values to barplots
|
|
732
|
-
i = 0
|
|
733
|
-
for p in g.patches:
|
|
734
|
-
|
|
735
|
-
|
|
731
|
+
# # Add un-normalized values to barplots
|
|
732
|
+
# i = 0
|
|
733
|
+
# for p in g.patches:
|
|
734
|
+
# g.annotate("{0:.1f}".format(vals[i]), (p.get_width(), p.get_y()+(p.get_height()/1.1) ), fontsize=8)
|
|
735
|
+
# i += 1
|
|
736
736
|
|
|
737
737
|
plt.title('Scoring of cluster {0}'.format(cluster))
|
|
738
738
|
plt.xlabel('Normalized Score')
|
|
@@ -1378,11 +1378,11 @@ def _make_scoring_plot(db, bars,**kwargs):
|
|
|
1378
1378
|
for variable in x['variable'].unique():
|
|
1379
1379
|
vals += [v for v in x['value'][x['variable'] == variable].tolist()]
|
|
1380
1380
|
|
|
1381
|
-
# Add un-normalized values to barplots
|
|
1382
|
-
i = 0
|
|
1383
|
-
for p in g.patches:
|
|
1384
|
-
|
|
1385
|
-
|
|
1381
|
+
# # Add un-normalized values to barplots
|
|
1382
|
+
# i = 0
|
|
1383
|
+
# for p in g.patches:
|
|
1384
|
+
# g.annotate("{0:.1f}".format(vals[i]), (p.get_width(), p.get_y()+(p.get_height()/1.1) ), fontsize=8)
|
|
1385
|
+
# i += 1
|
|
1386
1386
|
|
|
1387
1387
|
# Add taxonomy if available
|
|
1388
1388
|
axes = plt.gca()
|
|
@@ -98,7 +98,7 @@ def check_dependencies(print_out=False):
|
|
|
98
98
|
For all possible dependencies, see if you can find them
|
|
99
99
|
'''
|
|
100
100
|
for dep in ['mash', 'nucmer', 'checkm', 'ANIcalculator', 'prodigal', 'centrifuge',
|
|
101
|
-
'nsimscan', 'fastANI']:
|
|
101
|
+
'nsimscan', 'fastANI', 'skani']:
|
|
102
102
|
loc, works = find_program(dep)
|
|
103
103
|
works_message = {True:'all good', False:'!!! ERROR !!!'}[works]
|
|
104
104
|
message = '{0:.<40} {1:15} (location = {2})'.format(dep, works_message, loc)
|
|
@@ -6,6 +6,7 @@ import numpy as np
|
|
|
6
6
|
import pandas as pd
|
|
7
7
|
import scipy.cluster
|
|
8
8
|
from scipy.spatial import distance as ssd
|
|
9
|
+
import networkx as nx
|
|
9
10
|
|
|
10
11
|
import drep.d_cluster.utils
|
|
11
12
|
|
|
@@ -87,7 +88,33 @@ def iteratre_clusters(Bdb, Cdb, id='primary_cluster'):
|
|
|
87
88
|
yield d, cluster
|
|
88
89
|
|
|
89
90
|
|
|
90
|
-
def
|
|
91
|
+
def cluster_threshold_graph_optimized(db, linkage_cutoff=0.10, linkage_method='single'):
|
|
92
|
+
# Filter distances below threshold first
|
|
93
|
+
filtered_edges = db[db['dist'] <= linkage_cutoff]
|
|
94
|
+
|
|
95
|
+
# Create graph directly from filtered edges
|
|
96
|
+
G = nx.Graph()
|
|
97
|
+
G.add_edges_from(filtered_edges[['genome1', 'genome2']].values)
|
|
98
|
+
|
|
99
|
+
# Log that we're using the optimized method
|
|
100
|
+
logging.debug("Using low-RAM optimized clustering method with {0} edges".format(len(filtered_edges)))
|
|
101
|
+
|
|
102
|
+
# Find connected components
|
|
103
|
+
clusters = {}
|
|
104
|
+
for cluster_id, component in enumerate(nx.connected_components(G)):
|
|
105
|
+
for genome in component:
|
|
106
|
+
clusters[genome] = cluster_id + 1
|
|
107
|
+
|
|
108
|
+
# Add isolated nodes (if needed)
|
|
109
|
+
all_genomes = set(db['genome1']).union(set(db['genome2']))
|
|
110
|
+
for genome in all_genomes:
|
|
111
|
+
if genome not in clusters:
|
|
112
|
+
clusters[genome] = len(clusters)
|
|
113
|
+
|
|
114
|
+
# Return clusters and a special value indicating we used the optimized method
|
|
115
|
+
return clusters, "optimized_method_used"
|
|
116
|
+
|
|
117
|
+
def cluster_hierarchical(db, linkage_method= 'single', linkage_cutoff= 0.10, low_ram=False):
|
|
91
118
|
'''
|
|
92
119
|
Perform hierarchical clustering on a symmetrical distiance matrix
|
|
93
120
|
|
|
@@ -95,6 +122,7 @@ def cluster_hierarchical(db, linkage_method= 'single', linkage_cutoff= 0.10):
|
|
|
95
122
|
db: result of db.pivot usually
|
|
96
123
|
linkage_method: passed to scipy.cluster.hierarchy.fcluster
|
|
97
124
|
linkage_cutoff: distance to draw the clustering line (default = .1)
|
|
125
|
+
low_ram: whether to use the memory-efficient algorithm
|
|
98
126
|
|
|
99
127
|
Returns:
|
|
100
128
|
list: [Cdb, linkage]
|
|
@@ -102,21 +130,32 @@ def cluster_hierarchical(db, linkage_method= 'single', linkage_cutoff= 0.10):
|
|
|
102
130
|
# Save names
|
|
103
131
|
names = list(db.columns)
|
|
104
132
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
if low_ram:
|
|
134
|
+
# Convert to long format for optimized clustering
|
|
135
|
+
db_long = db.stack().reset_index()
|
|
136
|
+
db_long.columns = ['genome1', 'genome2', 'dist']
|
|
137
|
+
clusters, _ = cluster_threshold_graph_optimized(db_long, linkage_cutoff, linkage_method)
|
|
138
|
+
|
|
139
|
+
# Convert clusters to Cdb format
|
|
140
|
+
Cdb = pd.DataFrame({'genome': list(clusters.keys()),
|
|
141
|
+
'cluster': list(clusters.values())})
|
|
142
|
+
return Cdb, _
|
|
143
|
+
else:
|
|
144
|
+
# Generate linkage dataframe
|
|
145
|
+
arr = np.asarray(db)
|
|
146
|
+
try:
|
|
147
|
+
arr = ssd.squareform(arr)
|
|
148
|
+
except:
|
|
149
|
+
logging.error("The database passed in is not symmetrical!")
|
|
150
|
+
logging.error(arr)
|
|
151
|
+
logging.error(names)
|
|
152
|
+
sys.exit()
|
|
153
|
+
linkage = scipy.cluster.hierarchy.linkage(arr, method= linkage_method)
|
|
154
|
+
|
|
155
|
+
# Form clusters
|
|
156
|
+
fclust = scipy.cluster.hierarchy.fcluster(linkage,linkage_cutoff, \
|
|
157
|
+
criterion='distance')
|
|
158
|
+
# Make Cdb
|
|
159
|
+
Cdb = drep.d_cluster.utils._gen_cdb_from_fclust(fclust,names)
|
|
160
|
+
|
|
161
|
+
return Cdb, linkage
|
|
@@ -264,6 +264,7 @@ def cluster_mash_database(db, **kwargs):
|
|
|
264
264
|
Keyword arguments:
|
|
265
265
|
clusterAlg: how to cluster database (default = single)
|
|
266
266
|
P_ani: threshold to cluster at (default = 0.9)
|
|
267
|
+
low_ram_primary_clustering: whether to use memory-efficient algorithm
|
|
267
268
|
|
|
268
269
|
Returns:
|
|
269
270
|
list: [Cdb, [linkage, linkage_db, arguments]]
|
|
@@ -273,12 +274,13 @@ def cluster_mash_database(db, **kwargs):
|
|
|
273
274
|
# Load key words
|
|
274
275
|
P_Lmethod = kwargs.get('clusterAlg','single')
|
|
275
276
|
P_Lcutoff = 1 - kwargs.get('P_ani',.9)
|
|
277
|
+
low_ram = kwargs.get('low_ram_primary_clustering', False)
|
|
276
278
|
|
|
277
279
|
# Do the actual clustering
|
|
278
280
|
db['dist'] = 1 - db['similarity']
|
|
279
281
|
linkage_db = db.pivot(index="genome1", columns="genome2", values="dist")
|
|
280
282
|
Cdb, linkage = drep.d_cluster.cluster_utils.cluster_hierarchical(linkage_db, linkage_method= P_Lmethod, \
|
|
281
|
-
linkage_cutoff= P_Lcutoff)
|
|
283
|
+
linkage_cutoff= P_Lcutoff, low_ram=low_ram)
|
|
282
284
|
Cdb = Cdb.rename(columns={'cluster':'primary_cluster'})
|
|
283
285
|
Cdb['primary_cluster'] = Cdb['primary_cluster'].astype(int)
|
|
284
286
|
|
|
@@ -290,6 +292,7 @@ def cluster_mash_database(db, **kwargs):
|
|
|
290
292
|
return Cdb, cluster_ret
|
|
291
293
|
|
|
292
294
|
def secondary_clustering(Bdb, Cdb, algorithm, data_folder, **kwargs):
|
|
295
|
+
|
|
293
296
|
if kwargs.get('greedy_secondary_clustering', False) != True:
|
|
294
297
|
Ndb = pd.DataFrame()
|
|
295
298
|
for bdb, name in iteratre_clusters(Bdb, Cdb, id='primary_cluster'):
|
|
@@ -368,6 +371,12 @@ def compare_genomes(bdb, algorithm, data_folder, **kwargs):
|
|
|
368
371
|
df = drep.d_cluster.external.run_pairwise_fastANI(genome_list, working_data_folder, **kwargs)
|
|
369
372
|
return df
|
|
370
373
|
|
|
374
|
+
elif algorithm == 'skani':
|
|
375
|
+
genome_list = bdb['location'].tolist()
|
|
376
|
+
working_data_folder = os.path.join(data_folder, 'skani_files/')
|
|
377
|
+
df = drep.d_cluster.external.run_pairwise_skani(genome_list, working_data_folder, **kwargs)
|
|
378
|
+
return df
|
|
379
|
+
|
|
371
380
|
elif algorithm == 'gANI':
|
|
372
381
|
# Figure out prodigal folder
|
|
373
382
|
wd = kwargs.get('wd', False)
|
|
@@ -115,6 +115,88 @@ def run_pairwise_fastANI(genome_list, outdir, **kwargs):
|
|
|
115
115
|
logging.error("CRITICAL ERROR WITH SECONDARY CLUSTERING CODE {0}; SKIPPING".format(code))
|
|
116
116
|
return pd.DataFrame()
|
|
117
117
|
|
|
118
|
+
def run_pairwise_skani(genome_list, outdir, **kwargs):
|
|
119
|
+
code = drep.d_cluster.utils._randomString(stringLength=10)
|
|
120
|
+
extra_cmd = kwargs.get('skani_extra', "")
|
|
121
|
+
|
|
122
|
+
# Make folders
|
|
123
|
+
if not os.path.exists(outdir):
|
|
124
|
+
os.makedirs(outdir)
|
|
125
|
+
tmp_dir = os.path.join(outdir, 'tmp/')
|
|
126
|
+
if not os.path.exists(tmp_dir):
|
|
127
|
+
os.makedirs(tmp_dir)
|
|
128
|
+
|
|
129
|
+
# Make genome list
|
|
130
|
+
glist = os.path.join(tmp_dir, 'genomeList')
|
|
131
|
+
glist = _make_glist(genome_list, glist)
|
|
132
|
+
|
|
133
|
+
# Gen command
|
|
134
|
+
exe_loc = drep.get_exe('skani')
|
|
135
|
+
out_base = os.path.join(outdir, 'skani_out_{0}'.format(code))
|
|
136
|
+
#cmd = [exe_loc, '--ql', glist, '--rl', glist, '-o', out_base, '--matrix', '-t', str(p), "--minFraction", str(0)]
|
|
137
|
+
cmd = [exe_loc, "triangle", "-t", "1", '-o', out_base, '--full-matrix', '-l', glist, '--detailed', '-s', "1", '--min-af', "0"]
|
|
138
|
+
if extra_cmd != "":
|
|
139
|
+
cmd += extra_cmd.split(' ')
|
|
140
|
+
|
|
141
|
+
logging.debug(' '.join(cmd) + ' ' + code)
|
|
142
|
+
|
|
143
|
+
# Run command
|
|
144
|
+
if ('wd' in kwargs) and (kwargs.get('debug', False)):
|
|
145
|
+
logdir = kwargs.get('wd').get_dir('cmd_logs')
|
|
146
|
+
else:
|
|
147
|
+
logdir = False
|
|
148
|
+
drep.thread_cmds([cmd], shell=False, logdir=logdir, t=1)
|
|
149
|
+
|
|
150
|
+
# Load results
|
|
151
|
+
fdb = load_skani(out_base)
|
|
152
|
+
|
|
153
|
+
return fdb
|
|
154
|
+
|
|
155
|
+
def load_triangle_matrix(file_path):
|
|
156
|
+
with open(file_path, 'r') as f:
|
|
157
|
+
lines = f.readlines()
|
|
158
|
+
|
|
159
|
+
# Get the number of genomes
|
|
160
|
+
num_genomes = int(lines[0].strip())
|
|
161
|
+
|
|
162
|
+
# Initialize lists to store data
|
|
163
|
+
reference = []
|
|
164
|
+
query = []
|
|
165
|
+
ani = []
|
|
166
|
+
|
|
167
|
+
# Parse the matrix
|
|
168
|
+
for i in range(1, num_genomes + 1):
|
|
169
|
+
row = lines[i].strip().split('\t')
|
|
170
|
+
ref_genome = row[0]
|
|
171
|
+
for j in range(1, i + 1):
|
|
172
|
+
query_genome = lines[j].strip().split('\t')[0]
|
|
173
|
+
ani_value = float(row[j])
|
|
174
|
+
reference.append(ref_genome)
|
|
175
|
+
query.append(query_genome)
|
|
176
|
+
ani.append(ani_value)
|
|
177
|
+
|
|
178
|
+
# Create a DataFrame
|
|
179
|
+
df = pd.DataFrame({'reference': reference, 'querry': query, 'ani': ani})
|
|
180
|
+
return df
|
|
181
|
+
|
|
182
|
+
def load_matrix_to_dataframe(file_path):
|
|
183
|
+
with open(file_path, 'r') as file:
|
|
184
|
+
lines = file.readlines()
|
|
185
|
+
|
|
186
|
+
num_genomes = int(lines[0].strip())
|
|
187
|
+
genomes = [line.split('\t')[0] for line in lines[1:num_genomes + 1]]
|
|
188
|
+
|
|
189
|
+
data = []
|
|
190
|
+
for i in range(num_genomes):
|
|
191
|
+
for j in range(num_genomes):
|
|
192
|
+
genome1 = genomes[i]
|
|
193
|
+
genome2 = genomes[j]
|
|
194
|
+
ani = float(lines[i + 1].split('\t')[j + 1])
|
|
195
|
+
data.append([genome1, genome2, ani])
|
|
196
|
+
|
|
197
|
+
df = pd.DataFrame(data, columns=['reference', 'querry', 'ani'])
|
|
198
|
+
return df
|
|
199
|
+
|
|
118
200
|
def fastani_one_vs_many(one, many, genome_rep_file, outdir, **kwargs):
|
|
119
201
|
p = kwargs.get('processors', 6)
|
|
120
202
|
code = drep.d_cluster.utils._randomString(stringLength=10)
|
|
@@ -147,6 +229,28 @@ def load_fastani(file):
|
|
|
147
229
|
|
|
148
230
|
return fdb
|
|
149
231
|
|
|
232
|
+
def load_skani(file):
|
|
233
|
+
# Load the ani triangle
|
|
234
|
+
adb = load_triangle_matrix(file)
|
|
235
|
+
adb['ani'] = adb['ani'] / 100
|
|
236
|
+
|
|
237
|
+
# Make symnetrical
|
|
238
|
+
db = adb.rename(columns={'reference':'querry', 'querry':'reference'})
|
|
239
|
+
db = db[db['reference'] != db['querry']]
|
|
240
|
+
adb = pd.concat([adb, db], ignore_index=True).reset_index(drop=True)
|
|
241
|
+
|
|
242
|
+
# Load the af triangle
|
|
243
|
+
tdb = load_matrix_to_dataframe(file + '.af').rename(columns={'ani':'alignment_coverage'})
|
|
244
|
+
|
|
245
|
+
# Merge
|
|
246
|
+
assert len(adb) == len(tdb)
|
|
247
|
+
fdb = pd.merge(adb, tdb, how='inner')
|
|
248
|
+
|
|
249
|
+
# parse
|
|
250
|
+
for c in ['reference', 'querry']:
|
|
251
|
+
fdb[c] = [drep.d_cluster.utils._get_genome_name_from_fasta(x) for x in fdb[c]]
|
|
252
|
+
|
|
253
|
+
return fdb
|
|
150
254
|
|
|
151
255
|
def _fix_fastani(odb):
|
|
152
256
|
# Add back missing genomes
|
|
@@ -103,6 +103,8 @@ def estimate_time(comps, alg):
|
|
|
103
103
|
time = comps * .5
|
|
104
104
|
elif alg == 'fastANI':
|
|
105
105
|
time = comps * 0.00667
|
|
106
|
+
elif alg == 'skani':
|
|
107
|
+
time = comps * 0.00667
|
|
106
108
|
return time
|
|
107
109
|
|
|
108
110
|
|
|
@@ -352,7 +354,7 @@ def gen_goANI_cmd(file, g1, g2, exe):
|
|
|
352
354
|
return []
|
|
353
355
|
|
|
354
356
|
else:
|
|
355
|
-
cmd = [exe,'--om','TABX', g1, g2, file]
|
|
357
|
+
cmd = [exe,'--om','TABX', '--rpq', '1', g1, g2, file]
|
|
356
358
|
return cmd
|
|
357
359
|
|
|
358
360
|
def process_deltafiles(deltafiles, org_lengths, logger=None, **kwargs):
|
|
@@ -11,9 +11,6 @@ import gzip
|
|
|
11
11
|
import pandas as pd
|
|
12
12
|
import os
|
|
13
13
|
import sys
|
|
14
|
-
import shutil
|
|
15
|
-
import multiprocessing
|
|
16
|
-
from Bio import SeqIO
|
|
17
14
|
|
|
18
15
|
import drep
|
|
19
16
|
import drep.WorkDirectory
|
|
@@ -449,32 +446,43 @@ def calc_n50(loc):
|
|
|
449
446
|
Calculate the N50 of a .fasta file
|
|
450
447
|
|
|
451
448
|
Args:
|
|
452
|
-
|
|
449
|
+
loc: location of .fasta file.
|
|
453
450
|
|
|
454
451
|
Returns:
|
|
455
452
|
int: N50 of .fasta file.
|
|
456
453
|
'''
|
|
457
454
|
lengths = []
|
|
455
|
+
is_header = True
|
|
458
456
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
for seq_record in SeqIO.parse(handle, "fasta"):
|
|
463
|
-
lengths.append(len(seq_record))
|
|
457
|
+
if loc.endswith('.gz'):
|
|
458
|
+
open_func = gzip.open
|
|
459
|
+
mode = 'rt'
|
|
464
460
|
else:
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
461
|
+
open_func = open
|
|
462
|
+
mode = 'r'
|
|
463
|
+
|
|
464
|
+
with open_func(loc, mode) as handle:
|
|
465
|
+
seq_length = 0
|
|
466
|
+
for line in handle:
|
|
467
|
+
if line.startswith('>'):
|
|
468
|
+
if not is_header:
|
|
469
|
+
lengths.append(seq_length)
|
|
470
|
+
seq_length = 0
|
|
471
|
+
is_header = True
|
|
472
|
+
else:
|
|
473
|
+
seq_length += len(line.strip())
|
|
474
|
+
is_header = False
|
|
475
|
+
if not is_header:
|
|
476
|
+
lengths.append(seq_length)
|
|
477
|
+
|
|
478
|
+
half = sum(lengths) / 2
|
|
472
479
|
tally = 0
|
|
473
480
|
for l in sorted(lengths, reverse=True):
|
|
474
481
|
tally += l
|
|
475
482
|
if tally > half:
|
|
476
483
|
return l
|
|
477
484
|
|
|
485
|
+
|
|
478
486
|
def run_prodigal(genome_list, out_dir, **kwargs):
|
|
479
487
|
'''
|
|
480
488
|
Run prodigal on a set of genomes, store the output in the out_dir
|
|
@@ -647,23 +655,29 @@ def _iterate_checkm_groups(genome_folder_whole, checkm_outf_whole, checkm_group_
|
|
|
647
655
|
|
|
648
656
|
def calc_fasta_length(fasta_loc):
|
|
649
657
|
'''
|
|
650
|
-
Calculate the length of the .fasta file and
|
|
658
|
+
Calculate the length of the .fasta file and return length
|
|
651
659
|
|
|
652
660
|
Args:
|
|
653
661
|
fasta_loc: location of .fasta file
|
|
654
662
|
|
|
655
663
|
Returns:
|
|
656
|
-
int: total length of all .fasta
|
|
664
|
+
int: total length of all sequences in the .fasta file
|
|
657
665
|
'''
|
|
658
666
|
total = 0
|
|
659
667
|
|
|
660
|
-
if fasta_loc
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
total += len(seq_record)
|
|
668
|
+
if fasta_loc.endswith('.gz'):
|
|
669
|
+
open_func = gzip.open
|
|
670
|
+
mode = 'rt'
|
|
664
671
|
else:
|
|
665
|
-
|
|
666
|
-
|
|
672
|
+
open_func = open
|
|
673
|
+
mode = 'r'
|
|
674
|
+
|
|
675
|
+
with open_func(fasta_loc, mode) as handle:
|
|
676
|
+
for line in handle:
|
|
677
|
+
if line.startswith('>'):
|
|
678
|
+
pass
|
|
679
|
+
else:
|
|
680
|
+
total += len(line.strip())
|
|
667
681
|
|
|
668
682
|
return total
|
|
669
683
|
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: drep
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.1
|
|
4
4
|
Summary: De-replication of microbial genomes assembled from multiple samples
|
|
5
5
|
Home-page: https://github.com/MrOlm/drep
|
|
6
6
|
Author: Matt Olm
|
|
7
7
|
Author-email: mattolm@berkeley.edu
|
|
8
8
|
License: MIT
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: pandas
|
|
11
|
+
Requires-Dist: seaborn
|
|
12
|
+
Requires-Dist: matplotlib
|
|
13
|
+
Requires-Dist: biopython
|
|
14
|
+
Requires-Dist: scikit-learn
|
|
15
|
+
Requires-Dist: tqdm
|
|
16
|
+
Requires-Dist: pytest
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
README.md
|
|
2
|
+
pyproject.toml
|
|
2
3
|
setup.py
|
|
3
4
|
bin/dRep
|
|
4
5
|
drep/VERSION
|
|
@@ -28,4 +29,5 @@ drep/d_cluster/greedy_clustering.py
|
|
|
28
29
|
drep/d_cluster/parsers.py
|
|
29
30
|
drep/d_cluster/utils.py
|
|
30
31
|
helper_scripts/ScaffoldLevel_dRep.py
|
|
31
|
-
helper_scripts/parse_stb.py
|
|
32
|
+
helper_scripts/parse_stb.py
|
|
33
|
+
tests/test_suite.py
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
import os
|
|
11
|
-
import sys
|
|
12
11
|
import gzip
|
|
13
12
|
import glob
|
|
14
13
|
import textwrap
|
|
@@ -18,15 +17,13 @@ import argparse
|
|
|
18
17
|
import pandas as pd
|
|
19
18
|
|
|
20
19
|
from shutil import copyfile
|
|
21
|
-
import subprocess
|
|
22
20
|
from subprocess import call
|
|
23
21
|
from collections import defaultdict
|
|
24
22
|
|
|
25
23
|
from tqdm import tqdm
|
|
26
24
|
|
|
27
|
-
from Bio import SeqIO
|
|
28
|
-
|
|
29
25
|
import drep
|
|
26
|
+
import drep.d_filter
|
|
30
27
|
|
|
31
28
|
def version():
|
|
32
29
|
versionFile = open(os.path.join(drep.__path__[0], 'VERSION'))
|
|
@@ -128,8 +125,8 @@ class ANImCommand(abstractCommand):
|
|
|
128
125
|
|
|
129
126
|
if method == 'simple':
|
|
130
127
|
# Get the organism lengths
|
|
131
|
-
qlen =
|
|
132
|
-
rlen =
|
|
128
|
+
qlen = drep.d_filter.calc_fasta_length(self.config['querry'])
|
|
129
|
+
rlen = drep.d_filter.calc_fasta_length(self.config['reference'])
|
|
133
130
|
|
|
134
131
|
# Parse the reults
|
|
135
132
|
delta = get_delta_loc(self.config['prefix'])
|
|
@@ -156,7 +153,6 @@ class ANImCommand(abstractCommand):
|
|
|
156
153
|
|
|
157
154
|
def __str__(self):
|
|
158
155
|
''' Show the command parameters '''
|
|
159
|
-
return pprint.pformat(self.config)
|
|
160
156
|
|
|
161
157
|
def gen_mummer_cmd(**kwargs):
|
|
162
158
|
'''
|
|
@@ -660,16 +656,27 @@ def load_scaffold2length(fasta):
|
|
|
660
656
|
Return a database of scaffold to length
|
|
661
657
|
'''
|
|
662
658
|
table = defaultdict(list)
|
|
659
|
+
is_header = True
|
|
663
660
|
|
|
664
|
-
if fasta
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
table['scaffold'].append(seq_record.id)
|
|
668
|
-
table['length'].append(len(seq_record))
|
|
661
|
+
if fasta.endswith('.gz'):
|
|
662
|
+
open_func = gzip.open
|
|
663
|
+
mode = 'rt'
|
|
669
664
|
else:
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
665
|
+
open_func = open
|
|
666
|
+
mode = 'r'
|
|
667
|
+
|
|
668
|
+
with open_func(fasta, mode) as handle:
|
|
669
|
+
for line in handle:
|
|
670
|
+
if line.startswith('>'):
|
|
671
|
+
is_header = True
|
|
672
|
+
scaffold_id = line[1:].strip().split(' ')[0]
|
|
673
|
+
elif is_header:
|
|
674
|
+
table['scaffold'].append(scaffold_id)
|
|
675
|
+
table['length'].append(0)
|
|
676
|
+
is_header = False
|
|
677
|
+
else:
|
|
678
|
+
table['length'][-1] += len(line.strip())
|
|
679
|
+
|
|
673
680
|
return pd.DataFrame(table)
|
|
674
681
|
|
|
675
682
|
def add_cov_ani(Ddb, s2l):
|
|
@@ -712,28 +719,46 @@ def split_into_chunks(file, max_len, temp_folder):
|
|
|
712
719
|
chunks = []
|
|
713
720
|
|
|
714
721
|
chunk_number = 0
|
|
715
|
-
records = []
|
|
716
722
|
chunk_len = 0
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
723
|
+
chunk_records = []
|
|
724
|
+
record_id = ''
|
|
725
|
+
record_seq = ''
|
|
726
|
+
|
|
727
|
+
with open(file, 'r') as handle:
|
|
728
|
+
for line in handle:
|
|
729
|
+
if line.startswith('>'):
|
|
730
|
+
if chunk_len + len(record_seq) > max_len and len(chunk_records) > 0:
|
|
731
|
+
# Save this chunk
|
|
732
|
+
new_loc = newfile_base + '_CHUNK_{0}.fasta'.format(chunk_number)
|
|
733
|
+
with open(new_loc, 'w') as chunk_file:
|
|
734
|
+
chunk_file.write(''.join(chunk_records))
|
|
735
|
+
chunks.append(new_loc)
|
|
736
|
+
|
|
737
|
+
chunk_len = 0
|
|
738
|
+
chunk_number += 1
|
|
739
|
+
chunk_records = []
|
|
740
|
+
|
|
741
|
+
if record_id:
|
|
742
|
+
chunk_records.append('>' + record_id + '\n' + record_seq + '\n')
|
|
743
|
+
chunk_len += len(record_seq)
|
|
744
|
+
|
|
745
|
+
record_id = line[1:].strip().split(' ')[0]
|
|
746
|
+
record_seq = ''
|
|
747
|
+
else:
|
|
748
|
+
record_seq += line.strip()
|
|
749
|
+
|
|
750
|
+
# Add the last record
|
|
751
|
+
if record_id:
|
|
752
|
+
chunk_records.append('>' + record_id + '\n' + record_seq + '\n')
|
|
753
|
+
chunk_len += len(record_seq)
|
|
720
754
|
|
|
721
|
-
|
|
722
|
-
|
|
755
|
+
# Save the final chunk
|
|
756
|
+
if len(chunk_records) > 0:
|
|
723
757
|
new_loc = newfile_base + '_CHUNK_{0}.fasta'.format(chunk_number)
|
|
724
|
-
|
|
758
|
+
with open(new_loc, 'w') as chunk_file:
|
|
759
|
+
chunk_file.write(''.join(chunk_records))
|
|
725
760
|
chunks.append(new_loc)
|
|
726
761
|
|
|
727
|
-
chunk_len = 0
|
|
728
|
-
chunk_number += 1
|
|
729
|
-
records = []
|
|
730
|
-
|
|
731
|
-
# Save the final chunk
|
|
732
|
-
if len(records) > 0:
|
|
733
|
-
new_loc = newfile_base + '_CHUNK_{0}.fasta'.format(chunk_number)
|
|
734
|
-
SeqIO.write(records, new_loc, "fasta")
|
|
735
|
-
chunks.append(new_loc)
|
|
736
|
-
|
|
737
762
|
return chunks
|
|
738
763
|
|
|
739
764
|
def compare_wrapper(current, new, scaffDb, temp_folder, **kwargs):
|
|
@@ -875,23 +900,38 @@ def reconsile(Sdb, current, new, newFile, temp_folder, **kwargs):
|
|
|
875
900
|
|
|
876
901
|
return Rdb
|
|
877
902
|
|
|
878
|
-
|
|
879
903
|
def write_new(ori_loc, new_loc, to_rm, verbose=False):
|
|
880
904
|
'''
|
|
881
905
|
Write a new .fasta file removing certain scaffolds
|
|
882
906
|
'''
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
for r in SeqIO.parse(handle, "fasta"):
|
|
887
|
-
records.append(r)
|
|
907
|
+
if ori_loc.endswith('.gz'):
|
|
908
|
+
open_func = gzip.open
|
|
909
|
+
mode = 'rt'
|
|
888
910
|
else:
|
|
889
|
-
|
|
890
|
-
|
|
911
|
+
open_func = open
|
|
912
|
+
mode = 'r'
|
|
913
|
+
|
|
914
|
+
ori_len = 0
|
|
915
|
+
count = 0
|
|
916
|
+
with open_func(ori_loc, mode) as handle, open(new_loc, 'w') as out_handle:
|
|
917
|
+
record_id = ''
|
|
918
|
+
record_seq = ''
|
|
919
|
+
for line in handle:
|
|
920
|
+
if line.startswith('>'):
|
|
921
|
+
ori_len += 1
|
|
922
|
+
if record_id and record_id not in to_rm:
|
|
923
|
+
out_handle.write('>' + record_id + '\n' + record_seq + '\n')
|
|
924
|
+
count += 1
|
|
925
|
+
record_id = line[1:].strip().split(' ')[0]
|
|
926
|
+
record_seq = ''
|
|
927
|
+
else:
|
|
928
|
+
record_seq += line.strip()
|
|
929
|
+
|
|
930
|
+
# Write the last record
|
|
931
|
+
if record_id and record_id not in to_rm:
|
|
932
|
+
out_handle.write('>' + record_id + '\n' + record_seq + '\n')
|
|
933
|
+
count += 1
|
|
891
934
|
|
|
892
|
-
ori_len = len(records)
|
|
893
|
-
records = (r for r in records if r.id not in to_rm)
|
|
894
|
-
count = SeqIO.write(records, new_loc, "fasta")
|
|
895
935
|
if verbose:
|
|
896
936
|
print("Removed {0} scaffolds from {1}".format(ori_len - count, ori_loc))
|
|
897
937
|
|
|
@@ -957,9 +997,30 @@ class test_dRepScaffolds():
|
|
|
957
997
|
to_rm = ['N5_271_010G1_scaffold_119']
|
|
958
998
|
new_loc = self.test_dir + 'new_file.fasta'
|
|
959
999
|
|
|
960
|
-
|
|
1000
|
+
def count_fasta_records(fasta_loc):
|
|
1001
|
+
count = 0
|
|
1002
|
+
record_flag = False
|
|
1003
|
+
if fasta_loc.endswith('.gz'):
|
|
1004
|
+
open_func = gzip.open
|
|
1005
|
+
mode = 'rt'
|
|
1006
|
+
else:
|
|
1007
|
+
open_func = open
|
|
1008
|
+
mode = 'r'
|
|
1009
|
+
|
|
1010
|
+
with open_func(fasta_loc, mode) as handle:
|
|
1011
|
+
for line in handle:
|
|
1012
|
+
if line.startswith('>'):
|
|
1013
|
+
count += 1
|
|
1014
|
+
record_flag = True
|
|
1015
|
+
elif not record_flag:
|
|
1016
|
+
# In case the file starts with sequences without headers
|
|
1017
|
+
count += 1
|
|
1018
|
+
record_flag = True
|
|
1019
|
+
return count
|
|
1020
|
+
|
|
1021
|
+
ori_len = count_fasta_records(self.fastas[0])
|
|
961
1022
|
write_new(self.fastas[0], new_loc, to_rm, verbose=False)
|
|
962
|
-
new_len =
|
|
1023
|
+
new_len = count_fasta_records(new_loc)
|
|
963
1024
|
|
|
964
1025
|
assert new_len + 1 == ori_len
|
|
965
1026
|
|
|
@@ -3,50 +3,55 @@
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
5
|
import gzip
|
|
6
|
-
import logging
|
|
7
6
|
import textwrap
|
|
8
7
|
import argparse
|
|
9
8
|
|
|
10
|
-
from Bio import SeqIO
|
|
11
|
-
|
|
12
9
|
def extract_bins(fasta, stb_file, out_base):
|
|
13
10
|
if (out_base != '') & (out_base[-1] != '/'):
|
|
14
11
|
out_base += '_'
|
|
15
12
|
|
|
16
13
|
# Make scaffold to bin dictionary
|
|
17
14
|
stb = {}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if line.startswith('#') or line.startswith('scaffold_name'):
|
|
23
|
-
continue
|
|
15
|
+
with open(stb_file) as stb_reader:
|
|
16
|
+
for line in stb_reader:
|
|
17
|
+
line = line.strip()
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
stb[scaffold] = bin
|
|
19
|
+
if line.startswith('#') or line.startswith('scaffold_name'):
|
|
20
|
+
continue
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
handle = gzip.open(fasta, "rt")
|
|
32
|
-
seqs = SeqIO.parse(handle, "fasta")
|
|
22
|
+
scaffold, bin = line.split('\t')[:2]
|
|
23
|
+
stb[scaffold.strip()] = bin.strip()
|
|
33
24
|
|
|
25
|
+
# Parse the FASTA file and write to bins
|
|
26
|
+
if fasta.endswith('.gz'):
|
|
27
|
+
open_func = gzip.open
|
|
28
|
+
mode = 'rt'
|
|
34
29
|
else:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
open_func = open
|
|
31
|
+
mode = 'r'
|
|
32
|
+
|
|
33
|
+
with open_func(fasta, mode) as handle:
|
|
34
|
+
record_id = ''
|
|
35
|
+
record_seq = ''
|
|
36
|
+
for line in handle:
|
|
37
|
+
if line.startswith('>'):
|
|
38
|
+
if record_id and record_id in stb:
|
|
39
|
+
bin = stb[record_id]
|
|
40
|
+
with open(f"{out_base}{bin}.fa", 'a') as nw:
|
|
41
|
+
nw.write(f">{record_id}\n{record_seq}\n")
|
|
42
|
+
record_id = line[1:].strip().split(' ')[0]
|
|
43
|
+
record_seq = ''
|
|
44
|
+
else:
|
|
45
|
+
record_seq += line.strip()
|
|
46
|
+
|
|
47
|
+
# Write the last record
|
|
48
|
+
if record_id and record_id in stb:
|
|
49
|
+
bin = stb[record_id]
|
|
50
|
+
with open(f"{out_base}{bin}.fa", 'a') as nw:
|
|
51
|
+
nw.write(f">{record_id}\n{record_seq}\n")
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
nw.close()
|
|
47
|
-
|
|
48
|
-
if fasta[-3:] == '.gz':
|
|
49
|
-
handle.close()
|
|
53
|
+
import os
|
|
54
|
+
import gzip
|
|
50
55
|
|
|
51
56
|
def gen_stb(fastas):
|
|
52
57
|
if ((len(fastas) == 1) & (not fastas[0].endswith('.gz'))):
|
|
@@ -67,18 +72,22 @@ def gen_stb(fastas):
|
|
|
67
72
|
stb = {}
|
|
68
73
|
for fasta in fastas:
|
|
69
74
|
bin = os.path.basename(fasta)
|
|
70
|
-
if
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
id = str(seq_record.id).strip()
|
|
74
|
-
stb[id] = bin
|
|
75
|
+
if fasta.endswith('.gz'):
|
|
76
|
+
open_func = gzip.open
|
|
77
|
+
mode = 'rt'
|
|
75
78
|
else:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
open_func = open
|
|
80
|
+
mode = 'r'
|
|
81
|
+
|
|
82
|
+
with open_func(fasta, mode) as handle:
|
|
83
|
+
for line in handle:
|
|
84
|
+
if line.startswith('>'):
|
|
85
|
+
id = line[1:].strip().split(' ')[0]
|
|
86
|
+
stb[id] = bin
|
|
87
|
+
|
|
80
88
|
return stb
|
|
81
89
|
|
|
90
|
+
|
|
82
91
|
def print_stb(stb, output):
|
|
83
92
|
file = open(output,'w')
|
|
84
93
|
for key in sorted(stb, key=stb.get):
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
###############################################################################
|
|
4
|
+
#
|
|
5
|
+
# test_suite.py - process several E. coli genomes to verify operation of dRep
|
|
6
|
+
#
|
|
7
|
+
###############################################################################
|
|
8
|
+
|
|
9
|
+
import tests.test_rerun
|
|
10
|
+
import tests.test_unit
|
|
11
|
+
import tests.test_dereplicate
|
|
12
|
+
import tests.test_filter
|
|
13
|
+
import tests.test_cluster
|
|
14
|
+
import tests.test_choose
|
|
15
|
+
import tests.test_analyze
|
|
16
|
+
import tests.test_bonus
|
|
17
|
+
import tests.test_taxonomy
|
|
18
|
+
|
|
19
|
+
if __name__ == '__main__':
|
|
20
|
+
# tests.test_rerun.test_rerun().run()
|
|
21
|
+
# tests.test_unit.test_unit().run()
|
|
22
|
+
tests.test_dereplicate.test_dereplicate().run()
|
|
23
|
+
# tests.test_filter.test_filter().run()
|
|
24
|
+
# tests.test_cluster.test_cluster().run()
|
|
25
|
+
# tests.test_choose.test_choose().run()
|
|
26
|
+
# tests.test_analyze.test_analyze().run()
|
|
27
|
+
# tests.test_bonus.test_bonus().run()
|
|
28
|
+
# tests.test_taxonomy.test_taxonomy().run()
|
|
29
|
+
|
|
30
|
+
print("Everything seems to be working swimmingly!")
|
drep-3.4.5/drep/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3.4.5
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|