bioinform 0.0.1 → 0.1.0
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.
- 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
|