macroape 4.0.2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|