macroape 4.0.2 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -17
  3. data/Gemfile +4 -4
  4. data/LICENSE +22 -22
  5. data/README.md +70 -70
  6. data/Rakefile.rb +49 -49
  7. data/TODO.txt +46 -46
  8. data/benchmark/benchmark_helper.rb +4 -4
  9. data/benchmark/similarity_benchmark.rb +52 -52
  10. data/bin/align_motifs +4 -4
  11. data/bin/eval_alignment +4 -4
  12. data/bin/eval_similarity +4 -4
  13. data/bin/find_pvalue +4 -4
  14. data/bin/find_threshold +4 -4
  15. data/bin/preprocess_collection +4 -4
  16. data/bin/scan_collection +4 -4
  17. data/lib/macroape.rb +14 -11
  18. data/lib/macroape/aligned_pair_intersection.rb +61 -62
  19. data/lib/macroape/cli.rb +191 -188
  20. data/lib/macroape/cli/align_motifs.rb +120 -100
  21. data/lib/macroape/cli/eval_alignment.rb +157 -156
  22. data/lib/macroape/cli/eval_similarity.rb +138 -137
  23. data/lib/macroape/cli/find_pvalue.rb +93 -87
  24. data/lib/macroape/cli/find_threshold.rb +103 -96
  25. data/lib/macroape/cli/preprocess_collection.rb +169 -161
  26. data/lib/macroape/cli/scan_collection.rb +171 -163
  27. data/lib/macroape/collection.rb +29 -0
  28. data/lib/macroape/motif_with_thresholds.rb +18 -0
  29. data/lib/macroape/pwm_compare.rb +39 -44
  30. data/lib/macroape/pwm_compare_aligned.rb +139 -130
  31. data/lib/macroape/{counting.rb → pwm_counting.rb} +175 -121
  32. data/lib/macroape/support/inverf.rb +13 -0
  33. data/lib/macroape/support/partial_sums.rb +17 -0
  34. data/lib/macroape/version.rb +4 -4
  35. data/macroape.gemspec +19 -19
  36. data/spec/count_distribution_spec.rb +112 -109
  37. data/spec/inverf_spec.rb +23 -0
  38. data/spec/partial_sums_spec.rb +28 -0
  39. data/spec/spec_helper.rb +11 -11
  40. data/test/align_motifs_test.rb +42 -43
  41. data/test/data/AHR_si.pwm +10 -10
  42. data/test/data/KLF3_f1.pcm +16 -16
  43. data/test/data/KLF3_f1.pwm +16 -16
  44. data/test/data/KLF4_f2.pcm +11 -11
  45. data/test/data/KLF4_f2.pwm +11 -11
  46. data/test/data/KLF4_f2_scan_results_all.txt +2 -2
  47. data/test/data/KLF4_f2_scan_results_default_cutoff.txt +1 -1
  48. data/test/data/KLF4_f2_scan_results_precise_mode.txt +2 -2
  49. data/test/data/SP1_f1.pcm +12 -12
  50. data/test/data/SP1_f1.pwm +12 -12
  51. data/test/data/SP1_f1_revcomp.pcm +12 -12
  52. data/test/data/SP1_f1_revcomp.pwm +12 -12
  53. data/test/data/medium_motif.pwm +8 -8
  54. data/test/data/short_motif.pwm +7 -7
  55. data/test/data/test_collection.yaml +231 -214
  56. data/test/data/test_collection/GABPA_f1.pwm +14 -14
  57. data/test/data/test_collection/KLF4_f2.pwm +10 -10
  58. data/test/data/test_collection/SP1_f1.pwm +12 -12
  59. data/test/data/test_collection_pcm/GABPA_f1.pcm +14 -14
  60. data/test/data/test_collection_pcm/KLF4_f2.pcm +11 -11
  61. data/test/data/test_collection_pcm/SP1_f1.pcm +12 -12
  62. data/test/data/test_collection_single_file.txt +38 -38
  63. data/test/data/test_collection_single_file_pcm.txt +37 -37
  64. data/test/data/test_collection_weak.yaml +231 -214
  65. data/test/eval_alignment_test.rb +90 -111
  66. data/test/eval_similarity_test.rb +105 -123
  67. data/test/find_pvalue_test.rb +34 -39
  68. data/test/find_threshold_test.rb +87 -91
  69. data/test/preprocess_collection_test.rb +56 -65
  70. data/test/scan_collection_test.rb +42 -48
  71. data/test/test_helper.rb +159 -160
  72. metadata +14 -10
  73. data/test/data/collection_pcm_without_thresholds.yaml +0 -188
  74. data/test/data/collection_without_thresholds.yaml +0 -188
