annotate bwameth.py @ 5:f9c8c79b8b08 draft

Uploaded
author dpryan79
date Tue, 13 Sep 2016 16:01:35 -0400
parents 3e1095e1defa
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
1 #!/usr/bin/env python
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
2 """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
3 map bisulfite converted reads to an insilico converted genome using bwa mem.
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
4 A command to this program like:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
5
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
6 python bwameth.py --reference ref.fa A.fq B.fq
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
7
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
8 Gets converted to:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
9
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
10 bwa mem -pCMR ref.fa.bwameth.c2t '<python bwameth.py c2t A.fq B.fq'
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
11
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
12 So that A.fq has C's converted to T's and B.fq has G's converted to A's
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
13 and both are streamed directly to the aligner without a temporary file.
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
14 The output is a corrected, sorted, indexed BAM.
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
15 """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
16 from __future__ import print_function
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
17 import tempfile
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
18 import sys
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
19 import os
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
20 import os.path as op
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
21 import argparse
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
22 from subprocess import check_call
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
23 from operator import itemgetter
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
24 from itertools import groupby, repeat, chain
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
25 import re
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
26
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
27 try:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
28 from itertools import izip
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
29 import string
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
30 maketrans = string.maketrans
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
31 except ImportError: # python3
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
32 izip = zip
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
33 maketrans = str.maketrans
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
34 from toolshed import nopen, reader, is_newer_b
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
35
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
36 __version__ = "0.2.0"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
37
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
38 def checkX(cmd):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
39 for p in os.environ['PATH'].split(":"):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
40 if os.access(os.path.join(p, cmd), os.X_OK):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
41 break
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
42 else:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
43 raise Exception("executable for '%s' not found" % cmd)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
44
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
45 checkX('samtools')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
46 checkX('bwa')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
47
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
48 class BWAMethException(Exception): pass
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
49
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
50 def comp(s, _comp=maketrans('ATCG', 'TAGC')):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
51 return s.translate(_comp)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
52
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
53 def wrap(text, width=100): # much faster than textwrap
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
54 try: xrange
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
55 except NameError: xrange = range
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
56 for s in xrange(0, len(text), width):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
57 yield text[s:s+width]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
58
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
59 def run(cmd):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
60 list(nopen("|%s" % cmd.lstrip("|")))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
61
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
62 def fasta_iter(fasta_name):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
63 fh = nopen(fasta_name)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
64 faiter = (x[1] for x in groupby(fh, lambda line: line[0] == ">"))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
65 for header in faiter:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
66 header = next(header)[1:].strip()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
67 yield header, "".join(s.strip() for s in next(faiter)).upper()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
68
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
69 def convert_reads(fq1s, fq2s, out=sys.stdout):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
70
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
71 for fq1, fq2 in zip(fq1s.split(","), fq2s.split(",")):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
72 sys.stderr.write("converting reads in %s,%s\n" % (fq1, fq2))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
73 fq1 = nopen(fq1)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
74 if fq2 != "NA":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
75 fq2 = nopen(fq2)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
76 q2_iter = izip(*[fq2] * 4)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
77 else:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
78 sys.stderr.write("WARNING: running bwameth in single-end mode\n")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
79 q2_iter = repeat((None, None, None, None))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
80 q1_iter = izip(*[fq1] * 4)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
81
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
82 lt80 = 0
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
83 for pair in izip(q1_iter, q2_iter):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
84 for read_i, (name, seq, _, qual) in enumerate(pair):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
85 if name is None: continue
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
86 name = name.rstrip("\r\n").split(" ")[0]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
87 if name[0] != "@":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
88 sys.stderr.write("""ERROR!!!!
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
89 ERROR!!! FASTQ conversion failed
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
90 ERROR!!! expecting FASTQ 4-tuples, but found a record %s that doesn't start with "@"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
91 """ % name)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
92 sys.exit(1)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
93 if name.endswith(("_R1", "_R2")):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
94 name = name[:-3]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
95 elif name.endswith(("/1", "/2")):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
96 name = name[:-2]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
97
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
98 seq = seq.upper().rstrip('\n')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
99 if len(seq) < 80:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
100 lt80 += 1
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
101
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
102 char_a, char_b = ['CT', 'GA'][read_i]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
103 # keep original sequence as name.
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
104 name = " ".join((name,
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
105 "YS:Z:" + seq +
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
106 "\tYC:Z:" + char_a + char_b + '\n'))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
107 seq = seq.replace(char_a, char_b)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
108 out.write("".join((name, seq, "\n+\n", qual)))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
109
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
110 out.flush()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
111 if lt80 > 50:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
112 sys.stderr.write("WARNING: %i reads with length < 80\n" % lt80)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
113 sys.stderr.write(" : this program is designed for long reads\n")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
114 return 0
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
115
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
116 def convert_fasta(ref_fasta, just_name=False):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
117 out_fa = ref_fasta + ".bwameth.c2t"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
118 if just_name:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
119 return out_fa
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
120 msg = "c2t in %s to %s" % (ref_fasta, out_fa)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
121 if is_newer_b(ref_fasta, out_fa):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
122 sys.stderr.write("already converted: %s\n" % msg)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
123 return out_fa
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
124 sys.stderr.write("converting %s\n" % msg)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
125 try:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
126 fh = open(out_fa, "w")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
127 for header, seq in fasta_iter(ref_fasta):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
128 ########### Reverse ######################
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
129 fh.write(">r%s\n" % header)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
130
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
131 #if non_cpg_only:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
132 # for ctx in "TAG": # use "ATC" for fwd
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
133 # seq = seq.replace('G' + ctx, "A" + ctx)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
134 # for line in wrap(seq):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
135 # print >>fh, line
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
136 #else:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
137 for line in wrap(seq.replace("G", "A")):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
138 fh.write(line + '\n')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
139
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
140 ########### Forward ######################
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
141 fh.write(">f%s\n" % header)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
142 for line in wrap(seq.replace("C", "T")):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
143 fh.write(line + '\n')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
144 fh.close()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
145 except:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
146 try:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
147 fh.close()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
148 except UnboundLocalError:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
149 pass
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
150 os.unlink(out_fa)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
151 raise
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
152 return out_fa
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
153
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
154
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
155 def bwa_index(fa):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
156 if is_newer_b(fa, (fa + '.amb', fa + '.sa')):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
157 return
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
158 sys.stderr.write("indexing: %s\n" % fa)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
159 try:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
160 run("bwa index -a bwtsw %s" % fa)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
161 except:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
162 if op.exists(fa + ".amb"):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
163 os.unlink(fa + ".amb")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
164 raise
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
165
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
166 class Bam(object):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
167 __slots__ = 'read flag chrom pos mapq cigar chrom_mate pos_mate tlen \
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
168 seq qual other'.split()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
169 def __init__(self, args):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
170 for a, v in zip(self.__slots__[:11], args):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
171 setattr(self, a, v)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
172 self.other = args[11:]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
173 self.flag = int(self.flag)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
174 self.pos = int(self.pos)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
175 self.tlen = int(float(self.tlen))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
176
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
177 def __repr__(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
178 return "Bam({chr}:{start}:{read}".format(chr=self.chrom,
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
179 start=self.pos,
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
180 read=self.read)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
181
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
182 def __str__(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
183 return "\t".join(str(getattr(self, s)) for s in self.__slots__[:11]) \
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
184 + "\t" + "\t".join(self.other)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
185
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
186 def is_first_read(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
187 return bool(self.flag & 0x40)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
188
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
189 def is_second_read(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
190 return bool(self.flag & 0x80)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
191
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
192 def is_plus_read(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
193 return not (self.flag & 0x10)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
194
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
195 def is_minus_read(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
196 return bool(self.flag & 0x10)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
197
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
198 def is_mapped(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
199 return not (self.flag & 0x4)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
200
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
201 def cigs(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
202 if self.cigar == "*":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
203 yield (0, None)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
204 raise StopIteration
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
205 cig_iter = groupby(self.cigar, lambda c: c.isdigit())
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
206 for g, n in cig_iter:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
207 yield int("".join(n)), "".join(next(cig_iter)[1])
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
208
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
209 def cig_len(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
210 return sum(c[0] for c in self.cigs() if c[1] in
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
211 ("M", "D", "N", "EQ", "X", "P"))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
212
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
213 def left_shift(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
214 left = 0
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
215 for n, cig in self.cigs():
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
216 if cig == "M": break
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
217 if cig == "H":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
218 left += n
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
219 return left
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
220
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
221 def right_shift(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
222 right = 0
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
223 for n, cig in reversed(list(self.cigs())):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
224 if cig == "M": break
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
225 if cig == "H":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
226 right += n
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
227 return -right or None
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
228
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
229 @property
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
230 def original_seq(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
231 try:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
232 return next(x for x in self.other if x.startswith("YS:Z:"))[5:]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
233 except:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
234 sys.stderr.write(repr(self.other) + "\n")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
235 sys.stderr.write(self.read + "\n")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
236 raise
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
237
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
238 @property
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
239 def ga_ct(self):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
240 return [x for x in self.other if x.startswith("YC:Z:")]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
241
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
242 def longest_match(self, patt=re.compile("\d+M")):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
243 return max(int(x[:-1]) for x in patt.findall(self.cigar))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
244
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
245
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
246 def rname(fq1, fq2=""):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
247 fq1, fq2 = fq1.split(",")[0], fq2.split(",")[0]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
248 def name(f):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
249 n = op.basename(op.splitext(f)[0])
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
250 if n.endswith('.fastq'): n = n[:-6]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
251 if n.endswith(('.fq', '.r1', '.r2')): n = n[:-3]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
252 return n
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
253 return "".join(a for a, b in zip(name(fq1), name(fq2)) if a == b) or 'bm'
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
254
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
255
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
256 def bwa_mem(fa, mfq, extra_args, threads=1, rg=None,
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
257 paired=True, set_as_failed=None):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
258 conv_fa = convert_fasta(fa, just_name=True)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
259 if not is_newer_b(conv_fa, (conv_fa + '.amb', conv_fa + '.sa')):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
260 raise BWAMethException("first run bwameth.py index %s" % fa)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
261
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
262 if not rg is None and not rg.startswith('@RG'):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
263 rg = '@RG\tID:{rg}\tSM:{rg}'.format(rg=rg)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
264
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
265 # penalize clipping and unpaired. lower penalty on mismatches (-B)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
266 cmd = "|bwa mem -T 40 -B 2 -L 10 -CM "
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
267
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
268 if paired:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
269 cmd += ("-U 100 -p ")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
270 cmd += "-R '{rg}' -t {threads} {extra_args} {conv_fa} {mfq}"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
271 cmd = cmd.format(**locals())
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
272 sys.stderr.write("running: %s\n" % cmd.lstrip("|"))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
273 as_bam(cmd, fa, set_as_failed)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
274
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
275
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
276 def as_bam(pfile, fa, set_as_failed=None):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
277 """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
278 pfile: either a file or a |process to generate sam output
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
279 fa: the reference fasta
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
280 set_as_failed: None, 'f', or 'r'. If 'f'. Reads mapping to that strand
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
281 are given the sam flag of a failed QC alignment (0x200).
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
282 """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
283 sam_iter = nopen(pfile)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
284
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
285 for line in sam_iter:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
286 if not line[0] == "@": break
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
287 handle_header(line)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
288 else:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
289 sys.stderr.flush()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
290 raise Exception("bad or empty fastqs")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
291 sam_iter2 = (x.rstrip().split("\t") for x in chain([line], sam_iter))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
292 for read_name, pair_list in groupby(sam_iter2, itemgetter(0)):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
293 pair_list = [Bam(toks) for toks in pair_list]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
294
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
295 for aln in handle_reads(pair_list, set_as_failed):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
296 sys.stdout.write(str(aln) + '\n')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
297
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
298 def handle_header(line, out=sys.stdout):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
299 toks = line.rstrip().split("\t")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
300 if toks[0].startswith("@SQ"):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
301 sq, sn, ln = toks # @SQ SN:fchr11 LN:122082543
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
302 # we have f and r, only print out f
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
303 chrom = sn.split(":")[1]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
304 if chrom.startswith('r'): return
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
305 chrom = chrom[1:]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
306 toks = ["%s\tSN:%s\t%s" % (sq, chrom, ln)]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
307 if toks[0].startswith("@PG"):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
308 #out.write("\t".join(toks) + "\n")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
309 toks = ["@PG\tID:bwa-meth\tPN:bwa-meth\tVN:%s\tCL:\"%s\"" % (
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
310 __version__,
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
311 " ".join(x.replace("\t", "\\t") for x in sys.argv))]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
312 out.write("\t".join(toks) + "\n")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
313
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
314
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
315 def handle_reads(alns, set_as_failed):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
316
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
317 for aln in alns:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
318 orig_seq = aln.original_seq
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
319 assert len(aln.seq) == len(aln.qual), aln.read
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
320 # don't need this any more.
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
321 aln.other = [x for x in aln.other if not x.startswith('YS:Z')]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
322
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
323 # first letter of chrom is 'f' or 'r'
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
324 direction = aln.chrom[0]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
325 aln.chrom = aln.chrom.lstrip('fr')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
326
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
327 if not aln.is_mapped():
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
328 aln.seq = orig_seq
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
329 continue
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
330
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
331 assert direction in 'fr', (direction, aln)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
332 aln.other.append('YD:Z:' + direction)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
333
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
334 if set_as_failed == direction:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
335 aln.flag |= 0x200
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
336
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
337 # here we have a heuristic that if the longest match is not 44% of the
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
338 # sequence length, we mark it as failed QC and un-pair it. At the end
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
339 # of the loop we set all members of this pair to be unmapped
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
340 if aln.longest_match() < (len(orig_seq) * 0.44):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
341 aln.flag |= 0x200 # fail qc
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
342 aln.flag &= (~0x2) # un-pair
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
343 aln.mapq = min(int(aln.mapq), 1)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
344
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
345 mate_direction = aln.chrom_mate[0]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
346 if mate_direction not in "*=":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
347 aln.chrom_mate = aln.chrom_mate[1:]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
348
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
349 # adjust the original seq to the cigar
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
350 l, r = aln.left_shift(), aln.right_shift()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
351 if aln.is_plus_read():
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
352 aln.seq = orig_seq[l:r]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
353 else:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
354 aln.seq = comp(orig_seq[::-1][l:r])
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
355
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
356 if any(aln.flag & 0x200 for aln in alns):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
357 for aln in alns:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
358 aln.flag |= 0x200
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
359 aln.flag &= (~0x2)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
360 return alns
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
361
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
362 def cnvs_main(args):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
363 __doc__ = """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
364 calculate CNVs from BS-Seq bams or vcfs
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
365 """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
366 p = argparse.ArgumentParser(__doc__)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
367 p.add_argument("--regions", help="optional target regions", default='NA')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
368 p.add_argument("bams", nargs="+")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
369
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
370 a = p.parse_args(args)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
371 r_script = """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
372 options(stringsAsFactors=FALSE)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
373 suppressPackageStartupMessages(library(cn.mops))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
374 suppressPackageStartupMessages(library(snow))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
375 args = commandArgs(TRUE)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
376 regions = args[1]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
377 bams = args[2:length(args)]
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
378 n = length(bams)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
379 if(is.na(regions)){
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
380 bam_counts = getReadCountsFromBAM(bams, parallel=min(n, 4), mode="paired")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
381 res = cn.mops(bam_counts, parallel=min(n, 4), priorImpact=20)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
382 } else {
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
383 segments = read.delim(regions, header=FALSE)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
384 gr = GRanges(segments[,1], IRanges(segments[,2], segments[,3]))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
385 bam_counts = getSegmentReadCountsFromBAM(bams, GR=gr, mode="paired", parallel=min(n, 4))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
386 res = exomecn.mops(bam_counts, parallel=min(n, 4), priorImpact=20)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
387 }
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
388 res = calcIntegerCopyNumbers(res)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
389
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
390 df = as.data.frame(cnvs(res))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
391 write.table(df, row.names=FALSE, quote=FALSE, sep="\t")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
392 """
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
393 with tempfile.NamedTemporaryFile(delete=True) as rfh:
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
394 rfh.write(r_script + '\n')
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
395 rfh.flush()
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
396 for d in reader('|Rscript {rs_name} {regions} {bams}'.format(
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
397 rs_name=rfh.name, regions=a.regions, bams=" ".join(a.bams)),
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
398 header=False):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
399 print("\t".join(d))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
400
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
401
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
402 def convert_fqs(fqs):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
403 script = __file__
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
404 return "'<%s %s c2t %s %s'" % (sys.executable, script, fqs[0],
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
405 fqs[1] if len(fqs) > 1
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
406 else ','.join(['NA'] * len(fqs[0].split(","))))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
407
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
408 def main(args=sys.argv[1:]):
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
409
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
410 if len(args) > 0 and args[0] == "index":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
411 assert len(args) == 2, ("must specify fasta as 2nd argument")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
412 sys.exit(bwa_index(convert_fasta(args[1])))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
413
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
414 if len(args) > 0 and args[0] == "c2t":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
415 sys.exit(convert_reads(args[1], args[2]))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
416
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
417 if len(args) > 0 and args[0] == "cnvs":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
418 sys.exit(cnvs_main(args[1:]))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
419
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
420 p = argparse.ArgumentParser(__doc__)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
421 p.add_argument("--reference", help="reference fasta", required=True)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
422 p.add_argument("-t", "--threads", type=int, default=6)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
423 p.add_argument("--read-group", help="read-group to add to bam in same"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
424 " format as to bwa: '@RG\\tID:foo\\tSM:bar'")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
425 p.add_argument('--set-as-failed', help="flag alignments to this strand"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
426 " as not passing QC (0x200). Targetted BS-Seq libraries are often"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
427 " to a single strand, so we can flag them as QC failures. Note"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
428 " f == OT, r == OB. Likely, this will be 'f' as we will expect"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
429 " reads to align to the original-bottom (OB) strand and will flag"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
430 " as failed those aligning to the forward, or original top (OT).",
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
431 default=None, choices=('f', 'r'))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
432 p.add_argument('--version', action='version', version='bwa-meth.py {}'.format(__version__))
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
433
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
434 p.add_argument("fastqs", nargs="+", help="bs-seq fastqs to align. Run"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
435 "multiple sets separated by commas, e.g. ... a_R1.fastq,b_R1.fastq"
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
436 " a_R2.fastq,b_R2.fastq note that the order must be maintained.")
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
437
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
438 args, pass_through_args = p.parse_known_args(args)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
439
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
440 # for the 2nd file. use G => A and bwa's support for streaming.
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
441 conv_fqs_cmd = convert_fqs(args.fastqs)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
442
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
443 bwa_mem(args.reference, conv_fqs_cmd, ' '.join(map(str, pass_through_args)),
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
444 threads=args.threads, rg=args.read_group or
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
445 rname(*args.fastqs),
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
446 paired=len(args.fastqs) == 2,
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
447 set_as_failed=args.set_as_failed)
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
448
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
449 if __name__ == "__main__":
3e1095e1defa Deleted selected files
dpryan79
parents:
diff changeset
450 main(sys.argv[1:])