bio-mummer 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/delta2gvcf.rb +161 -109
- data/lib/bio-mummer/mummer.rb +20 -20
- data/test/test_bio-mummer.rb +2 -2
- metadata +2 -3
- data/.document +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 299d153188c65b1881bf1635b7389276ab1733f2
|
4
|
+
data.tar.gz: 3e3bf43c9c1551715d82c40bfd6c1b151f58dc2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c397099eb1478ceb5bc65d9657c64cfbe1bd02d2d0ce8e91a878065d1cf24407553d2f9609f8102af8b361d30b9048a499c4863a2b0772462f1977ae7d4d75ea
|
7
|
+
data.tar.gz: 3b1cdf0711552be2cdbfb3d1ad309d5d8abcdf7bbdae096cbcf439c6a9da2bba181b1085088ff4e1dcf1f8f84839186337977b048f7a89700b8c800717c71501
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.1
|
data/bin/delta2gvcf.rb
CHANGED
@@ -20,6 +20,7 @@ class OptParser
|
|
20
20
|
opts.on("-d", "--delta FILENAME", "Delta file generated by nucmer") do |fn|
|
21
21
|
pn = Pathname.new(fn)
|
22
22
|
if pn.size?
|
23
|
+
options.samplename = pn.basename(".delta")
|
23
24
|
options.delta = pn
|
24
25
|
match = pn.each_line.first.match(/(?<ref>\/.*) (?<qry>\/.*)/)
|
25
26
|
if match
|
@@ -38,6 +39,10 @@ class OptParser
|
|
38
39
|
exit(1)
|
39
40
|
end
|
40
41
|
end
|
42
|
+
|
43
|
+
opts.on("-s", "--sample SAMPLENAME", "gVCF Sample name") do |samplename|
|
44
|
+
options.samplename = samplename
|
45
|
+
end
|
41
46
|
end
|
42
47
|
opt_parser.parse!(args)
|
43
48
|
return options
|
@@ -45,7 +50,6 @@ class OptParser
|
|
45
50
|
end
|
46
51
|
options = OptParser.parse(ARGV)
|
47
52
|
|
48
|
-
# Open the Delta File
|
49
53
|
d = BioMummer::DeltaFile.new(StringIO.new(`delta-filter -r -q #{options.delta}`))
|
50
54
|
|
51
55
|
puts '##fileformat=VCFv4.1
|
@@ -57,125 +61,173 @@ puts '##fileformat=VCFv4.1
|
|
57
61
|
##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
|
58
62
|
##FORMAT=<ID=MIN_DP,Number=1,Type=Integer,Description="Minimum DP observed within the GVCF block">
|
59
63
|
##FORMAT=<ID=PL,Number=G,Type=Integer,Description="Normalized, Phred-scaled likelihoods for genotypes as defined in the VCF specification">'
|
60
|
-
|
61
64
|
options.ref.each do |name, seq|
|
62
65
|
puts "##contig=<ID=#{name},length=#{seq.length}>"
|
63
66
|
end
|
64
|
-
puts "
|
67
|
+
puts '##INFO=<ID=BaseQRankSum,Number=1,Type=Float,Description="Z-score from Wilcoxon rank sum test of Alt Vs. Ref base qualities">
|
68
|
+
##INFO=<ID=ClippingRankSum,Number=1,Type=Float,Description="Z-score From Wilcoxon rank sum test of Alt vs. Ref number of hard clipped bases">
|
69
|
+
##INFO=<ID=DP,Number=1,Type=Integer,Description="Approximate read depth; some reads may have been filtered">
|
70
|
+
##INFO=<ID=DS,Number=0,Type=Flag,Description="Were any of the samples downsampled?">
|
71
|
+
##INFO=<ID=END,Number=1,Type=Integer,Description="Stop position of the interval">
|
72
|
+
##INFO=<ID=HaplotypeScore,Number=1,Type=Float,Description="Consistency of the site with at most two segregating haplotypes">
|
73
|
+
##INFO=<ID=InbreedingCoeff,Number=1,Type=Float,Description="Inbreeding coefficient as estimated from the genotype likelihoods per-sample when compared against the Hardy-Weinberg expectation">
|
74
|
+
##INFO=<ID=MLEAC,Number=A,Type=Integer,Description="Maximum likelihood expectation (MLE) for the allele counts (not necessarily the same as the AC), for each ALT allele, in the same order as listed">
|
75
|
+
##INFO=<ID=MLEAF,Number=A,Type=Float,Description="Maximum likelihood expectation (MLE) for the allele frequency (not necessarily the same as the AF), for each ALT allele, in the same order as listed">
|
76
|
+
##INFO=<ID=MQ,Number=1,Type=Float,Description="RMS Mapping Quality">
|
77
|
+
##INFO=<ID=MQ0,Number=1,Type=Integer,Description="Total Mapping Quality Zero Reads">
|
78
|
+
##INFO=<ID=MQRankSum,Number=1,Type=Float,Description="Z-score From Wilcoxon rank sum test of Alt vs. Ref read mapping qualities">
|
79
|
+
##INFO=<ID=ReadPosRankSum,Number=1,Type=Float,Description="Z-score from Wilcoxon rank sum test of Alt vs. Ref read position bias">'
|
80
|
+
puts "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT\t#{options.samplename}"
|
65
81
|
|
66
82
|
d.alignments
|
67
|
-
.group_by{|
|
68
|
-
.
|
83
|
+
.group_by{ |alignment| alignment.refname }
|
84
|
+
.sort_by{ |refname, alignments| refname }
|
69
85
|
.each do |refname, alignments|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
86
|
+
|
87
|
+
clusters = Enumerator.new do |yielder|
|
88
|
+
# We sweep along each of the reference sequences. The cursor tracks
|
89
|
+
# our position as we go so we don't concatenate regions that are
|
90
|
+
# actually overlapping.
|
91
|
+
cursor = 1
|
92
|
+
|
93
|
+
# The =alignments= object is an array of BioMummer::Alignment
|
94
|
+
# objects that all match a particular scaffold.
|
95
|
+
alignments
|
96
|
+
.sort_by{ |alignment| alignment.refstart }.
|
97
|
+
each do |aln|
|
98
|
+
# Create Bio::Sequence::NA subsequences for the reference and
|
99
|
+
# query. They are initially unaligned.
|
100
|
+
refSeq = options.ref[aln.refname].subseq(aln.refstart, aln.refstop)
|
101
|
+
qrySeq = options.qry[aln.qryname].subseq(aln.qrystart, aln.qrystop)
|
102
|
+
qrySeq.complement! unless aln.strand
|
103
|
+
|
104
|
+
# Do we have uncovered bases before the alignment starts? These
|
105
|
+
# are detected as gaps between the cursor and the alignment start
|
106
|
+
# site in the reference.
|
107
|
+
gap_size = aln.refstart - cursor
|
108
|
+
overlap_size = 0
|
109
|
+
if gap_size > 0
|
110
|
+
# There is a stretch of reference bases without an alignment
|
111
|
+
gapSeq = options.ref[aln.refname].subseq(cursor, aln.refstart - 1)
|
112
|
+
gapSeq
|
113
|
+
.chars
|
114
|
+
.zip(("-" * gapSeq.length).chars, Range.new(cursor, aln.refstart, true))
|
115
|
+
.each{ |ary| yielder << ary }
|
116
|
+
cursor = aln.refstart
|
100
117
|
else
|
101
|
-
|
102
|
-
end
|
103
|
-
end.drop_while do |varClass, arr|
|
104
|
-
if varClass != "INS"
|
105
|
-
overlap, overlap2 = overlap - arr.length , overlap
|
118
|
+
overlap_size = cursor - aln.refstart
|
106
119
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
120
|
+
|
121
|
+
# Nucmer records insertions and deletions as a series of positive
|
122
|
+
# and negative integers corresponding to how many steps along the
|
123
|
+
# alignment until you get to the next gap in the reference
|
124
|
+
# sequence (positive integer) or how many steps until the next gap
|
125
|
+
# in the query (negative integer). BioMummer exposes these as the
|
126
|
+
# alignments 'distances' array.
|
127
|
+
# We walk along the Bio::Sequence::NA objects and insert gaps
|
128
|
+
# (".") when needed. We store our current position in the
|
129
|
+
# reference and the query in a two-element array.
|
130
|
+
aln.distances.inject([0,0]) do |mem, distance_to_gap|
|
131
|
+
if distance_to_gap > 0
|
132
|
+
qrySeq.insert(mem[0] + distance_to_gap - 1, ".")
|
133
|
+
[mem[0] + distance_to_gap, mem[1] + distance_to_gap]
|
113
134
|
else
|
114
|
-
|
115
|
-
|
116
|
-
end
|
117
|
-
puts [refname,
|
118
|
-
cursor,
|
119
|
-
".",
|
120
|
-
refBase,
|
121
|
-
"<NON_REF>",
|
122
|
-
'.',
|
123
|
-
'.',
|
124
|
-
"END=#{cursor + arr.length - 1 - overlap2};ALTSCAFF=#{a.queryname};RLEN=#{arr.length};OVERLAP2=#{overlap2}",
|
125
|
-
"GT:DP:GQ:MIN_DP:PL",
|
126
|
-
"0:200:200:200:0,800"].join("\t")
|
127
|
-
cursor += arr.length - overlap2
|
128
|
-
overlap2 = 0
|
129
|
-
when "SNP"
|
130
|
-
arr.each do |snp|
|
131
|
-
puts [refname,
|
132
|
-
cursor,
|
133
|
-
".",
|
134
|
-
snp.first.upcase,
|
135
|
-
[snp.last.upcase, "<NON_REF>"].join(","),
|
136
|
-
'.',
|
137
|
-
'.',
|
138
|
-
"END=#{cursor};ALTSCAFF=#{a.queryname}",
|
139
|
-
"GT:DP:GQ:MIN_DP:PL",
|
140
|
-
"1:200:200:200:800,0,800"].join("\t")
|
141
|
-
cursor += 1
|
135
|
+
refSeq.insert(mem[1] - distance_to_gap - 1, ".")
|
136
|
+
[mem[0] - distance_to_gap, mem[1] - distance_to_gap]
|
142
137
|
end
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# cursor += arr.length
|
154
|
-
when "INS"
|
155
|
-
refBase = options.ref[refname][cursor-2].upcase
|
156
|
-
puts [refname,
|
157
|
-
cursor-1,
|
158
|
-
".",
|
159
|
-
refBase,
|
160
|
-
[(refBase + arr.map{|a| a.last}.join).upcase, "<NON_REF>"].join(","),
|
161
|
-
'.',
|
162
|
-
'.',
|
163
|
-
"END=#{cursor - 1};ALTSCAFF=#{a.queryname};STRAND=#{a.strand}",
|
164
|
-
"GT:DP:GQ:MIN_DP:PL",
|
165
|
-
"1:200:200:200:800,0,800"].join("\t")
|
166
|
-
when "DEL"
|
167
|
-
puts [refname,
|
168
|
-
cursor,
|
169
|
-
".",
|
170
|
-
arr.map{|a| a.first.upcase}.join,
|
171
|
-
".,<NON_REF>",
|
172
|
-
'.',
|
173
|
-
'.',
|
174
|
-
"END=#{cursor + arr.length - 1};ALTSCAFF=#{a.queryname}",
|
175
|
-
"GT:DP:GQ:MIN_DP:PL",
|
176
|
-
"1:200:200:200:800,0,800"].join("\t")
|
177
|
-
cursor += arr.length
|
138
|
+
end
|
139
|
+
|
140
|
+
if overlap_size < refSeq.length
|
141
|
+
i = aln.refstart - 1
|
142
|
+
positions = refSeq.chars.map{ |base| base == '.' ? i : i+=1 }
|
143
|
+
refSeq
|
144
|
+
.chars
|
145
|
+
.zip(qrySeq.chars, positions)
|
146
|
+
.drop(overlap_size)
|
147
|
+
.each{ |ary| yielder << ary }
|
178
148
|
end
|
179
149
|
end
|
180
150
|
end
|
151
|
+
|
152
|
+
cursor = 0
|
153
|
+
stolen_zipped = [nil, nil, nil]
|
154
|
+
chunked = clusters.find_all do |refBase, qryBase, position|
|
155
|
+
if position > cursor || (position == cursor && refBase == ".")
|
156
|
+
cursor = position
|
157
|
+
true
|
158
|
+
else
|
159
|
+
false
|
160
|
+
end
|
161
|
+
end.chunk do |refBase, qryBase, position|
|
162
|
+
# Classify runs of identiry, insertions, deletions or SNPs.
|
163
|
+
if refBase == qryBase
|
164
|
+
:NO_VARIATION
|
165
|
+
elsif qryBase == "-"
|
166
|
+
:NO_COVERAGE
|
167
|
+
elsif qryBase == '.'
|
168
|
+
:DELETION
|
169
|
+
elsif refBase == '.'
|
170
|
+
:INSERTION
|
171
|
+
else
|
172
|
+
:SNP
|
173
|
+
end
|
174
|
+
end.to_a
|
175
|
+
|
176
|
+
chunked.each_cons(2) do |current, upcoming|
|
177
|
+
cur_class = current.first
|
178
|
+
cur_zipped = current.last
|
179
|
+
nxt_class = upcoming.first
|
180
|
+
|
181
|
+
if nxt_class == :INSERTION || nxt_class == :DELETION
|
182
|
+
stolen_zipped = cur_zipped.pop
|
183
|
+
next if cur_zipped.length == 0
|
184
|
+
end
|
185
|
+
|
186
|
+
case cur_class
|
187
|
+
when :NO_COVERAGE
|
188
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{cur_zipped.first.first.upcase}\t<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t0:0:0:0,0"
|
189
|
+
when :NO_VARIATION
|
190
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{cur_zipped.first.first.upcase}\t<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t0:1:200:0,800"
|
191
|
+
when :SNP
|
192
|
+
cur_zipped.each do |refBase, qryBase, position|
|
193
|
+
puts "#{refname}\t#{position}\t.\t#{refBase.upcase}\t#{qryBase.upcase},<NON_REF>\t.\t.\tEND=#{position}\tGT:DP:GQ:PL\t1:1:200:800,0,800"
|
194
|
+
end
|
195
|
+
when :INSERTION
|
196
|
+
refSeq, qrySeq = cur_zipped.unshift(stolen_zipped).transpose.map{|seq| seq.reject{|c|c=='.'}.join.upcase }
|
197
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{refSeq}\t#{qrySeq},<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t1:1:200:800,0,800"
|
198
|
+
when :DELETION
|
199
|
+
refSeq, qrySeq = cur_zipped.unshift(stolen_zipped).transpose.map{|seq| seq.reject{|c|c=='.'}.join.upcase }
|
200
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{refSeq}\t#{qrySeq},<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t1:1:200:800,0,800"
|
201
|
+
end
|
202
|
+
cursor = [cursor, cur_zipped.last.last].max
|
203
|
+
end
|
204
|
+
|
205
|
+
# We iterated over the entries in a window of length two, outputting
|
206
|
+
# the first in the pair. This leaves the last entry unobserved, so
|
207
|
+
# we take special care to output it here
|
208
|
+
cur_class, cur_zipped = chunked.last
|
209
|
+
case cur_class
|
210
|
+
when :NO_COVERAGE
|
211
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{cur_zipped.first.first.upcase}\t<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t0:0:0:0,0"
|
212
|
+
when :NO_VARIATION
|
213
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{cur_zipped.first.first.upcase}\t<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t0:1:200:0,800"
|
214
|
+
when :SNP
|
215
|
+
cur_zipped.each do |refBase, qryBase, position|
|
216
|
+
puts "#{refname}\t#{position}\t.\t#{refBase.upcase}\t#{qryBase.upcase},<NON_REF>\t.\t.\tEND=#{position}\tGT:DP:GQ:PL\t1:1:200:800,0,800"
|
217
|
+
end
|
218
|
+
when :INSERTION
|
219
|
+
refSeq, qrySeq = cur_zipped.unshift(stolen_zipped).transpose.map{|seq| seq.reject{|c|c=='.'}.join.upcase }
|
220
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{refSeq}\t#{qrySeq},<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t1:1:200:800,0,800"
|
221
|
+
when :DELETION
|
222
|
+
refSeq, qrySeq = cur_zipped.unshift(stolen_zipped).transpose.map{|seq| seq.reject{|c|c=='.'}.join.upcase }
|
223
|
+
puts "#{refname}\t#{cur_zipped.first.last}\t.\t#{refSeq}\t#{qrySeq},<NON_REF>\t.\t.\tEND=#{cur_zipped.last.last}\tGT:DP:GQ:PL\t1:1:200:800,0,800"
|
224
|
+
end
|
225
|
+
|
226
|
+
# It's likely that the alignments don't run to the end of the
|
227
|
+
# scaffold, so we fill in to the scaffold end with the 'no coverage'
|
228
|
+
# entry
|
229
|
+
remaining = options.ref[refname].length - cursor
|
230
|
+
if remaining > 0
|
231
|
+
puts "#{refname}\t#{cursor+1}\t.\t#{options.ref[refname][cursor].upcase}\t<NON_REF>\t.\t.\tEND=#{options.ref[refname].length}\tGT:DP:GQ:PL\t0:0:0:0,0"
|
232
|
+
end
|
181
233
|
end
|
data/lib/bio-mummer/mummer.rb
CHANGED
@@ -3,15 +3,15 @@ require 'stringio'
|
|
3
3
|
module BioMummer
|
4
4
|
|
5
5
|
class Alignment
|
6
|
-
attr_accessor :refname, :
|
6
|
+
attr_accessor :refname, :qryname, :refstart, :refstop, :qrystart, :qrystop, :strand, :distances
|
7
7
|
|
8
|
-
def initialize(refname,
|
8
|
+
def initialize(refname, qryname, refstart, refstop, qrystart, qrystop, strand, distances)
|
9
9
|
@refname = refname
|
10
|
-
@
|
10
|
+
@qryname = qryname
|
11
11
|
@refstart = refstart
|
12
12
|
@refstop = refstop
|
13
|
-
@
|
14
|
-
@
|
13
|
+
@qrystart = qrystart
|
14
|
+
@qrystop = qrystop
|
15
15
|
@strand = strand
|
16
16
|
@distances = distances
|
17
17
|
end
|
@@ -35,13 +35,13 @@ module BioMummer
|
|
35
35
|
|
36
36
|
def ref_to_query(ref_position)
|
37
37
|
position_in_alignment = ref_position - refstart + 1
|
38
|
-
|
38
|
+
qrypos = nil
|
39
39
|
if position_in_alignment >= deltas.length
|
40
|
-
|
40
|
+
qrypos = @qrystart - 1 + position_in_alignment + deltas.last
|
41
41
|
elsif deltas[position_in_alignment-1]
|
42
|
-
|
42
|
+
qrypos = @qrystart - 1 + position_in_alignment + deltas[position_in_alignment-1]
|
43
43
|
end
|
44
|
-
!@strand &&
|
44
|
+
!@strand && qrypos ? @qrystart + @qrystop - qrypos : qrypos
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -64,21 +64,21 @@ module BioMummer
|
|
64
64
|
|
65
65
|
def parse(string)
|
66
66
|
string.split("\n").slice_before(/^>/).flat_map do |block|
|
67
|
-
refname,
|
67
|
+
refname, qryname = block.shift.match(/>(.*) (.*) \d+ \d+/).captures
|
68
68
|
block.slice_before(/\d+ \d+ \d+ \d+/).map do |alignment|
|
69
|
-
refstart, refstop,
|
69
|
+
refstart, refstop, qrystart, qrystop = alignment
|
70
70
|
.shift
|
71
71
|
.match(/(\d+) (\d+) (\d+) (\d+) /)
|
72
72
|
.captures
|
73
73
|
.map{ |c| c.to_i }
|
74
74
|
alignment.pop
|
75
75
|
Alignment.new(refname,
|
76
|
-
|
76
|
+
qryname,
|
77
77
|
refstart,
|
78
78
|
refstop,
|
79
|
-
[
|
80
|
-
[
|
81
|
-
|
79
|
+
[qrystart, qrystop].min,
|
80
|
+
[qrystart, qrystop].max,
|
81
|
+
qrystart < qrystop,
|
82
82
|
alignment.map{ |i| i.to_i })
|
83
83
|
end
|
84
84
|
end
|
@@ -110,13 +110,13 @@ module BioMummer
|
|
110
110
|
a.refname == refname && a.refstart <= startpos && a.refstop >= endpos
|
111
111
|
end
|
112
112
|
if a
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
if
|
113
|
+
qryname = a.qryname
|
114
|
+
qrystart = a.ref_to_query(startpos)
|
115
|
+
qrystop = a.ref_to_query(endpos)
|
116
|
+
if qrystart.nil? || qrystop.nil?
|
117
117
|
return nil
|
118
118
|
else
|
119
|
-
return [
|
119
|
+
return [qryname, qrystart, qrystop, a.strand]
|
120
120
|
end
|
121
121
|
else
|
122
122
|
return nil
|
data/test/test_bio-mummer.rb
CHANGED
@@ -15,8 +15,8 @@ class TestBioMummer < MiniTest::Test
|
|
15
15
|
assert_kind_of Fixnum, @report.alignments.first.refstart
|
16
16
|
assert_equal 1, @report.alignments.first.refstart
|
17
17
|
assert_equal 2435, @report.alignments.first.refstop
|
18
|
-
assert_equal 1, @report.alignments.first.
|
19
|
-
assert_equal 2435, @report.alignments.first.
|
18
|
+
assert_equal 1, @report.alignments.first.qrystart
|
19
|
+
assert_equal 2435, @report.alignments.first.qrystop
|
20
20
|
end
|
21
21
|
|
22
22
|
should "do basic coordinate transforms on the positive strand" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bio-mummer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- robsyme
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: shoulda
|
@@ -105,7 +105,6 @@ extra_rdoc_files:
|
|
105
105
|
- README.md
|
106
106
|
- README.rdoc
|
107
107
|
files:
|
108
|
-
- .document
|
109
108
|
- .travis.yml
|
110
109
|
- Gemfile
|
111
110
|
- LICENSE.txt
|