@@ -0,0 +1,13 @@
1
+ module Math
2
+ def self.inverf(x)
3
+ sign = x < 0 ? -1 : 1
4
+ x = x.abs
5
+ a = 8 / (3*Math::PI) * (Math::PI-3) / (4-Math::PI)
6
+ part0 = ( 2/(Math::PI*a) + (Math.log(1-x*x)) / 2 )**2
7
+ part = -2 / (Math::PI * a) - Math.log(1-x*x)/2 + Math.sqrt(-1/a * Math.log(1-x*x) + part0)
8
+ sign * Math.sqrt(part)
9
+ end
10
+ def inverf(x)
11
+ Math.inverf(x)
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ class Array
2
+ def partial_sums(initial = 0.0)
3
+ sums = initial
4
+ map{|el| sums += el}
5
+ end
6
+ end
7
+
8
+ class Hash
9
+ # {1 => 5, 4 => 3, 3 => 2}.partial_sums == {1=>5, 3=>7, 4=>10}
10
+ def partial_sums(initial = 0.0)
11
+ sums = initial
12
+ sort.each_with_object({}){|(k,v), hsh|
13
+ sums += v
14
+ hsh[k] = sums
15
+ }
16
+ end
17
+ end
@@ -1,4 +1,4 @@
1
- module Macroape
2
- VERSION = "4.0.2"
3
- STANDALONE = false
4
- end
1
+ module Macroape
2
+ VERSION = "4.1.0"
3
+ STANDALONE = false
4
+ end
@@ -1,19 +1,19 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/macroape/version', __FILE__)
3
-
4
- Gem::Specification.new do |gem|
5
- gem.authors = ["Ilya Vorontsov"]
6
- gem.email = ["prijutme4ty@gmail.com"]
7
- gem.description = %q{Macroape is an abbreviation for MAtrix CompaRisOn by Approximate P-value Estimation. It's a bioinformatic tool for evaluating similarity measure and best alignment between a pair of Position Weight Matrices(PWM), finding thresholds by P-values and vice versa and even searching a collection of motifs for the most similar ones. Used approach and application described in manual at https://docs.google.com/document/pub?id=1_jsxhMNzMzy4d2d_byAd3n6Szg5gEcqG_Sf7w9tEqWw}
8
- gem.summary = %q{PWM comparison tool using MACROAPE approach}
9
- gem.homepage = "http://autosome.ru/macroape/"
10
-
11
- gem.files = `git ls-files`.split($/)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
- gem.name = "macroape"
15
- gem.require_paths = ["lib"]
16
- gem.version = Macroape::VERSION
17
-
18
- gem.add_dependency('bioinform', '~> 0.1.10')
19
- end
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/macroape/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ilya Vorontsov"]
6
+ gem.email = ["prijutme4ty@gmail.com"]
7
+ gem.description = %q{Macroape is an abbreviation for MAtrix CompaRisOn by Approximate P-value Estimation. It's a bioinformatic tool for evaluating similarity measure and best alignment between a pair of Position Weight Matrices(PWM), finding thresholds by P-values and vice versa and even searching a collection of motifs for the most similar ones. Used approach and application described in manual at https://docs.google.com/document/pub?id=1_jsxhMNzMzy4d2d_byAd3n6Szg5gEcqG_Sf7w9tEqWw}
8
+ gem.summary = %q{PWM comparison tool using MACROAPE approach}
9
+ gem.homepage = "http://autosome.ru/macroape/"
10
+
11
+ gem.files = `git ls-files`.split($/)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "macroape"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Macroape::VERSION
17
+
18
+ gem.add_dependency('bioinform', '~> 0.2.0')
19
+ end
@@ -1,109 +1,112 @@
1
- require_relative 'spec_helper'
2
- require_relative '../lib/macroape/counting'
3
-
4
- describe Bioinform::PWM do
5
- let :matrix_first do [[1,2,3,4],[10,20,30,40],[100,200,300,400]] end
6
- let :matrix_second do [[1,2,3,4],[2,3,4,5]] end
7
- let :pwm_first do Bioinform::PWM.new(matrix_first) end
8
- let :pwm_second do Bioinform::PWM.new(matrix_second) end
9
- let :background do [0.1,0.4,0.4,0.1] end
10
- let :pwm_first_on_background do pwm_first.tap{|pwm| pwm.set_parameters(background: background)} end
11
- let :pwm_second_on_background do pwm_second.tap{|pwm| pwm.set_parameters(background: background)} end
12
-
13
- context '#count_distribution_after_threshold' do
14
-
15
- it 'should return hash of score => count for all scores >= threshold' do
16
- distribution_first = pwm_first.count_distribution_after_threshold(0)
17
- distribution_first.keys.should == Array.product(*matrix_first).map{|score_row| score_row.inject(&:+)}
18
- distribution_first.values.uniq.should == [1]
19
-
20
- distribution_second = pwm_second.count_distribution_after_threshold(0)
21
- distribution_second.should == { 3=>1, 4=>2, 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 }
22
-
23
- distribution_second = pwm_second.count_distribution_after_threshold(5)
24
- distribution_second.should == { 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 }
25
- end
26
-
27
- it 'for PWMs on different background it should contain the same scores (keys of hash)' do
28
- pwm_first.count_distribution_after_threshold(0).keys.sort.should == pwm_first_on_background.count_distribution_after_threshold(0).keys.sort
29
- pwm_first.count_distribution_after_threshold(13).keys.sort.should == pwm_first_on_background.count_distribution_after_threshold(13).keys.sort
30
- end
31
-
32
- it 'should return hash of score => count for all scores >= threshold when calculated on background' do
33
- distribution_second = pwm_second_on_background.count_distribution_after_threshold(0)
34
- distribution_second.should have_nearly_the_same_values({ 3=>0.01, 4=>0.08, 5=>0.24, 6=>0.34, 7=>0.24, 8=>0.08, 9=>0.01 }, 1e-7 )
35
-
36
- distribution_second = pwm_second_on_background.count_distribution_after_threshold(5)
37
- distribution_second.should have_nearly_the_same_values({ 5=>0.24, 6=>0.34, 7=>0.24, 8=>0.08, 9=>0.01 }, 1e-7 )
38
- end
39
-
40
- it 'should use existing precalculated hash @count_distribution if it exists' do
41
- pwm = pwm_second;
42
- pwm.instance_variable_set :@count_distribution, { 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
43
-
44
- distribution_second = pwm.count_distribution_after_threshold(0)
45
- distribution_second.should == { 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
46
-
47
- distribution_second = pwm.count_distribution_after_threshold(5)
48
- distribution_second.should == { 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
49
- end
50
- end
51
-
52
- context '#count_distribution' do
53
- it 'should return hash of score => count for all available scores' do
54
- pwm_second.count_distribution.should == { 3=>1, 4=>2, 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 }
55
- end
56
-
57
- it 'should cache calculation in @count_distribution' do
58
- pwm = pwm_second;
59
- pwm.instance_variable_set :@count_distribution, { 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
60
- pwm.count_distribution.should == { 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
61
-
62
- pwm.instance_variable_set :@count_distribution, nil
63
- pwm.count_distribution.should == { 3=>1, 4=>2, 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 }
64
- end
65
- end
66
-
67
- context '#pvalue_by_threshold' do
68
- it 'should return probability to be >= than threshold' do
69
- pwm_second.pvalue_by_threshold(7).should be_within(1e-7).of(6.0/16)
70
- end
71
- it 'should return probability to be >= than threshold when calculated on background' do
72
- pwm_second_on_background.pvalue_by_threshold(7).should be_within(1e-7).of(0.33)
73
- end
74
- end
75
- context '#threshold' do
76
- it 'should return threshold such that according pvalue doesn\'t exceed requested value' do
77
- requested_pvalue = 6.0/16
78
- threshold = pwm_second.threshold(requested_pvalue)
79
- pwm_second.pvalue_by_threshold(threshold).should <= requested_pvalue
80
- end
81
- it 'should return threshold such that according pvalue doesn\'t exceed requested value when calculated on background' do
82
- requested_pvalue = 0.33
83
- threshold = pwm_second_on_background.threshold(requested_pvalue)
84
- pwm_second_on_background.pvalue_by_threshold(threshold).should <= requested_pvalue
85
- end
86
- it 'should return threshold such that according pvalue doesn\'t exceed requested value when actual pvalue isn\'t exact equal to requested' do
87
- requested_pvalue = 0.335
88
- threshold = pwm_second_on_background.threshold(requested_pvalue)
89
- pwm_second_on_background.pvalue_by_threshold(threshold).should <= requested_pvalue
90
- end
91
- end
92
- context '#weak_threshold' do
93
- it 'should return threshold such that according pvalue exceed requested value' do
94
- requested_pvalue = 6.0/16
95
- threshold = pwm_second.weak_threshold(requested_pvalue)
96
- pwm_second.pvalue_by_threshold(threshold).should >= requested_pvalue
97
- end
98
- it 'should return threshold such that according pvalue exceed requested value when calculated on background' do
99
- requested_pvalue = 0.33
100
- threshold = pwm_second_on_background.weak_threshold(requested_pvalue)
101
- pwm_second_on_background.pvalue_by_threshold(threshold).should >= requested_pvalue
102
- end
103
- it 'should return threshold such that according pvalue exceed requested value when actual pvalue isn\'t exact equal to requested' do
104
- requested_pvalue = 0.335
105
- threshold = pwm_second_on_background.weak_threshold(requested_pvalue)
106
- pwm_second_on_background.pvalue_by_threshold(threshold).should >= requested_pvalue
107
- end
108
- end
109
- end
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/macroape/pwm_counting'
3
+
4
+ describe Bioinform::MotifModel::PWM do
5
+ let :matrix_first do [[1,2,3,4],[10,20,30,40],[100,200,300,400]] end
6
+ let :matrix_second do [[1,2,3,4],[2,3,4,5]] end
7
+ let :pwm_first do Bioinform::MotifModel::PWM.new(matrix_first) end
8
+ let :pwm_second do Bioinform::MotifModel::PWM.new(matrix_second) end
9
+ let :background do Bioinform::Frequencies.new([0.1,0.4,0.4,0.1]) end
10
+
11
+ let :counting_first do Macroape::PWMCounting.new(pwm_first) end
12
+ let :counting_second do Macroape::PWMCounting.new(pwm_second) end
13
+ let :counting_first_on_background do Macroape::PWMCounting.new(pwm_first, background: background) end
14
+ let :counting_second_on_background do Macroape::PWMCounting.new(pwm_second, background: background) end
15
+
16
+ context '#count_distribution_after_threshold' do
17
+
18
+ it 'should return hash of score => count for all scores >= threshold' do
19
+ distribution_first = counting_first.count_distribution_after_threshold(0)
20
+ expect(distribution_first.keys).to eq (matrix_first.first).product(*matrix_first[1..-1]).map{|score_row| score_row.inject(&:+)}
21
+ expect(distribution_first.values.uniq).to eq [1]
22
+
23
+ distribution_second = counting_second.count_distribution_after_threshold(0)
24
+ expect(distribution_second).to eq({ 3=>1, 4=>2, 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 })
25
+
26
+ distribution_second = counting_second.count_distribution_after_threshold(5)
27
+ expect(distribution_second).to eq({ 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 })
28
+ end
29
+
30
+ it 'for PWMs on different background it should contain the same scores (keys of hash)' do
31
+ expect(counting_first.count_distribution_after_threshold(0).keys.sort).to eq counting_first_on_background.count_distribution_after_threshold(0).keys.sort
32
+ expect(counting_first.count_distribution_after_threshold(13).keys.sort).to eq counting_first_on_background.count_distribution_after_threshold(13).keys.sort
33
+ end
34
+
35
+ it 'should return hash of score => count for all scores >= threshold when calculated on background' do
36
+ distribution_second = counting_second_on_background.count_distribution_after_threshold(0)
37
+ expect(distribution_second).to have_nearly_the_same_values({ 3=>0.01, 4=>0.08, 5=>0.24, 6=>0.34, 7=>0.24, 8=>0.08, 9=>0.01 }, 1e-7 )
38
+
39
+ distribution_second = counting_second_on_background.count_distribution_after_threshold(5)
40
+ expect(distribution_second).to have_nearly_the_same_values({ 5=>0.24, 6=>0.34, 7=>0.24, 8=>0.08, 9=>0.01 }, 1e-7 )
41
+ end
42
+
43
+ it 'should use existing precalculated hash @count_distribution if it exists' do
44
+ counting = counting_second;
45
+ counting.instance_variable_set :@count_distribution, { 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
46
+
47
+ distribution_second = counting.count_distribution_after_threshold(0)
48
+ expect(distribution_second).to eq({ 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 })
49
+
50
+ distribution_second = counting.count_distribution_after_threshold(5)
51
+ expect(distribution_second).to eq({ 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 })
52
+ end
53
+ end
54
+
55
+ context '#count_distribution' do
56
+ it 'should return hash of score => count for all available scores' do
57
+ expect(counting_second.count_distribution).to eq({ 3=>1, 4=>2, 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 })
58
+ end
59
+
60
+ it 'should cache calculation in @count_distribution' do
61
+ counting = counting_second;
62
+ counting.instance_variable_set :@count_distribution, { 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 }
63
+ expect(counting.count_distribution).to eq({ 3=>10, 4=>20, 5=>30, 6=>40, 7=>30, 8=>20, 9=>10 })
64
+
65
+ counting.instance_variable_set :@count_distribution, nil
66
+ expect(counting.count_distribution).to eq({ 3=>1, 4=>2, 5=>3, 6=>4, 7=>3, 8=>2, 9=>1 })
67
+ end
68
+ end
69
+
70
+ context '#pvalue_by_threshold' do
71
+ it 'should return probability to be >= than threshold' do
72
+ expect(counting_second.pvalue_by_threshold(7)).to be_within(1e-7).of(6.0/16)
73
+ end
74
+ it 'should return probability to be >= than threshold when calculated on background' do
75
+ expect(counting_second_on_background.pvalue_by_threshold(7)).to be_within(1e-7).of(0.33)
76
+ end
77
+ end
78
+ context '#threshold' do
79
+ it 'should return threshold such that according pvalue doesn\'t exceed requested value' do
80
+ requested_pvalue = 6.0/16
81
+ threshold = counting_second.threshold(requested_pvalue)
82
+ expect(counting_second.pvalue_by_threshold(threshold)).to be <= requested_pvalue
83
+ end
84
+ it 'should return threshold such that according pvalue doesn\'t exceed requested value when calculated on background' do
85
+ requested_pvalue = 0.33
86
+ threshold = counting_second_on_background.threshold(requested_pvalue)
87
+ expect(counting_second_on_background.pvalue_by_threshold(threshold)).to be <= requested_pvalue
88
+ end
89
+ it 'should return threshold such that according pvalue doesn\'t exceed requested value when actual pvalue isn\'t exact equal to requested' do
90
+ requested_pvalue = 0.335
91
+ threshold = counting_second_on_background.threshold(requested_pvalue)
92
+ expect(counting_second_on_background.pvalue_by_threshold(threshold)).to be <= requested_pvalue
93
+ end
94
+ end
95
+ context '#weak_threshold' do
96
+ it 'should return threshold such that according pvalue exceed requested value' do
97
+ requested_pvalue = 6.0/16
98
+ threshold = counting_second.weak_threshold(requested_pvalue)
99
+ expect(counting_second.pvalue_by_threshold(threshold)).to be >= requested_pvalue
100
+ end
101
+ it 'should return threshold such that according pvalue exceed requested value when calculated on background' do
102
+ requested_pvalue = 0.33
103
+ threshold = counting_second_on_background.weak_threshold(requested_pvalue)
104
+ expect(counting_second_on_background.pvalue_by_threshold(threshold)).to be >= requested_pvalue
105
+ end
106
+ it 'should return threshold such that according pvalue exceed requested value when actual pvalue isn\'t exact equal to requested' do
107
+ requested_pvalue = 0.335
108
+ threshold = counting_second_on_background.weak_threshold(requested_pvalue)
109
+ expect(counting_second_on_background.pvalue_by_threshold(threshold)).to be >= requested_pvalue
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'spec_helper'
2
+ require 'macroape/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|
11
+ expect(el).to be <= 0.001
12
+ }
13
+ end
14
+ it 'should be erf(inverf(x)) == x' do
15
+ rng = (-5..5).step(1)
16
+ arr = rng.to_a
17
+ arr2 = rng.map{|x| Math.erf(x)}.map{|x| Math.inverf(x)}
18
+ delta = arr.each_index.map{|i| (arr[i] - arr2[i]).abs }
19
+ delta.each{|el|
20
+ expect(el).to be <= 0.01
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'spec_helper'
2
+ require 'macroape/support/partial_sums'
3
+
4
+ describe 'Array#partial_sums' do
5
+ context 'when no initial value given' do
6
+ it 'should return an array of the same size with partial sums of elements 0..ind inclusive with float elements' do
7
+ expect([2,3,4,5].partial_sums).to eq [2, 5, 9, 14]
8
+ expect([2,3,4,5].partial_sums.last).to be_kind_of(Float)
9
+ end
10
+ end
11
+ it 'should start counting from argument when it\'s given. Type of values depends on type of initial value' do
12
+ expect([2,3,4,5].partial_sums(100)).to eq [102,105,109,114]
13
+ expect([2,3,4,5].partial_sums(100).last).to be_kind_of(Integer)
14
+ end
15
+ end
16
+
17
+ describe 'Hash#partial_sums' do
18
+ context 'when no initial value given' do
19
+ it 'should return a hash with float values of the same size with partial sums of elements that has keys <= than argument' do
20
+ expect({1 => 5, 4 => 3, 3 => 2}.partial_sums).to eq({1=>5, 3=>7, 4=>10})
21
+ expect({1 => 5, 4 => 3, 3 => 2}.partial_sums.values.last).to be_kind_of(Float)
22
+ end
23
+ end
24
+ it 'should start counting from argument when it\'s given. Type of values depends on type of initial value' do
25
+ expect({1 => 5, 4 => 3, 3 => 2}.partial_sums(100)).to eq({1=>105, 3=>107, 4=>110})
26
+ expect({1 => 5, 4 => 3, 3 => 2}.partial_sums(100).values.last).to be_kind_of(Integer)
27
+ end
28
+ end
@@ -1,11 +1,11 @@
1
- $bioinform_folder = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bioinform', 'lib'))
2
- $LOAD_PATH.unshift $bioinform_folder
3
-
4
- require 'rspec'
5
-
6
- # comparing hashes with float values
7
- RSpec::Matchers.define :have_nearly_the_same_values do |expected, vicinity|
8
- match do |actual|
9
- expected.all?{|key, _| actual.has_key?(key)} && actual.all?{|key, _| expected.has_key?(key)} && expected.all?{|key, value| (actual[key] - value).abs <= vicinity }
10
- end
11
- end
1
+ $bioinform_folder = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bioinform', 'lib'))
2
+ $LOAD_PATH.unshift $bioinform_folder
3
+
4
+ require 'rspec'
5
+
6
+ # comparing hashes with float values
7
+ RSpec::Matchers.define :have_nearly_the_same_values do |expected, vicinity|
8
+ match do |actual|
9
+ expected.all?{|key, _| actual.has_key?(key)} && actual.all?{|key, _| expected.has_key?(key)} && expected.all?{|key, value| (actual[key] - value).abs <= vicinity }
10
+ end
11
+ end
@@ -1,43 +1,42 @@
1
- require_relative 'test_helper'
2
-
3
- class TestAlignmotifs < Test::Unit::TestCase
4
- def setup
5
- @start_dir = Dir.pwd
6
- Dir.chdir File.join(File.dirname(__FILE__), 'data')
7
- end
8
- def teardown
9
- Dir.chdir(@start_dir)
10
- end
11
-
12
- def test_align_motifs
13
- assert_equal [%w[KLF4_f2.pwm 0 direct],
14
- %w[KLF3_f1.pwm -4 direct],
15
- %w[SP1_f1_revcomp.pwm -1 revcomp]],
16
- Helpers.align_motifs_output('KLF4_f2.pwm KLF3_f1.pwm SP1_f1_revcomp.pwm')
17
- end
18
- def test_align_pcm_motifs
19
- assert_equal [%w[KLF4_f2.pcm 0 direct],
20
- %w[KLF3_f1.pcm -4 direct],
21
- %w[SP1_f1_revcomp.pcm -1 revcomp]],
22
- Helpers.align_motifs_output('--pcm KLF4_f2.pcm KLF3_f1.pcm SP1_f1_revcomp.pcm')
23
- end
24
- def test_names_from_stdin_leader_specified
25
- assert_equal [%w[KLF4_f2.pwm 0 direct],
26
- %w[KLF3_f1.pwm -4 direct],
27
- %w[SP1_f1_revcomp.pwm -1 revcomp]],
28
- Helpers.provide_stdin('KLF3_f1.pwm SP1_f1_revcomp.pwm'){ Helpers.align_motifs_output('KLF4_f2.pwm') }
29
- end
30
- def test_names_from_stdin_leader_not_specified
31
- assert_equal [%w[KLF4_f2.pwm 0 direct],
32
- %w[KLF3_f1.pwm -4 direct],
33
- %w[SP1_f1_revcomp.pwm -1 revcomp]],
34
- Helpers.provide_stdin('KLF4_f2.pwm KLF3_f1.pwm SP1_f1_revcomp.pwm'){ Helpers.align_motifs_output('') }
35
- end
36
- def test_names_from_stdin_duplicate_leader
37
- assert_equal [%w[KLF4_f2.pwm 0 direct],
38
- %w[KLF3_f1.pwm -4 direct],
39
- %w[SP1_f1_revcomp.pwm -1 revcomp]],
40
- Helpers.provide_stdin('KLF3_f1.pwm KLF4_f2.pwm SP1_f1_revcomp.pwm'){ Helpers.align_motifs_output('KLF4_f2.pwm') }
41
- end
42
-
43
- end
1
+ require_relative 'test_helper'
2
+
3
+ class TestAlignmotifs < Test::Unit::TestCase
4
+ def setup
5
+ @start_dir = Dir.pwd
6
+ Dir.chdir File.join(File.dirname(__FILE__), 'data')
7
+ end
8
+ def teardown
9
+ Dir.chdir(@start_dir)
10
+ end
11
+
12
+ def test_align_motifs
13
+ assert_equal [%w[KLF4_f2.pwm 0 direct],
14
+ %w[KLF3_f1.pwm -4 direct],
15
+ %w[SP1_f1_revcomp.pwm -1 revcomp]],
16
+ Helpers.align_motifs_output('KLF4_f2.pwm KLF3_f1.pwm SP1_f1_revcomp.pwm')
17
+ end
18
+ def test_align_pcm_motifs
19
+ assert_equal [%w[KLF4_f2.pcm 0 direct],
20
+ %w[KLF3_f1.pcm -4 direct],
21
+ %w[SP1_f1_revcomp.pcm -1 revcomp]],
22
+ Helpers.align_motifs_output('--pcm KLF4_f2.pcm KLF3_f1.pcm SP1_f1_revcomp.pcm')
23
+ end
24
+ def test_names_from_stdin_leader_specified
25
+ assert_equal [%w[KLF4_f2.pwm 0 direct],
26
+ %w[KLF3_f1.pwm -4 direct],
27
+ %w[SP1_f1_revcomp.pwm -1 revcomp]],
28
+ Helpers.provide_stdin('KLF3_f1.pwm SP1_f1_revcomp.pwm'){ Helpers.align_motifs_output('KLF4_f2.pwm') }
29
+ end
30
+ def test_names_from_stdin_leader_not_specified
31
+ assert_equal [%w[KLF4_f2.pwm 0 direct],
32
+ %w[KLF3_f1.pwm -4 direct],
33
+ %w[SP1_f1_revcomp.pwm -1 revcomp]],
34
+ Helpers.provide_stdin('KLF4_f2.pwm KLF3_f1.pwm SP1_f1_revcomp.pwm'){ Helpers.align_motifs_output('') }
35
+ end
36
+ def test_names_from_stdin_duplicate_leader
37
+ assert_equal [%w[KLF4_f2.pwm 0 direct],
38
+ %w[KLF3_f1.pwm -4 direct],
39
+ %w[SP1_f1_revcomp.pwm -1 revcomp]],
40
+ Helpers.provide_stdin('KLF3_f1.pwm KLF4_f2.pwm SP1_f1_revcomp.pwm'){ Helpers.align_motifs_output('KLF4_f2.pwm') }
41
+ end
42
+ end