macroape 4.0.2 → 4.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.
- checksums.yaml +4 -4
- data/.gitignore +17 -17
- data/Gemfile +4 -4
- data/LICENSE +22 -22
- data/README.md +70 -70
- data/Rakefile.rb +49 -49
- data/TODO.txt +46 -46
- data/benchmark/benchmark_helper.rb +4 -4
- data/benchmark/similarity_benchmark.rb +52 -52
- data/bin/align_motifs +4 -4
- data/bin/eval_alignment +4 -4
- data/bin/eval_similarity +4 -4
- data/bin/find_pvalue +4 -4
- data/bin/find_threshold +4 -4
- data/bin/preprocess_collection +4 -4
- data/bin/scan_collection +4 -4
- data/lib/macroape.rb +14 -11
- data/lib/macroape/aligned_pair_intersection.rb +61 -62
- data/lib/macroape/cli.rb +191 -188
- data/lib/macroape/cli/align_motifs.rb +120 -100
- data/lib/macroape/cli/eval_alignment.rb +157 -156
- data/lib/macroape/cli/eval_similarity.rb +138 -137
- data/lib/macroape/cli/find_pvalue.rb +93 -87
- data/lib/macroape/cli/find_threshold.rb +103 -96
- data/lib/macroape/cli/preprocess_collection.rb +169 -161
- data/lib/macroape/cli/scan_collection.rb +171 -163
- data/lib/macroape/collection.rb +29 -0
- data/lib/macroape/motif_with_thresholds.rb +18 -0
- data/lib/macroape/pwm_compare.rb +39 -44
- data/lib/macroape/pwm_compare_aligned.rb +139 -130
- data/lib/macroape/{counting.rb → pwm_counting.rb} +175 -121
- data/lib/macroape/support/inverf.rb +13 -0
- data/lib/macroape/support/partial_sums.rb +17 -0
- data/lib/macroape/version.rb +4 -4
- data/macroape.gemspec +19 -19
- data/spec/count_distribution_spec.rb +112 -109
- data/spec/inverf_spec.rb +23 -0
- data/spec/partial_sums_spec.rb +28 -0
- data/spec/spec_helper.rb +11 -11
- data/test/align_motifs_test.rb +42 -43
- data/test/data/AHR_si.pwm +10 -10
- data/test/data/KLF3_f1.pcm +16 -16
- data/test/data/KLF3_f1.pwm +16 -16
- data/test/data/KLF4_f2.pcm +11 -11
- data/test/data/KLF4_f2.pwm +11 -11
- data/test/data/KLF4_f2_scan_results_all.txt +2 -2
- data/test/data/KLF4_f2_scan_results_default_cutoff.txt +1 -1
- data/test/data/KLF4_f2_scan_results_precise_mode.txt +2 -2
- data/test/data/SP1_f1.pcm +12 -12
- data/test/data/SP1_f1.pwm +12 -12
- data/test/data/SP1_f1_revcomp.pcm +12 -12
- data/test/data/SP1_f1_revcomp.pwm +12 -12
- data/test/data/medium_motif.pwm +8 -8
- data/test/data/short_motif.pwm +7 -7
- data/test/data/test_collection.yaml +231 -214
- data/test/data/test_collection/GABPA_f1.pwm +14 -14
- data/test/data/test_collection/KLF4_f2.pwm +10 -10
- data/test/data/test_collection/SP1_f1.pwm +12 -12
- data/test/data/test_collection_pcm/GABPA_f1.pcm +14 -14
- data/test/data/test_collection_pcm/KLF4_f2.pcm +11 -11
- data/test/data/test_collection_pcm/SP1_f1.pcm +12 -12
- data/test/data/test_collection_single_file.txt +38 -38
- data/test/data/test_collection_single_file_pcm.txt +37 -37
- data/test/data/test_collection_weak.yaml +231 -214
- data/test/eval_alignment_test.rb +90 -111
- data/test/eval_similarity_test.rb +105 -123
- data/test/find_pvalue_test.rb +34 -39
- data/test/find_threshold_test.rb +87 -91
- data/test/preprocess_collection_test.rb +56 -65
- data/test/scan_collection_test.rb +42 -48
- data/test/test_helper.rb +159 -160
- metadata +14 -10
- data/test/data/collection_pcm_without_thresholds.yaml +0 -188
- 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
|
data/lib/macroape/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module Macroape
|
2
|
-
VERSION = "4.0
|
3
|
-
STANDALONE = false
|
4
|
-
end
|
1
|
+
module Macroape
|
2
|
+
VERSION = "4.1.0"
|
3
|
+
STANDALONE = false
|
4
|
+
end
|
data/macroape.gemspec
CHANGED
@@ -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.
|
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/
|
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
|
-
|
11
|
-
let :
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
distribution_second =
|
24
|
-
distribution_second.
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
distribution_second =
|
37
|
-
distribution_second.
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
distribution_second =
|
48
|
-
distribution_second.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
it 'should return probability to be >= than threshold
|
72
|
-
|
73
|
-
end
|
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
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
data/spec/inverf_spec.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
CHANGED
@@ -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
|
data/test/align_motifs_test.rb
CHANGED
@@ -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
|