bioinform 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -17
- data/Gemfile +4 -4
- data/LICENSE +21 -21
- data/README.md +29 -29
- data/Rakefile +5 -12
- data/bioinform.gemspec +21 -21
- data/lib/bioinform/data_models/collection.rb +2 -0
- data/lib/bioinform/data_models/{iupac.rb → old_style_models_TO_BE_REMOVED/iupac.rb} +1 -1
- data/lib/bioinform/data_models/{iupac_word.rb → old_style_models_TO_BE_REMOVED/iupac_word.rb} +0 -0
- data/lib/bioinform/data_models/{positional_count_matrix.rb → old_style_models_TO_BE_REMOVED/positional_count_matrix.rb} +0 -0
- data/lib/bioinform/data_models/{positional_matrix.rb → old_style_models_TO_BE_REMOVED/positional_matrix.rb} +3 -5
- data/lib/bioinform/data_models/{positional_probability_matrix.rb → old_style_models_TO_BE_REMOVED/positional_probability_matrix.rb} +0 -0
- data/lib/bioinform/data_models/{positional_weight_matrix.rb → old_style_models_TO_BE_REMOVED/positional_weight_matrix.rb} +0 -0
- data/lib/bioinform/data_models/parser.rb +41 -0
- data/lib/bioinform/data_models/parsers/array_parser.rb +17 -0
- data/lib/bioinform/data_models/parsers/hash_parser.rb +19 -0
- data/lib/bioinform/data_models/parsers/string_fantom_parser.rb +21 -0
- data/lib/bioinform/data_models/parsers/string_parser.rb +45 -0
- data/lib/bioinform/data_models/parsers.rb +4 -0
- data/lib/bioinform/data_models/pcm.rb +7 -0
- data/lib/bioinform/data_models/pm.rb +195 -0
- data/lib/bioinform/data_models/ppm.rb +8 -0
- data/lib/bioinform/data_models/pwm.rb +23 -0
- data/lib/bioinform/data_models.rb +5 -5
- data/lib/bioinform/support/callable_symbol.rb +33 -4
- data/lib/bioinform/support/collect_hash.rb +7 -0
- data/lib/bioinform/support/curry_except_self.rb +2 -2
- data/lib/bioinform/support/deep_dup.rb +5 -0
- data/lib/bioinform/support/delete_many.rb +14 -0
- data/lib/bioinform/support/has_keys.rb +14 -0
- data/lib/bioinform/support/inverf.rb +13 -0
- data/lib/bioinform/support/partial_sums.rb +6 -0
- data/lib/bioinform/support/{same.rb → same_by.rb} +1 -1
- data/lib/bioinform/support.rb +13 -5
- data/lib/bioinform/version.rb +3 -3
- data/lib/bioinform.rb +8 -7
- data/spec/data_models/parser_spec.rb +46 -0
- data/spec/data_models/parsers/array_parser_spec.rb +53 -0
- data/spec/data_models/parsers/hash_parser_spec.rb +60 -0
- data/spec/data_models/parsers/string_fantom_parser_spec.rb +38 -0
- data/spec/data_models/parsers/string_parser_spec.rb +112 -0
- data/spec/data_models/pm_spec.rb +369 -0
- data/spec/data_models/pwm_spec.rb +25 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/callable_symbol_spec.rb +66 -0
- data/spec/support/collect_hash_spec.rb +15 -0
- data/spec/support/curry_except_self_spec.rb +9 -0
- data/spec/support/delete_many_spec.rb +44 -0
- data/spec/support/has_keys_spec.rb +48 -0
- data/spec/support/inverf_spec.rb +19 -0
- data/spec/support/multiline_squish_spec.rb +11 -0
- data/spec/support/partial_sums_spec.rb +9 -0
- data/spec/support/same_by_spec.rb +36 -0
- metadata +60 -21
- data/lib/bioinform/support/pmap.rb +0 -10
- data/lib/bioinform/support/ptap.rb +0 -7
- data/spec/callable_symbol_spec.rb +0 -37
- data/spec/pmap_test.rb +0 -24
- data/spec/positional_matrix_spec.rb +0 -169
- data/spec/ptap_spec.rb +0 -17
- data/spec/same_spec.rb +0 -19
@@ -0,0 +1,369 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/data_models/pm'
|
3
|
+
|
4
|
+
module Bioinform
|
5
|
+
describe PM do
|
6
|
+
include PM::Parser::Helpers
|
7
|
+
|
8
|
+
describe '#valid?' do
|
9
|
+
it 'should be true iff an argument is an array of arrays of 4 numerics in a column' do
|
10
|
+
PM.new.instance_eval{@matrix = [[1,2,3,4],[1,4,5,6.5]]; self }.valid?.should be_true
|
11
|
+
PM.new.instance_eval{@matrix = {A: [1,1], C: [2,4], G: [3,5], T: [4, 6.5]}; self }.valid?.should be_false
|
12
|
+
PM.new.instance_eval{@matrix = [{A:1,C:2,G:3,T:4},{A:1,C:4,G:5,T: 6.5}]; self }.valid?.should be_false
|
13
|
+
PM.new.instance_eval{@matrix = [[1,2,3,4],[1,4,6.5]]; self }.valid?.should be_false
|
14
|
+
PM.new.instance_eval{@matrix = [[1,2,3],[1,4,6.5]]; self }.valid?.should be_false
|
15
|
+
PM.new.instance_eval{@matrix = [[1,2,'3','4'],[1,'4','5',6.5]]; self }.valid?.should be_false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#initialize' do
|
20
|
+
context 'when parser specified' do
|
21
|
+
before :each do
|
22
|
+
parser_stub :ParserBad, false, { matrix: [[0,0,0,0],[1,1,1,1]], name: 'Bad' }
|
23
|
+
parser_stub :ParserGood, true, { matrix: [[1,1,1,1],[1,1,1,1]], name: 'Good' }
|
24
|
+
parser_stub :ParserWithIncompleteOutput, true, { name: 'Without `matrix` key' }
|
25
|
+
parser_stub :ParserGoodWithoutName, true, { matrix: [[1,1,1,1],[1,1,1,1]] }
|
26
|
+
parser_stub :ParserWithInvalidMatrix, true, { matrix: [[1,1,1],[1,1,1]] }
|
27
|
+
end
|
28
|
+
after :each do
|
29
|
+
parser_subclasses_cleanup
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should raise an ArgumentError if parser cannot parse input' do
|
33
|
+
expect{ PM.new('my stub input', ParserBad) }.to raise_error ArgumentError
|
34
|
+
end
|
35
|
+
it 'should raise an ArgumentError if parser output doesn\'t have `matrix` key' do
|
36
|
+
expect{ PM.new('my stub input', ParserWithIncompleteOutput) }.to raise_error ArgumentError
|
37
|
+
end
|
38
|
+
it 'should raise an ArgumentError if parser output has invalid matrix' do
|
39
|
+
expect{ PM.new('my stub input', ParserWithInvalidMatrix) }.to raise_error ArgumentError
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when parse was successful' do
|
43
|
+
it 'should load matrix from parser\'s resulting hash' do
|
44
|
+
pm = PM.new('my stub input', ParserGoodWithoutName)
|
45
|
+
pm.matrix.should == [[1,1,1,1],[1,1,1,1]]
|
46
|
+
pm.name.should be_nil
|
47
|
+
end
|
48
|
+
it 'should set other available attributes from parse resulting hash' do
|
49
|
+
pm = PM.new('my stub input', ParserGood)
|
50
|
+
pm.matrix.should == [[1,1,1,1],[1,1,1,1]]
|
51
|
+
pm.name.should == 'Good'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when parser not specified' do
|
57
|
+
after :each do
|
58
|
+
parser_subclasses_cleanup
|
59
|
+
end
|
60
|
+
it 'should raise an ArgumentError if no one parser can parse input' do
|
61
|
+
parser_stub :ParserBad, false, { matrix: [[0,0,0,0],[1,1,1,1]], name: 'Bad' }
|
62
|
+
expect{ PM.new('my stub input') }.to raise_error ArgumentError
|
63
|
+
end
|
64
|
+
it 'should use first parsed which can parse input' do
|
65
|
+
parser_stub :ParserBad, false, { matrix: [[0,0,0,0],[1,1,1,1]], name: 'Bad' }
|
66
|
+
parser_stub :ParserGoodFirst, true, { matrix: [[1,1,1,1],[1,1,1,1]], name: 'GoodFirst' }
|
67
|
+
parser_stub :ParserGoodSecond, true, { matrix: [[1,1,1,1],[1,1,1,1]], name: 'GoodSecond' }
|
68
|
+
|
69
|
+
pm = PM.new('my stub input')
|
70
|
+
pm.name.should == 'GoodFirst'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#matrix=' do
|
76
|
+
it 'should replace matrix if argument is a valid matrix' do
|
77
|
+
@pm = PM.new()
|
78
|
+
@pm.matrix.should be_nil
|
79
|
+
|
80
|
+
@pm.matrix = [[1,2,3,4],[1,4,5,6.5]]
|
81
|
+
@pm.matrix.should == [[1,2,3,4],[1,4,5,6.5]]
|
82
|
+
|
83
|
+
@pm.matrix = [[1,4,5,6.5], [2,2,2,2]]
|
84
|
+
@pm.matrix.should == [[1,4,5,6.5],[2,2,2,2]]
|
85
|
+
end
|
86
|
+
it 'should raise an exception if argument isn\'t valid matrix' do
|
87
|
+
@pm = PM.new
|
88
|
+
expect{ @pm.matrix = [[1,2,3,4],[1,4,5]] }.to raise_error
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#to_s' do
|
93
|
+
before :each do
|
94
|
+
@pm = PM.new
|
95
|
+
@pm.matrix = [[1,2,3,4],[1,4,5,6.5]]
|
96
|
+
end
|
97
|
+
it 'should return string with single-tabulated multiline matrix' do
|
98
|
+
@pm.to_s.should == "1\t2\t3\t4\n1\t4\t5\t6.5"
|
99
|
+
end
|
100
|
+
it 'should return positions in rows, letters in cols' do
|
101
|
+
@pm.to_s.split("\n").size.should == 2
|
102
|
+
@pm.to_s.split("\n").map{|pos| pos.split.size}.all?{|sz| sz==4}.should be_true
|
103
|
+
end
|
104
|
+
context 'with name specified' do
|
105
|
+
before :each do
|
106
|
+
@pm.name = 'Stub name'
|
107
|
+
end
|
108
|
+
it 'should return a string with a name and a matrix from the next line' do
|
109
|
+
@pm.to_s.should == "Stub name\n1\t2\t3\t4\n1\t4\t5\t6.5"
|
110
|
+
end
|
111
|
+
it 'should not return a name if argument is set to false' do
|
112
|
+
@pm.to_s(false).should == "1\t2\t3\t4\n1\t4\t5\t6.5"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#pretty_string' do
|
118
|
+
it 'should return a string formatted with spaces'
|
119
|
+
it 'should contain first string of ACGT letters'
|
120
|
+
context 'with name specified' do
|
121
|
+
it 'should contain name if parameter isn\'t false'
|
122
|
+
end
|
123
|
+
context 'without name specified' do
|
124
|
+
it 'should not contain name'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#size' do
|
129
|
+
it 'should return number of positions' do
|
130
|
+
@pm = PM.new
|
131
|
+
@pm.matrix = [[1,2,3,4],[1,4,5,6.5]]
|
132
|
+
@pm.size.should == 2
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '#to_hash' do
|
137
|
+
before :each do
|
138
|
+
@pm = PM.new
|
139
|
+
@pm.matrix = [[1,2,3,4],[1,4,5,6.5]]
|
140
|
+
@hsh = @pm.to_hash
|
141
|
+
end
|
142
|
+
it 'should return a hash with keys A, C, G, T' do
|
143
|
+
@hsh.should be_kind_of Hash
|
144
|
+
@hsh.keys.sort.should == %w{A C G T}
|
145
|
+
end
|
146
|
+
it 'should contain matrix elements of corresponding letter' do
|
147
|
+
@hsh['A'].should == [1, 1]
|
148
|
+
@hsh['C'].should == [2, 4]
|
149
|
+
@hsh['G'].should == [3, 5]
|
150
|
+
@hsh['T'].should == [4, 6.5]
|
151
|
+
end
|
152
|
+
it 'should be accessible both by name and symbol (e.g. pm.to_hash[:A] or pm.to_hash[\'A\'] is the same)' do
|
153
|
+
@hsh['A'].should == @hsh[:A]
|
154
|
+
@hsh['C'].should == @hsh[:C]
|
155
|
+
@hsh['G'].should == @hsh[:G]
|
156
|
+
@hsh['T'].should == @hsh[:T]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '#background' do
|
161
|
+
before :each do
|
162
|
+
@pm = PM.new
|
163
|
+
@pm.matrix = [[1,2,3,4],[1,4,5,6.5]]
|
164
|
+
end
|
165
|
+
context 'when none arguments passed' do
|
166
|
+
context 'when pm just created' do
|
167
|
+
it 'should be [1,1,1,1]' do
|
168
|
+
@pm.background.should == [1,1,1,1]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
it 'should return background' do
|
172
|
+
@pm.instance_eval { @background = [0.2, 0.3, 0.3, 0.2] }
|
173
|
+
@pm.background.should == [0.2, 0.3, 0.3, 0.2]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
context 'when one argument passed' do
|
177
|
+
it 'should set background' do
|
178
|
+
@pm.background([0.2,0.3,0.3,0.2])
|
179
|
+
@pm.background.should == [0.2, 0.3, 0.3, 0.2]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
context 'when more than one argument passed' do
|
183
|
+
it 'should raise an ArgumentError' do
|
184
|
+
expect { @pm.background(:first, :second, :third) }.to raise_error ArgumentError
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '#reverse_complement!' do
|
190
|
+
before :each do
|
191
|
+
@pm = PM.new
|
192
|
+
@pm.matrix = [[1, 2, 3, 4], [1, 4, 5, 6.5]]
|
193
|
+
end
|
194
|
+
it 'should return pm object itself' do
|
195
|
+
@pm.reverse_complement!.should be_equal(@pm)
|
196
|
+
end
|
197
|
+
it 'should reverse matrix rows and columns' do
|
198
|
+
@pm.reverse_complement!
|
199
|
+
@pm.matrix.should == [[6.5, 5, 4, 1], [4, 3, 2, 1]]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#left_augment!' do
|
204
|
+
before :each do
|
205
|
+
@pm = PM.new
|
206
|
+
@pm.matrix = [[1, 2, 3, 4], [1, 4, 5, 6.5]]
|
207
|
+
end
|
208
|
+
it 'should return pm object itself' do
|
209
|
+
@pm.left_augment!(2).should be_equal(@pm)
|
210
|
+
end
|
211
|
+
it 'should add number of zero columns from the left' do
|
212
|
+
@pm.left_augment!(2)
|
213
|
+
@pm.matrix.should == [[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [1, 2, 3, 4], [1, 4, 5, 6.5]]
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe '#right_augment!' do
|
218
|
+
before :each do
|
219
|
+
@pm = PM.new
|
220
|
+
@pm.matrix = [[1, 2, 3, 4], [1, 4, 5, 6.5]]
|
221
|
+
end
|
222
|
+
it 'should return pm object itself' do
|
223
|
+
@pm.right_augment!(2).should be_equal(@pm)
|
224
|
+
end
|
225
|
+
it 'should add number of zero columns from the right' do
|
226
|
+
@pm.right_augment!(2)
|
227
|
+
@pm.matrix.should == [[1, 2, 3, 4], [1, 4, 5, 6.5], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#shift_to_zero!' do
|
232
|
+
before :each do
|
233
|
+
@pm = PM.new
|
234
|
+
@pm.matrix = [[1, 2, 3, 4], [5, 6.5, 3, 4]]
|
235
|
+
end
|
236
|
+
it 'should return pm object itself' do
|
237
|
+
@pm.shift_to_zero!.should be_equal(@pm)
|
238
|
+
end
|
239
|
+
it 'should make shift each column' do
|
240
|
+
@pm.shift_to_zero!
|
241
|
+
@pm.matrix.should == [[0, 1, 2, 3], [2, 3.5, 0, 1]]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe '#discrete!' do
|
246
|
+
before :each do
|
247
|
+
@pm = PM.new
|
248
|
+
@pm.matrix = [[1.3, 2.0, 3.2, 4.9], [6.51, 6.5, 3.25, 4.633]]
|
249
|
+
end
|
250
|
+
it 'should return pm object itself' do
|
251
|
+
@pm.discrete!(10).should be_equal(@pm)
|
252
|
+
end
|
253
|
+
context 'rate is 1' do
|
254
|
+
it 'should discrete each element of matrix' do
|
255
|
+
@pm.discrete!(1)
|
256
|
+
@pm.matrix.should == [[2, 2, 4, 5], [7, 7, 4, 5]]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
it 'should discrete each element of matrix multiplied by rate' do
|
260
|
+
@pm.discrete!(10)
|
261
|
+
@pm.matrix.should == [[13, 20, 32, 49], [66, 65, 33, 47]]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe '#background_sum' do
|
266
|
+
before :each do
|
267
|
+
@pm = PM.new
|
268
|
+
@pm.matrix = [[1.3, 2.0, 3.2, 4.9], [5.0, 6.5, 3.2, 4.6]]
|
269
|
+
end
|
270
|
+
context 'when background is [1,1,1,1]' do
|
271
|
+
it 'should be 4' do
|
272
|
+
@pm.background_sum.should == 4
|
273
|
+
end
|
274
|
+
end
|
275
|
+
it 'should be sum of background' do
|
276
|
+
@pm.background( [0.2, 0.3, 0.3, 0.2] )
|
277
|
+
@pm.background_sum.should == 1.0
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe '#vocabulary_volume' do
|
282
|
+
before :each do
|
283
|
+
@pm_2_positions = PM.new
|
284
|
+
@pm_2_positions.matrix = [[1.3, 2.0, 3.2, 4.9], [5.0, 6.5, 3.2, 4.6]]
|
285
|
+
@pm_3_positions = PM.new
|
286
|
+
@pm_3_positions.matrix = [[1.3, 2.0, 3.2, 4.9], [5.0, 6.5, 3.2, 4.6], [1, 2, 3, 4]]
|
287
|
+
end
|
288
|
+
context 'when background is [1,1,1,1]' do
|
289
|
+
it 'should be equal to number of words' do
|
290
|
+
@pm_2_positions.vocabulary_volume.should == 4**2
|
291
|
+
@pm_3_positions.vocabulary_volume.should == 4**3
|
292
|
+
end
|
293
|
+
end
|
294
|
+
context 'when background is normalized probabilities' do
|
295
|
+
it 'should be 1.0' do
|
296
|
+
@pm_2_positions.background( [0.2, 0.3, 0.3, 0.2] )
|
297
|
+
@pm_2_positions.background_sum.should == 1.0
|
298
|
+
|
299
|
+
@pm_3_positions.background( [0.2, 0.3, 0.3, 0.2] )
|
300
|
+
@pm_3_positions.background_sum.should == 1.0
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
describe '#best_score' do
|
306
|
+
it 'should be equal to best score' do
|
307
|
+
@pm = PM.new
|
308
|
+
@pm.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
309
|
+
@pm.best_score.should == 4.9 + 7.13 + (-1.0)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
describe '#worst_score' do
|
313
|
+
it 'should be equal to worst score' do
|
314
|
+
@pm = PM.new
|
315
|
+
@pm.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
316
|
+
@pm.worst_score.should == 1.3 + 3.25 + (-1.5)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
describe '#best_suffix' do
|
321
|
+
it 'should be an array of best suffices from start of string and to empty suffix inclusive' do
|
322
|
+
@pm = PM.new
|
323
|
+
@pm.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
324
|
+
@pm.best_suffix.should == [(4.9 + 7.13 - 1.0), (7.13 - 1.0), (-1.0), (0.0) ]
|
325
|
+
end
|
326
|
+
end
|
327
|
+
describe '#worst_suffix' do
|
328
|
+
it 'should be an array of worst suffices from start of string and to empty suffix inclusive' do
|
329
|
+
@pm = PM.new
|
330
|
+
@pm.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
331
|
+
@pm.worst_suffix.should == [(1.3 + 3.25 - 1.5), (3.25 - 1.5), (- 1.5), (0.0) ]
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
[:shift_to_zero, :reverse_complement].each do |meth|
|
336
|
+
describe "nonbang method #{meth}" do
|
337
|
+
before :each do
|
338
|
+
@pm = PM.new
|
339
|
+
@pm.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
340
|
+
@pm_2 = PM.new
|
341
|
+
@pm_2.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
342
|
+
end
|
343
|
+
it 'should return copy of object not object itself' do
|
344
|
+
@pm.send(meth).should_not be_equal @pm
|
345
|
+
end
|
346
|
+
it 'should == to bang-method' do
|
347
|
+
@pm.send(meth).to_s.should == @pm_2.send("#{meth}!").to_s
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
[:discrete , :left_augment, :right_augment].each do |meth|
|
353
|
+
describe "nonbang method #{meth}" do
|
354
|
+
before :each do
|
355
|
+
@pm = PM.new
|
356
|
+
@pm.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
357
|
+
@pm_2 = PM.new
|
358
|
+
@pm_2.matrix = [[1.3, 2.0, 4.9, 3.2], [7.13, 6.5, 3.25, 4.633], [-1.0, -1.0, -1.5, -1.0]]
|
359
|
+
end
|
360
|
+
it 'should return copy of object not object itself' do
|
361
|
+
@pm.send(meth, 2).should_not be_equal @pm
|
362
|
+
end
|
363
|
+
it 'should == to bang-method' do
|
364
|
+
@pm.send(meth, 2).to_s.should == @pm_2.send("#{meth}!", 2).to_s
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/data_models/pwm'
|
3
|
+
|
4
|
+
module Bioinform
|
5
|
+
describe PWM do
|
6
|
+
describe '#score_mean' do
|
7
|
+
it 'should be equal to a mean score of pwm' do
|
8
|
+
pwm = PWM.new
|
9
|
+
pwm.matrix = [[1,2,1,2],[4,6,8,6],[2,2,2,2]]
|
10
|
+
pwm.score_mean.should == 1.5 + 6 + 2
|
11
|
+
end
|
12
|
+
it 'should be equal to a mean score of pwm by measure induced from background probability mean' do
|
13
|
+
pwm = PWM.new.background([0.2, 0.3, 0.3, 0.2])
|
14
|
+
pwm.matrix = [[1,2,1,2],[4,6,8,6],[2,2,2,2]]
|
15
|
+
pwm.score_mean.should == ((0.2*1+0.3*2+0.3*1+0.2*2) + (0.2*4+0.3*6+0.3*8+0.2*6) + (0.2*2+0.3*2+0.3*2+0.2*2)) / (0.2+0.3+0.3+0.2)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#score_variance' do
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#gauss_estimation' do
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
module Bioinform
|
6
|
+
class PM
|
7
|
+
class Parser
|
8
|
+
module Helpers
|
9
|
+
def parser_stub(class_name, can_parse, result)
|
10
|
+
klass = Class.new(PM::Parser) do
|
11
|
+
define_method :can_parse? do can_parse end
|
12
|
+
define_method :parse do result end
|
13
|
+
end
|
14
|
+
#class_levels = class_name.to_s.split('::')
|
15
|
+
#class_levels[0..-2].inject(Object){|klass, level| klass.const_get level}.const_set(class_name, class_levels.last)
|
16
|
+
Bioinform.const_set(class_name.to_s.split('::').last, klass)
|
17
|
+
end
|
18
|
+
def parser_subclasses_cleanup
|
19
|
+
PM::Parser.subclasses.each do |klass|
|
20
|
+
#class_levels = klass.to_s.split('::')
|
21
|
+
#class_levels[0..-2].inject(Object){|klass, level| klass.const_get level}.const_set(class_name, class_levels.last)
|
22
|
+
|
23
|
+
Bioinform.send :remove_const, klass.name.split('::').last
|
24
|
+
end
|
25
|
+
PM::Parser.subclasses.clear
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/support/callable_symbol'
|
3
|
+
|
4
|
+
# TODO: organize and write more correct descriptions
|
5
|
+
describe Symbol do
|
6
|
+
describe '#call' do
|
7
|
+
context 'when symbol curries a block' do
|
8
|
+
it 'should pass a block to a corresponding proc' do
|
9
|
+
:map.(&:to_s).to_proc.call([1,2,3]).should == ['1','2','3']
|
10
|
+
[[1,2,3],[4,5,6]].map(&:map.(&:to_s)).should == [['1','2','3'],['4','5','6']]
|
11
|
+
[[1,2,3],[4,5,6]].map(&:map.(&:to_s.(2))).should == [['1','10','11'],['100','101','110']]
|
12
|
+
['abc','cdef','xy','z','wwww'].select(&:size.() == 4).should == ['cdef', 'wwww']
|
13
|
+
|
14
|
+
[%w{1 2 3 4 5},%w{6 7 8 9 10}].map(&:join.().length).should == [5,6] # method chaining
|
15
|
+
['abc','aaA','AaA','z'].count(&:upcase.().succ == 'AAB').should == 2 # method chaining with ==
|
16
|
+
[[1,2,3]].map( &:map.(&:to_s.(2)).map(&:to_i) ).should == [[1,10,11]] # method chaining with block on initial symbol and on later symbols
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'returned object' do
|
21
|
+
|
22
|
+
it 'should have to_proc method' do
|
23
|
+
expect { :to_s.() }.to respond_to :to_proc
|
24
|
+
expect { :to_s.(2) }.to respond_to :to_proc
|
25
|
+
expect { :to_s.(2) == '110' }.to respond_to :to_proc
|
26
|
+
expect { :to_s.(2).postprocess('arg1','arg2') }.to respond_to :to_proc
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'corresponding proc' do
|
30
|
+
it 'should call method, corresponding to symbol, on first argument' do
|
31
|
+
stub_obj = double('obj')
|
32
|
+
stub_obj.should_receive(:to_s).exactly(:twice)
|
33
|
+
prc_1 = :to_s.(2).to_proc
|
34
|
+
prc_2 = :to_s.(2).to_proc # When used with &, to_proc can be omitted: it's implicitly casted on call (see other examples)
|
35
|
+
prc_1.call(stub_obj) # These forms are almost equivalent, but second is much more concise
|
36
|
+
stub_obj.tap(&prc_2)
|
37
|
+
end
|
38
|
+
context 'when multiple arguments of call specified' do
|
39
|
+
it 'should call using given arguments' do
|
40
|
+
stub_obj = double('obj')
|
41
|
+
stub_obj.should_receive(:gsub).with('before','after')
|
42
|
+
prc = :gsub.('before','after')
|
43
|
+
stub_obj.tap(&prc)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context 'when the only argument of call specified' do
|
47
|
+
it 'should call using given argument' do
|
48
|
+
stub_obj = double('obj')
|
49
|
+
stub_obj.should_receive(:to_s).with(2)
|
50
|
+
prc = :to_s.(2)
|
51
|
+
stub_obj.tap(&prc)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
context 'when no arguments given' do
|
55
|
+
it 'should call without any arguments' do
|
56
|
+
stub_obj = double('obj')
|
57
|
+
stub_obj.should_receive(:to_s).with()
|
58
|
+
prc = :to_s.()
|
59
|
+
stub_obj.tap(&prc)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/support/collect_hash'
|
3
|
+
|
4
|
+
describe Enumerable do
|
5
|
+
# %w{A C G T}.collect_hash{|k| [k*2, k*3] }
|
6
|
+
# # ==> {"AA" => "AAA", "CC" => "CCC", "GG" => "GGG", "TT" => "TTT"}
|
7
|
+
context '#collect_hash' do
|
8
|
+
it 'should take a block and create a hash from collected [k,v] pairs' do
|
9
|
+
%w{A C G T}.collect_hash{|k| [k*2, k*3] }.should == {"AA" => "AAA", "CC" => "CCC", "GG" => "GGG", "TT" => "TTT"}
|
10
|
+
end
|
11
|
+
it 'should create a hash from yielded [k,v] pairs if block not given' do
|
12
|
+
%w{A C G T}.each_with_index.collect_hash.should == {"A" => 0, "C" => 1, "G" => 2, "T" => 3}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/support/delete_many'
|
3
|
+
|
4
|
+
describe Array do
|
5
|
+
before :each do
|
6
|
+
@arr = %w{a b c d e f g h i j b b}
|
7
|
+
end
|
8
|
+
describe '#delete_at_many' do
|
9
|
+
it 'should delete elements at specified indices when indices in ascending order' do
|
10
|
+
@arr.delete_at_many(1,3,7)
|
11
|
+
@arr.should == %w{a c e f g i j b b}
|
12
|
+
end
|
13
|
+
it 'should delete elements at specified indices when indices in descending order' do
|
14
|
+
@arr.delete_at_many(7,3,1)
|
15
|
+
@arr.should == %w{a c e f g i j b b}
|
16
|
+
end
|
17
|
+
it 'should delete elements at specified indices when indices in arbitrary order' do
|
18
|
+
@arr.delete_at_many(3,1,7)
|
19
|
+
@arr.should == %w{a c e f g i j b b}
|
20
|
+
end
|
21
|
+
it 'should delete at each index once' do
|
22
|
+
@arr.delete_at_many(0,0,0,2,0)
|
23
|
+
@arr.should == %w{b d e f g h i j b b}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
describe '#delete_many' do
|
27
|
+
it 'should delete multiple elements with specified values' do
|
28
|
+
@arr.delete_many('b', 'd', 'h', 'b')
|
29
|
+
@arr.should == %w{a c e f g i j}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Hash do
|
35
|
+
before :each do
|
36
|
+
@arr = {A: 3, T: 6, G: 4, C: 5}
|
37
|
+
end
|
38
|
+
describe '#delete_many' do
|
39
|
+
it 'should delete specified keys' do
|
40
|
+
@arr.delete_many(:T, :C, :F, :T, :T)
|
41
|
+
@arr.should == {A: 3, G: 4}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/support/has_keys'
|
3
|
+
|
4
|
+
describe Hash do
|
5
|
+
describe '#has_all_keys?' do
|
6
|
+
it 'should be true if all given keys are at place' do
|
7
|
+
{a: 3, b: 6, c: 7, d: 13}.has_all_keys?(:a, :c).should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should be false if any given of keys is missing' do
|
11
|
+
{a: 3, b: 6, c: 7, d: 13}.has_all_keys?(:a, :x).should be_false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#has_any_key?' do
|
16
|
+
it 'should be true if any of given keys is at place' do
|
17
|
+
{a: 3, b: 6, c: 7, d: 13}.has_any_key?(:a, :x).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should be false if no one of given is missing' do
|
21
|
+
{a: 3, b: 6, c: 7, d: 13}.has_any_key?(:x, :y).should be_false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#has_none_key?' do
|
26
|
+
it 'should be true if all given keys are missing' do
|
27
|
+
{a: 3, b: 6, c: 7, d: 13}.has_none_key?(:x, :y).should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should be false if any of given keys is at place' do
|
31
|
+
{a: 3, b: 6, c: 7, d: 13}.has_none_key?(:a, :y).should be_false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#has_one_key?' do
|
36
|
+
it 'should be true if one of given keys is present' do
|
37
|
+
{a: 3, b: 6, c: 7, d: 13}.has_one_key?(:x, :a).should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should be false if many of given keys are present' do
|
41
|
+
{a: 3, b: 6, c: 7, d: 13}.has_one_key?(:a, :c).should be_false
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should be false if none of given keys is at place' do
|
45
|
+
{a: 3, b: 6, c: 7, d: 13}.has_one_key?(:x, :y).should be_false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/support/inverf'
|
3
|
+
|
4
|
+
describe 'Math#inverf' do
|
5
|
+
it 'should be erf(inverf(x)) == x' do
|
6
|
+
rng = (-0.9..0.9).step(0.1)
|
7
|
+
arr = rng.to_a
|
8
|
+
arr2 = rng.map{|x| Math.inverf(x)}.map{|x| Math.erf(x)}
|
9
|
+
delta = arr.each_index.map{|i| (arr[i] - arr2[i]).abs }
|
10
|
+
delta.each{|el| el.should <= 0.001}
|
11
|
+
end
|
12
|
+
it 'should be erf(inverf(x)) == x' do
|
13
|
+
rng = (-5..5).step(1)
|
14
|
+
arr = rng.to_a
|
15
|
+
arr2 = rng.map{|x| Math.erf(x)}.map{|x| Math.inverf(x)}
|
16
|
+
delta = arr.each_index.map{|i| (arr[i] - arr2[i]).abs }
|
17
|
+
delta.each{|el| el.should <= 0.01}
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bioinform/support/multiline_squish'
|
3
|
+
|
4
|
+
describe String do
|
5
|
+
describe '#multiline_squish' do
|
6
|
+
it 'should replace multiple spaces with one space'
|
7
|
+
it 'should replace tabs with a space'
|
8
|
+
it 'should replace \r\n with \n'
|
9
|
+
it 'should preserve rows pagination'
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
describe 'Array#partial_sums' do
|
2
|
+
it 'should return an array of the same size with partial sums of elements 0..ind inclusive with float elements' do
|
3
|
+
[2,3,4,5].partial_sums.should == [2, 5, 9, 14]
|
4
|
+
[2,3,4,5].partial_sums.last.should be_kind_of(Float)
|
5
|
+
end
|
6
|
+
it 'should start counting from argument when it\'s given' do
|
7
|
+
[2,3,4,5].partial_sums(100).should == [102,105,109,114]
|
8
|
+
end
|
9
|
+
end
|