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
drep/d_bonus.py
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import sys
|
|
7
|
+
import shutil
|
|
8
|
+
import subprocess
|
|
9
|
+
import time
|
|
10
|
+
|
|
11
|
+
import drep
|
|
12
|
+
import drep.WorkDirectory
|
|
13
|
+
import drep.d_filter
|
|
14
|
+
|
|
15
|
+
def d_bonus_wrapper(wd,**kwargs):
|
|
16
|
+
logging.info("Loading work directory")
|
|
17
|
+
wd = drep.WorkDirectory.WorkDirectory(wd)
|
|
18
|
+
logging.debug(str(wd))
|
|
19
|
+
|
|
20
|
+
if kwargs.get('check_dependencies'):
|
|
21
|
+
logging.info('Checking dependencies')
|
|
22
|
+
check_dependencies()
|
|
23
|
+
|
|
24
|
+
if kwargs.get('run_tax'):
|
|
25
|
+
logging.info('Running tax')
|
|
26
|
+
run_taxonomy(wd,**kwargs)
|
|
27
|
+
|
|
28
|
+
def run_taxonomy(wd, **kwargs):
|
|
29
|
+
# Validate arguments- make sure you have everything you need
|
|
30
|
+
Bdb, prod_dir, cent_dir = validate_arguments(wd, **kwargs)
|
|
31
|
+
|
|
32
|
+
# Run prodigal
|
|
33
|
+
drep.d_filter.run_prodigal(Bdb['location'].tolist(), prod_dir, **kwargs)
|
|
34
|
+
|
|
35
|
+
# Run centrifuge
|
|
36
|
+
run_centrifuge(Bdb, prod_dir, cent_dir, wd=wd, **kwargs)
|
|
37
|
+
|
|
38
|
+
# # Call a centrifuge parser that returns Tdb
|
|
39
|
+
# Tdb = parse_centrifuge(Bdb, cent_dir, **kwargs)
|
|
40
|
+
#
|
|
41
|
+
# # Add taxonomic info to Bdb
|
|
42
|
+
# Bdb = add_taxonomy(Bdb,Tdb)
|
|
43
|
+
|
|
44
|
+
# Parse taxonomy
|
|
45
|
+
Tdb, Bdb = parse_taxonomy(Bdb, cent_dir, **kwargs)
|
|
46
|
+
|
|
47
|
+
# Save Tdb and Bdb
|
|
48
|
+
wd.store_db(Tdb,'Tdb',overwrite=True)
|
|
49
|
+
wd.store_db(Bdb,'Bdb',overwrite=True)
|
|
50
|
+
|
|
51
|
+
def parse_taxonomy(Bdb, cent_dir, **kwargs):
|
|
52
|
+
'''
|
|
53
|
+
take the centrifuge directory and Bdb, return Tdb and Bdb with an added 'taxonomy' column
|
|
54
|
+
'''
|
|
55
|
+
|
|
56
|
+
method = kwargs.get('tax_method')
|
|
57
|
+
|
|
58
|
+
if method == 'max':
|
|
59
|
+
Tdb = parse_centrifuge(Bdb, cent_dir, **kwargs)
|
|
60
|
+
|
|
61
|
+
elif method == 'percent':
|
|
62
|
+
Tdb = parse_centrifuge_percent(Bdb, cent_dir, **kwargs)
|
|
63
|
+
|
|
64
|
+
else:
|
|
65
|
+
logging.error("dont recognize method {0}, quitting".format(method))
|
|
66
|
+
sys.exit()
|
|
67
|
+
|
|
68
|
+
Bdb = add_taxonomy(Bdb,Tdb)
|
|
69
|
+
return Tdb, Bdb
|
|
70
|
+
|
|
71
|
+
def validate_arguments(wd, **kwargs):
|
|
72
|
+
'''
|
|
73
|
+
make sure you have everything you need
|
|
74
|
+
'''
|
|
75
|
+
if wd.hasDb('Bdb'):
|
|
76
|
+
if kwargs.get('genomes',None) != None:
|
|
77
|
+
logging.error("Both Bdb and a genome list are found- either don't include "\
|
|
78
|
+
+ "a genome list or start a new work directory!")
|
|
79
|
+
sys.exit()
|
|
80
|
+
Bdb = wd.get_db('Bdb')
|
|
81
|
+
|
|
82
|
+
else:
|
|
83
|
+
if kwargs.get('genomes',None) == None:
|
|
84
|
+
logging.error("I don't have anything to determine the taxonomy of! Give me a genome list")
|
|
85
|
+
sys.exit()
|
|
86
|
+
Bdb = drep.d_cluster.utils.load_genomes(kwargs['genomes'])
|
|
87
|
+
|
|
88
|
+
prod_dir = wd.get_dir('prodigal')
|
|
89
|
+
cent_dir = wd.get_dir('centrifuge')
|
|
90
|
+
# if wd.hasDb('Tdb') and (kwargs.get('overwrite',False) == False):
|
|
91
|
+
# logging.error('Tdb already exists- run with overwrite to overwrite')
|
|
92
|
+
# sys.exit()
|
|
93
|
+
|
|
94
|
+
return Bdb, prod_dir, cent_dir
|
|
95
|
+
|
|
96
|
+
def check_dependencies(print_out=False):
|
|
97
|
+
'''
|
|
98
|
+
For all possible dependencies, see if you can find them
|
|
99
|
+
'''
|
|
100
|
+
for dep in ['mash', 'nucmer', 'checkm', 'ANIcalculator', 'prodigal', 'centrifuge',
|
|
101
|
+
'nsimscan', 'fastANI', 'skani']:
|
|
102
|
+
loc, works = find_program(dep)
|
|
103
|
+
works_message = {True:'all good', False:'!!! ERROR !!!'}[works]
|
|
104
|
+
message = '{0:.<40} {1:15} (location = {2})'.format(dep, works_message, loc)
|
|
105
|
+
if print_out:
|
|
106
|
+
print(message)
|
|
107
|
+
else:
|
|
108
|
+
logging.info(message)
|
|
109
|
+
|
|
110
|
+
def find_program(dep):
|
|
111
|
+
'''
|
|
112
|
+
return location of progrgam, works = True/False (based on calling the help)
|
|
113
|
+
'''
|
|
114
|
+
# find the location of the program
|
|
115
|
+
loc = shutil.which(dep)
|
|
116
|
+
|
|
117
|
+
# make sure the help on the program works
|
|
118
|
+
works = False
|
|
119
|
+
if loc != None:
|
|
120
|
+
try:
|
|
121
|
+
result = subprocess.run([loc, '-h'], capture_output=True)
|
|
122
|
+
# Some tools (e.g. older fastANI) exit with code 1 on -h even when working
|
|
123
|
+
if len(result.stdout) > 0 or len(result.stderr) > 0:
|
|
124
|
+
works = True
|
|
125
|
+
except Exception:
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
return loc, works
|
|
129
|
+
|
|
130
|
+
def run_centrifuge(Bdb, prod_dir, cent_dir, **kwargs):
|
|
131
|
+
t = kwargs.get('processors','6')
|
|
132
|
+
|
|
133
|
+
cmds = []
|
|
134
|
+
files = []
|
|
135
|
+
for genome in Bdb['genome'].unique():
|
|
136
|
+
genes = "{0}{1}.fna".format(prod_dir, genome)
|
|
137
|
+
cent = "{0}{1}".format(cent_dir, genome)
|
|
138
|
+
if not (os.path.exists("{0}_hits.tsv".format(cent)) and \
|
|
139
|
+
os.path.exists("{0}_report.tsv".format(cent))):
|
|
140
|
+
cmds.append(gen_centrifuge_cmd(genes,cent,**kwargs))
|
|
141
|
+
|
|
142
|
+
if len(cmds) >= 1:
|
|
143
|
+
logging.info('Running Centrifuge')
|
|
144
|
+
for cmd in cmds:
|
|
145
|
+
logging.debug(' '.join(cmd))
|
|
146
|
+
|
|
147
|
+
if 'wd' in kwargs:
|
|
148
|
+
logdir = kwargs.get('wd').get_dir('cmd_logs')
|
|
149
|
+
else:
|
|
150
|
+
logdir = False
|
|
151
|
+
drep.thread_cmds(cmds, shell=False, logdir=logdir, t=int(t))
|
|
152
|
+
#drep.d_cluster.thread_mash_cmds_status(cmds,t=int(t))
|
|
153
|
+
|
|
154
|
+
else:
|
|
155
|
+
logging.info('Past centrifuge runs found- will not re-run')
|
|
156
|
+
|
|
157
|
+
def gen_read2bin(gene_files):
|
|
158
|
+
r2b = {}
|
|
159
|
+
for f in gene_files:
|
|
160
|
+
genome = os.path.basename(f)[:-4]
|
|
161
|
+
with open(f) as handle:
|
|
162
|
+
for line in handle:
|
|
163
|
+
if line.startswith('>'):
|
|
164
|
+
r2b.setdefault(genome,[]).append(line.strip()[1:].split(' ')[0])
|
|
165
|
+
return r2b
|
|
166
|
+
|
|
167
|
+
def parse_centrifuge(Bdb, cent_dir, **kwargs):
|
|
168
|
+
|
|
169
|
+
Tdb = pd.DataFrame()
|
|
170
|
+
for genome in Bdb['genome'].unique():
|
|
171
|
+
|
|
172
|
+
hits = parse_raw_centrifuge("{0}{1}_hits.tsv".format(cent_dir,genome), \
|
|
173
|
+
"{0}{1}_report.tsv".format(cent_dir,genome))
|
|
174
|
+
|
|
175
|
+
if hits.empty:
|
|
176
|
+
logging.debug("No centrifuge hits found for {0}- skipping".format(genome))
|
|
177
|
+
continue
|
|
178
|
+
|
|
179
|
+
x = gen_phylo_db(hits)
|
|
180
|
+
x['genome'] = genome
|
|
181
|
+
Tdb = pd.concat([x,Tdb], ignore_index=True)
|
|
182
|
+
|
|
183
|
+
# Find the best hits
|
|
184
|
+
g2t = {}
|
|
185
|
+
for genome in Tdb['genome'].unique():
|
|
186
|
+
d = Tdb[Tdb['genome'] == genome]
|
|
187
|
+
taxID = d['tax_ID'][d['tax_confidence'] == d['tax_confidence'].max()].tolist()[0]
|
|
188
|
+
g2t[genome] = taxID
|
|
189
|
+
Tdb['best_hit'] = [True if g2t[g] == t else False for g,t in zip(Tdb['genome'], Tdb['tax_ID'])]
|
|
190
|
+
|
|
191
|
+
# Try and add full taxonomy string
|
|
192
|
+
try:
|
|
193
|
+
Tdb['full_tax'] = [lineage_from_taxId(t) if b else False for t, b in zip(\
|
|
194
|
+
Tdb['tax_ID'], Tdb['best_hit'])]
|
|
195
|
+
except:
|
|
196
|
+
logging.info("problem determing full tax string with ete3 - skipping")
|
|
197
|
+
|
|
198
|
+
return Tdb
|
|
199
|
+
|
|
200
|
+
def parse_centrifuge_percent(Bdb, cent_dir, **kwargs):
|
|
201
|
+
min_perc = int(kwargs.get('percent'))
|
|
202
|
+
min_score = kwargs.get('min_score', 250)
|
|
203
|
+
|
|
204
|
+
Tdb = pd.DataFrame()
|
|
205
|
+
for genome in Bdb['genome'].unique():
|
|
206
|
+
hits = parse_raw_centrifuge("{0}{1}_hits.tsv".format(cent_dir,genome), \
|
|
207
|
+
"{0}{1}_report.tsv".format(cent_dir,genome))
|
|
208
|
+
tdb = tdb_from_hits(hits[hits['score'] > min_score], minPerc= int(min_perc))
|
|
209
|
+
tdb['genome'] = genome
|
|
210
|
+
|
|
211
|
+
Tdb = pd.concat([Tdb, tdb])
|
|
212
|
+
# Find the best hit
|
|
213
|
+
|
|
214
|
+
# THIS IS HARDER BECAUSE YOU HAVE TO PICK THE LOWEST LEVEL OVER the percent
|
|
215
|
+
# # Find the best hits
|
|
216
|
+
# g2t = {}
|
|
217
|
+
# for genome in Tdb['genome'].unique():
|
|
218
|
+
# d = Tdb[Tdb['genome'] == genome]
|
|
219
|
+
# taxID = d['tax_ID'][d['tax_confidence'] == d['tax_confidence'].max()].tolist()[0]
|
|
220
|
+
# g2t[genome] = taxID
|
|
221
|
+
# Tdb['best_hit'] = [True if g2t[g] == t else False for g,t in zip(Tdb['genome'], Tdb['tax_ID'])]
|
|
222
|
+
#
|
|
223
|
+
# # Try and add full taxonomy string
|
|
224
|
+
# try:
|
|
225
|
+
# Tdb['full_tax'] = [lineage_from_taxId(t) if b else False for t, b in zip(\
|
|
226
|
+
# Tdb['tax_ID'], Tdb['best_hit'])]
|
|
227
|
+
# except:
|
|
228
|
+
# logging.info("problem determing full tax string with ete3 - skipping")
|
|
229
|
+
|
|
230
|
+
return Tdb
|
|
231
|
+
|
|
232
|
+
def tdb_from_hits(hits, minPerc= 50, testing=False):
|
|
233
|
+
'''
|
|
234
|
+
Determines the lowest taxonomic level with at least minPerc certainty
|
|
235
|
+
|
|
236
|
+
For every hit:
|
|
237
|
+
reconstruct the lineage (kingdom, phylum, class, ect.)
|
|
238
|
+
add a count to every rank in the lineage
|
|
239
|
+
|
|
240
|
+
For every rank:
|
|
241
|
+
see if the number of hits matching one taxa at that rank is above the minPerc
|
|
242
|
+
the denominator for this equation is the number of hits that have a phyla rank
|
|
243
|
+
|
|
244
|
+
* Note: this is complicated because some lower ranks don't have higher ranks
|
|
245
|
+
For example, species [Eubacterium] rectale (taxID 39491) has no genus
|
|
246
|
+
Also, species [artifical construct] (taxID 32630) has no anything but species
|
|
247
|
+
|
|
248
|
+
'''
|
|
249
|
+
|
|
250
|
+
from ete3 import NCBITaxa
|
|
251
|
+
ncbi = NCBITaxa()
|
|
252
|
+
|
|
253
|
+
Levels = ['superkingdom','phylum','class','order','family','genus','species']
|
|
254
|
+
|
|
255
|
+
# generate nested dictionary for levels
|
|
256
|
+
countDic = {}
|
|
257
|
+
for level in Levels:
|
|
258
|
+
countDic[level] = {}
|
|
259
|
+
|
|
260
|
+
# fill in nested dictionary
|
|
261
|
+
for t in hits['taxID'].tolist():
|
|
262
|
+
if t == 0:
|
|
263
|
+
continue
|
|
264
|
+
|
|
265
|
+
# This try / except thing is trying to catch sporatic errors of:
|
|
266
|
+
# sqlite3.OperationalError: disk I/O error
|
|
267
|
+
try:
|
|
268
|
+
lin = ncbi.get_lineage(t)
|
|
269
|
+
lin2name = ncbi.get_taxid_translator(lin)
|
|
270
|
+
name2rank = ncbi.get_rank(lin)
|
|
271
|
+
except:
|
|
272
|
+
time.sleep(1)
|
|
273
|
+
lin = ncbi.get_lineage(t)
|
|
274
|
+
lin2name = ncbi.get_taxid_translator(lin)
|
|
275
|
+
name2rank = ncbi.get_rank(lin)
|
|
276
|
+
|
|
277
|
+
for i in lin:
|
|
278
|
+
rank = name2rank[i]
|
|
279
|
+
name = lin2name[i]
|
|
280
|
+
if rank in countDic:
|
|
281
|
+
countDic[rank][i] = countDic[rank].get(i,0) + 1
|
|
282
|
+
|
|
283
|
+
# make the table
|
|
284
|
+
total = sum(countDic['phylum'].values())
|
|
285
|
+
table = {'tax_ID':[], 'tax_confidence':[], 'tax_level':[], 'taxonomy':[]}
|
|
286
|
+
count = None
|
|
287
|
+
|
|
288
|
+
for level in Levels:
|
|
289
|
+
dic = countDic[level]
|
|
290
|
+
for name in sorted(dic, key=dic.get, reverse= True):
|
|
291
|
+
count = dic[name]
|
|
292
|
+
break
|
|
293
|
+
|
|
294
|
+
if count == None:
|
|
295
|
+
table['tax_ID'].append(None)
|
|
296
|
+
table['tax_confidence'].append(0)
|
|
297
|
+
table['tax_level'].append(level)
|
|
298
|
+
table['taxonomy'].append('unk')
|
|
299
|
+
|
|
300
|
+
else:
|
|
301
|
+
lin = ncbi.get_lineage(name)
|
|
302
|
+
lin2name = ncbi.get_taxid_translator(lin)
|
|
303
|
+
name2rank = ncbi.get_rank(lin)
|
|
304
|
+
rank2name = {v: k for k, v in name2rank.items()}
|
|
305
|
+
tax = (lin2name[rank2name[level]])
|
|
306
|
+
|
|
307
|
+
table['tax_ID'].append(name)
|
|
308
|
+
table['tax_confidence'].append(((count/total) *100))
|
|
309
|
+
table['tax_level'].append(level)
|
|
310
|
+
table['taxonomy'].append(tax)
|
|
311
|
+
|
|
312
|
+
count = None
|
|
313
|
+
tdb = pd.DataFrame(table)
|
|
314
|
+
|
|
315
|
+
# find and mark the best hit
|
|
316
|
+
best = tdb['tax_ID'][tdb['tax_confidence'] >= minPerc].tolist()[-1]
|
|
317
|
+
tdb['best_hit'] = [True if i == best else False for i in tdb['tax_ID']]
|
|
318
|
+
|
|
319
|
+
# get the full taxonomy for the best hit
|
|
320
|
+
tdb['full_tax'] = [lineage_from_taxId(t) if b else False for t, b in zip(\
|
|
321
|
+
tdb['tax_ID'], tdb['best_hit'])]
|
|
322
|
+
|
|
323
|
+
return tdb
|
|
324
|
+
|
|
325
|
+
def lineage_from_taxId(t):
|
|
326
|
+
from ete3 import NCBITaxa
|
|
327
|
+
ncbi = NCBITaxa()
|
|
328
|
+
|
|
329
|
+
Levels = ['superkingdom','phylum','class','order','family','genus','species']
|
|
330
|
+
name = []
|
|
331
|
+
|
|
332
|
+
lin = ncbi.get_lineage(t)
|
|
333
|
+
|
|
334
|
+
lin2name = ncbi.get_taxid_translator(lin)
|
|
335
|
+
name2rank = ncbi.get_rank(lin)
|
|
336
|
+
rank2name = {v: k for k, v in name2rank.items()}
|
|
337
|
+
|
|
338
|
+
for level in Levels:
|
|
339
|
+
if level in rank2name:
|
|
340
|
+
name.append(lin2name[rank2name[level]])
|
|
341
|
+
else:
|
|
342
|
+
name.append('unk')
|
|
343
|
+
|
|
344
|
+
return '|'.join([str(int(t))] + name)
|
|
345
|
+
|
|
346
|
+
def parse_raw_centrifuge(hits, report):
|
|
347
|
+
tax = pd.read_table(report)
|
|
348
|
+
t2l = tax.set_index('taxID')['taxRank'].to_dict()
|
|
349
|
+
t2n = tax.set_index('taxID')['name'].to_dict()
|
|
350
|
+
|
|
351
|
+
hits = pd.read_table(hits)
|
|
352
|
+
hits['gene'] = hits['readID']
|
|
353
|
+
hits['scaffold'] = hits['readID'].map(get_scaff)
|
|
354
|
+
hits['level'] = hits['taxID'].map(t2l)
|
|
355
|
+
hits['name'] = hits['taxID'].map(t2n)
|
|
356
|
+
del hits['readID']
|
|
357
|
+
|
|
358
|
+
return hits
|
|
359
|
+
|
|
360
|
+
def add_taxonomy(Bdb,Tdb):
|
|
361
|
+
g2t = {}
|
|
362
|
+
for genome in Tdb['genome'].unique():
|
|
363
|
+
d = Tdb[(Tdb['genome'] == genome) & (Tdb['best_hit'] == True)]
|
|
364
|
+
if len(d) != 1:
|
|
365
|
+
raise ValueError('Bug')
|
|
366
|
+
|
|
367
|
+
tax = d['taxonomy'].tolist()[0]
|
|
368
|
+
g2t[genome] = tax
|
|
369
|
+
Bdb['taxonomy'] = Bdb['genome'].map(g2t)
|
|
370
|
+
return Bdb
|
|
371
|
+
|
|
372
|
+
def gen_phylo_db(hits):
|
|
373
|
+
Table = {'tax_confidence':[],'taxonomy':[],'tax_level':[],'tax_ID':[]}
|
|
374
|
+
|
|
375
|
+
skip = ['uncultured bacterium','Mus musculus', 'Vitis vinifera', 'Homo sapiens']
|
|
376
|
+
|
|
377
|
+
levels = ['leaf','subspecies','species','genus','family']
|
|
378
|
+
total_ORFS = len(hits['gene'].unique())
|
|
379
|
+
for level in levels:
|
|
380
|
+
|
|
381
|
+
# Restrict to the level in question
|
|
382
|
+
d = hits[hits['level'] == level]
|
|
383
|
+
|
|
384
|
+
# Get rid of hits to shitty things
|
|
385
|
+
d = d[~d['name'].isin(skip)]
|
|
386
|
+
|
|
387
|
+
# Only get the top hit for each gene
|
|
388
|
+
d = d.sort_values(by='score')
|
|
389
|
+
d = d[~d.duplicated('gene')]
|
|
390
|
+
|
|
391
|
+
# Find percentage of top tax
|
|
392
|
+
try:
|
|
393
|
+
top_tax = d['name'].mode()[0]
|
|
394
|
+
except:
|
|
395
|
+
Table['tax_level'].append(level)
|
|
396
|
+
Table['tax_ID'].append(None)
|
|
397
|
+
Table['taxonomy'].append(None)
|
|
398
|
+
Table['tax_confidence'].append(None)
|
|
399
|
+
continue
|
|
400
|
+
|
|
401
|
+
x = d[d['name'] == top_tax]
|
|
402
|
+
top_perc = (len(x['gene'].unique()) / total_ORFS) * 100
|
|
403
|
+
tax_ID = x['taxID'].unique()[0]
|
|
404
|
+
|
|
405
|
+
Table['tax_level'].append(level)
|
|
406
|
+
Table['tax_ID'].append(tax_ID)
|
|
407
|
+
Table['taxonomy'].append(top_tax)
|
|
408
|
+
Table['tax_confidence'].append(top_perc)
|
|
409
|
+
|
|
410
|
+
return pd.DataFrame(Table)
|
|
411
|
+
|
|
412
|
+
def get_scaff(read):
|
|
413
|
+
return "_".join(read.split('_')[:-1])
|
|
414
|
+
|
|
415
|
+
def gen_centrifuge_cmd(genes,cent,**kwargs):
|
|
416
|
+
cent_exe = shutil.which('centrifuge')
|
|
417
|
+
if cent_exe == None:
|
|
418
|
+
logging.error("Can't find centrifuge- make sure it's in your system path")
|
|
419
|
+
sys.exit()
|
|
420
|
+
|
|
421
|
+
cent_indicies = kwargs.get('cent_index', False)
|
|
422
|
+
if cent_indicies == False:
|
|
423
|
+
logging.error("Can't find centrifuge index- must provide for taxonomy")
|
|
424
|
+
sys.exit()
|
|
425
|
+
|
|
426
|
+
cmd = [cent_exe, '-f', '-x', cent_indicies, genes, '-S', "{0}_hits.tsv".format(cent),\
|
|
427
|
+
'-p','1','--report-file',"{0}_report.tsv".format(cent)]
|
|
428
|
+
|
|
429
|
+
return cmd
|