-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwrite_bins_from_tsv.py
More file actions
93 lines (63 loc) · 2.62 KB
/
Copy pathwrite_bins_from_tsv.py
File metadata and controls
93 lines (63 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from collections import defaultdict
import pandas as pd
from pathlib import Path
import argparse
from itertools import takewhile, repeat
from tqdm import tqdm
def get_parser():
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--fasta")
parser.add_argument("-c", "--clusters")
parser.add_argument("--outdir", default=Path(Path.cwd(), "bins"), type=Path)
parser.add_argument("--minbin", default=500_000, type=int)
return parser
def linecount(filename):
print(f"Counting lines from {filename}")
with open(filename, "rb") as file:
bufgen = takewhile(lambda x: x, (file.raw.read(1024*1024) for _ in repeat(None)))
return sum( buf.count(b'\n') for buf in bufgen )
def read_fasta(file):
sequences = dict()
lines = linecount(file)
with open(file) as fasta_read:
header = fasta_read.readline().strip()[1:]
_seq = []
lengths = dict()
for line in tqdm(fasta_read, total=lines-1, desc=f"reading {file}..."):
if line[0] == '>':
sequence = ''.join(_seq)
sequences[header] = sequence
lengths[header] = len(sequence)
sequence = ''
_seq = []
header = line.strip()[1:]
else:
_seq.append(line.strip())
else:
sequence = ''.join(_seq)
sequences[header] = sequence
lengths[header] = len(sequence)
del _seq, header
return sequences, lengths
# Path().mkdir()
def write_bins(fasta_dict, clusters_dict, contiglen, minbin_len, outdir):
outdir.mkdir(parents=True, exist_ok=False)
for bin_, contigs in tqdm(clusters_dict.items(), total=len(clusters_dict), desc=f"Writing bins to {str(outdir)}"):
if sum(contiglen[c] for c in contigs) < minbin_len:
continue
# breakpoint()
with open(outdir / f"{bin_}.fa", "w") as f_write:
f_write.write('\n'.join(">{}\n{}".format(contig, fasta_dict[contig]) for contig in contigs))
def main():
parser = get_parser()
args = parser.parse_args()
clusters = pd.read_csv(args.clusters, index_col=0, header=None, sep='\t')
contig2bin = dict(zip(clusters.index, clusters.iloc[:, 0]))
bin2contig = defaultdict(list)
for contig, bin_ in contig2bin.items():
bin2contig[bin_].append(contig)
del clusters
fasta, contiglen = read_fasta(args.fasta)
write_bins(fasta, bin2contig, contiglen, args.minbin, args.outdir)
if __name__ == "__main__":
main()