bio-genomic-interval 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/.document +5 -0
- data/.rspec +2 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +79 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/bio-genomic-interval.gemspec +67 -0
- data/lib/bio-genomic-interval.rb +158 -0
- data/spec/bio-genomic-interval_spec.rb +357 -0
- data/spec/spec_helper.rb +12 -0
- metadata +157 -0
data/.document
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.3.0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
gem "bio", ">= 1.4.1"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
bio (1.4.1)
|
5
|
+
diff-lcs (1.1.2)
|
6
|
+
git (1.2.5)
|
7
|
+
jeweler (1.5.2)
|
8
|
+
bundler (~> 1.0.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rake
|
11
|
+
rake (0.8.7)
|
12
|
+
rcov (0.9.9)
|
13
|
+
rspec (2.3.0)
|
14
|
+
rspec-core (~> 2.3.0)
|
15
|
+
rspec-expectations (~> 2.3.0)
|
16
|
+
rspec-mocks (~> 2.3.0)
|
17
|
+
rspec-core (2.3.1)
|
18
|
+
rspec-expectations (2.3.0)
|
19
|
+
diff-lcs (~> 1.1.2)
|
20
|
+
rspec-mocks (2.3.0)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
bio (>= 1.4.1)
|
27
|
+
bundler (~> 1.0.0)
|
28
|
+
jeweler (~> 1.5.2)
|
29
|
+
rcov
|
30
|
+
rspec (~> 2.3.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Hiroyuki Mishima
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
= bio-genomic-interval
|
2
|
+
|
3
|
+
Author:: MISHIMA, Hiroyuki (hmishima AT nagasaki-u.ac.jp, missy AT be.to)
|
4
|
+
Version:: 0.1.0
|
5
|
+
Copyright:: Copyright (c) MISHIMA, Hiroyuki, 2011
|
6
|
+
License:: the MIT/X11 license
|
7
|
+
|
8
|
+
A BioRuby plugin: handling genomic intervals,such as "chr1:123-456",
|
9
|
+
and overlaps between two intervals.
|
10
|
+
|
11
|
+
= Usage
|
12
|
+
== Generation of interval objects
|
13
|
+
a interval object be generated by like the following:
|
14
|
+
a = Bio::GenomicInterval.new("chr1", 123, 456)
|
15
|
+
a.to_s # => "chr1:123-456"
|
16
|
+
b = Bio::GenomicInterval.parse("chr1:123-456")
|
17
|
+
b.to_s # => "chr1:123-456"
|
18
|
+
c = Bio::GenomicInetrval.zero_based("chr1", 122, 456)
|
19
|
+
c.to_s # => "chr1:123-456"
|
20
|
+
c.zero_start # => 122
|
21
|
+
|
22
|
+
Last one is generated from a "Zero-based half-closed[start, end)" interval
|
23
|
+
, which used in UCSC Genobe Browser's BED format, instead of usual
|
24
|
+
"One-based full-closed [start, end]" intervals.
|
25
|
+
|
26
|
+
== Comparison
|
27
|
+
ref = Bio::GenomicInterval.parse("chr1:123-456")
|
28
|
+
cmp = Bio::GenomicInterval.parse("chr1:234-567")
|
29
|
+
ref.compare(cmp) # => :right_overlapped
|
30
|
+
|
31
|
+
ref.adjacent # => 20
|
32
|
+
near = Bio::GenomicInterval.parse("chr1:458-567")
|
33
|
+
ref.compare(cmp) # => :right_adjacent
|
34
|
+
|
35
|
+
ref.adjacent = 1
|
36
|
+
ref.compare(cmp) # => :right_off
|
37
|
+
|
38
|
+
== Overlap metrics
|
39
|
+
* When a overlap exist, return a positive integers (>1) for the overlap length.
|
40
|
+
* When a overlap does not exist, return a zero or a negative (<= 0) for the space size between the intervals.
|
41
|
+
|
42
|
+
ref = Bio::GenomicInterval.parse("chr1:10-20")
|
43
|
+
cmp = Bio::GenomicInterval.parse("chr1:15-25")
|
44
|
+
ref.overlap(cmp) # => 6
|
45
|
+
cmp2 = Bio::GenomicInterval.parse("chr1:25-35")
|
46
|
+
ref.overlap(cmp) # => -4
|
47
|
+
|
48
|
+
== Expansion (or integration)
|
49
|
+
ref = Bio::GenomicInterval.parse("chr1:400-600")
|
50
|
+
other = Bio::GenomicInterval.parse("chr1:650-800")
|
51
|
+
ref.expand(other).to_s # => "chr1:400-800"
|
52
|
+
|
53
|
+
== Center
|
54
|
+
obj1 = Bio::GenomicInterval.parse("chr1:1-3")
|
55
|
+
obj1.center # => "chr1:2-2"
|
56
|
+
obj2 = Bio::GenomicInterval.parse("chr2:1-4")
|
57
|
+
obj2.center # => "chr1:2-2"
|
58
|
+
|
59
|
+
== And others
|
60
|
+
ref = Bio::GenomicInterval.parse("chr1:400-600")
|
61
|
+
other = Bio::GenomicInterval.parse("chr1:605-800")
|
62
|
+
ref.overlapped?(other) # => false
|
63
|
+
ref.nearly_overlapped?(other) # => true
|
64
|
+
ref.size # => 201
|
65
|
+
ref.chr_start -= 100
|
66
|
+
ref.chr_end += 100
|
67
|
+
ref.chrom = "chrX"
|
68
|
+
ref.to_s # => "chrX:300-700"
|
69
|
+
|
70
|
+
See also the Rspec file.
|
71
|
+
|
72
|
+
== Contributing to bio-genomic-interval
|
73
|
+
Please do not hesitate to contanct the author by emails.
|
74
|
+
|
75
|
+
== Copyright
|
76
|
+
|
77
|
+
Copyright (c) 2011 Hiroyuki Mishima. See LICENSE.txt for
|
78
|
+
further details.
|
79
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "bio-genomic-interval"
|
16
|
+
gem.homepage = "http://github.com/misshie/bioruby-genomic-interval"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{a BioRuby plugin: handling genomic interavals and overlaps}
|
19
|
+
gem.description =
|
20
|
+
%Q{a BioRuby plugin: handling genomic intervals,such as "chr1:123-456", and overlaps between two intervalsrake }
|
21
|
+
gem.email = "missy@be.to"
|
22
|
+
gem.authors = ["Hiroyuki Mishima"]
|
23
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
24
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
25
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
26
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rspec/core'
|
31
|
+
require 'rspec/core/rake_task'
|
32
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
33
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
37
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
38
|
+
spec.rcov = true
|
39
|
+
end
|
40
|
+
|
41
|
+
task :default => :spec
|
42
|
+
|
43
|
+
require 'rake/rdoctask'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "bio-genomic-interval #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{bio-genomic-interval}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Hiroyuki Mishima"]
|
12
|
+
s.date = %q{2011-04-07}
|
13
|
+
s.description = %q{a BioRuby plugin: handling genomic intervals,such as "chr1:123-456", and overlaps between two intervalsrake }
|
14
|
+
s.email = %q{missy@be.to}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bio-genomic-interval.gemspec",
|
29
|
+
"lib/bio-genomic-interval.rb",
|
30
|
+
"spec/bio-genomic-interval_spec.rb",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/misshie/bioruby-genomic-interval}
|
34
|
+
s.licenses = ["MIT"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.6.2}
|
37
|
+
s.summary = %q{a BioRuby plugin: handling genomic interavals and overlaps}
|
38
|
+
s.test_files = [
|
39
|
+
"spec/bio-genomic-interval_spec.rb",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
48
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
49
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
50
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<bio>, [">= 1.4.1"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
54
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
55
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
56
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
57
|
+
s.add_dependency(%q<bio>, [">= 1.4.1"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
61
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
62
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
63
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
64
|
+
s.add_dependency(%q<bio>, [">= 1.4.1"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Bio
|
2
|
+
|
3
|
+
#
|
4
|
+
# =a class for manupirate genomic intervals such as "chr1:123-456"
|
5
|
+
#
|
6
|
+
class GenomicInterval
|
7
|
+
# a default value to determine the adjacent/very near distance in bp
|
8
|
+
DEFAULT_ADJACENT = 20
|
9
|
+
|
10
|
+
def initialize(chrom = "", chr_start = 1, chr_end = 1)
|
11
|
+
raise ArgumentError unless chr_start >= 1
|
12
|
+
raise ArgumentError unless chr_end >= 1
|
13
|
+
raise ArgumentError unless chr_start <= chr_end
|
14
|
+
@chrom = chrom
|
15
|
+
@chr_start = chr_start
|
16
|
+
@chr_end = chr_end
|
17
|
+
@adjacent = DEFAULT_ADJACENT
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :chrom, :chr_start, :chr_end, :adjacent
|
21
|
+
|
22
|
+
#
|
23
|
+
# generate an interval object from a string expressing
|
24
|
+
# one-based full-closed interval such as "chr1:123-456"
|
25
|
+
#
|
26
|
+
def self.parse(interval)
|
27
|
+
chrom, start_end = interval.split(":")
|
28
|
+
str_start, str_end = start_end.split("-")[0..1]
|
29
|
+
str_end = str_start if str_end.nil?
|
30
|
+
chr_start = Integer(str_start)
|
31
|
+
chr_end = Integer(str_end)
|
32
|
+
if chr_start > chr_end
|
33
|
+
chr_end, chr_start = chr_start, chr_end
|
34
|
+
end
|
35
|
+
self.new(chrom, chr_start, chr_end)
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# generate an interval object from three atguments expressing
|
40
|
+
# zero-based half-closed interval such as "chr1", 122, 456
|
41
|
+
#
|
42
|
+
def self.zero_based(chrom = "", z_start = 0, z_end = 1)
|
43
|
+
z_start += 1
|
44
|
+
self.new(chrom, z_start, z_end)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# returns one-based full-closed interval such as "chr1:123-456"
|
49
|
+
#
|
50
|
+
def to_s
|
51
|
+
"#{@chrom}:#{@chr_start}-#{@chr_end}"
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# returns zero-based half-closed start position
|
56
|
+
#
|
57
|
+
def zero_start
|
58
|
+
@chr_start - 1
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# returns zero-based half-closed end position
|
63
|
+
#
|
64
|
+
def zero_end
|
65
|
+
@chr_end
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# returns one of the followings:
|
70
|
+
# :different_chrom, :left_adjacent, :right_adjacent
|
71
|
+
# :left_off, :right_off, :equal
|
72
|
+
# :contained, :containing, :left_overlapped, :right_overlapped
|
73
|
+
# Imagine that the receiver object is fixed on a number line
|
74
|
+
#
|
75
|
+
def compare(other)
|
76
|
+
case
|
77
|
+
when self.chrom != other.chrom
|
78
|
+
:different_chrom
|
79
|
+
when other.chr_end.between?(self.chr_start - @adjacent, self.chr_start - 1)
|
80
|
+
:left_adjacent
|
81
|
+
when other.chr_start.between?(self.chr_end + 1, self.chr_end + @adjacent)
|
82
|
+
:right_adjacent
|
83
|
+
when other.chr_end < self.chr_start
|
84
|
+
:left_off
|
85
|
+
when self.chr_end < other.chr_start
|
86
|
+
:right_off
|
87
|
+
when (self.chr_start == other.chr_start) &&
|
88
|
+
(self.chr_end == other.chr_end)
|
89
|
+
:equal
|
90
|
+
when (other.chr_start.between?(self.chr_start, self.chr_end)) &&
|
91
|
+
(other.chr_end.between?(self.chr_start, self.chr_end))
|
92
|
+
:contained
|
93
|
+
when (self.chr_start.between?(other.chr_start, other.chr_end)) &&
|
94
|
+
(self.chr_end.between?(other.chr_start, other.chr_end))
|
95
|
+
:containing
|
96
|
+
when (other.chr_start < self.chr_start) &&
|
97
|
+
(other.chr_end.between?(self.chr_start, self.chr_end))
|
98
|
+
:left_overlapped
|
99
|
+
when (other.chr_start.between?(self.chr_start, self.chr_end)) &&
|
100
|
+
(self.chr_end < other.chr_end)
|
101
|
+
:right_overlapped
|
102
|
+
else
|
103
|
+
raise Exception, "must not happen"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def nearly_overlapped?(other)
|
108
|
+
result = compare(other)
|
109
|
+
[ :left_adjacent, :right_adjacent,
|
110
|
+
:equal, :contained, :containing,
|
111
|
+
:left_overlapped, :right_overlapped].any?{|x| x == result}
|
112
|
+
end
|
113
|
+
|
114
|
+
def overlapped?(other)
|
115
|
+
result = compare(other)
|
116
|
+
[ :equal, :contained, :containing,
|
117
|
+
:left_overlapped, :right_overlapped].any?{|x| x == result}
|
118
|
+
end
|
119
|
+
|
120
|
+
def expand(other)
|
121
|
+
raise ArgumentError unless self.chrom == other.chrom
|
122
|
+
new_start = [self.chr_start, other.chr_start].min
|
123
|
+
new_end = [self.chr_end, other.chr_end].max
|
124
|
+
Bio::GenomicInterval.new(@chrom, new_start, new_end)
|
125
|
+
end
|
126
|
+
|
127
|
+
def size
|
128
|
+
chr_end - chr_start + 1
|
129
|
+
end
|
130
|
+
|
131
|
+
alias :length :size
|
132
|
+
|
133
|
+
def center
|
134
|
+
center = (chr_start + chr_end) / 2
|
135
|
+
Bio::GenomicInterval.new(self.chrom, center, center)
|
136
|
+
end
|
137
|
+
|
138
|
+
# * When a overlap exist, return a positive integers (>1) for the overlap length.
|
139
|
+
# * When a overlap does not exist, return a zero or a negative (<= 0) for the space size between the intervals.
|
140
|
+
#
|
141
|
+
def overlap(other)
|
142
|
+
case self.compare(other)
|
143
|
+
when :different_chrom
|
144
|
+
0
|
145
|
+
when :left_off, :left_adjacent, :left_overlapped
|
146
|
+
other.chr_end - self.chr_start + 1
|
147
|
+
when :contained, :equal
|
148
|
+
other.size
|
149
|
+
when :containing
|
150
|
+
self.size
|
151
|
+
when :right_off, :right_adjacent, :right_overlapped
|
152
|
+
self.chr_end - other.chr_start + 1
|
153
|
+
else
|
154
|
+
raise Exception, "must not happen"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,357 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Bio::GenomicInterval" do
|
4
|
+
|
5
|
+
#
|
6
|
+
# class methods
|
7
|
+
#
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
context 'given ("chr1", 1, 234)' do
|
11
|
+
it "is a Bio::GenomicInterval" do
|
12
|
+
Bio::GenomicInterval.new("chr1", 1, 234).should be_a(Bio::GenomicInterval)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'given ("chr1", -1, 234)' do
|
17
|
+
it "raises an ArgumentError" do
|
18
|
+
expect{Bio::GenomicInterval.new("chr1", -1, 234)}.to raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'given ("chr1", 234, 1)' do
|
23
|
+
it "raise an ArgumentError" do
|
24
|
+
expect{Bio::GenomicInterval.new("chr1", 234, 1)}.to raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'given no argument' do
|
29
|
+
it "is a Bio::GenomicInterval" do
|
30
|
+
Bio::GenomicInterval.new.should be_a(Bio::GenomicInterval)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".parse" do
|
36
|
+
context 'given "chr1:1-123"' do
|
37
|
+
it 'represents "chr1:1-123" by the to_s method' do
|
38
|
+
Bio::GenomicInterval.parse("chr1:1-123").to_s.should == "chr1:1-123"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'given "chr1:123-1"' do
|
43
|
+
it 'represents "chr1:1-123" by the to_s method' do
|
44
|
+
Bio::GenomicInterval.parse("chr1:123-1").to_s.should == "chr1:1-123"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'given "chr1:123"' do
|
49
|
+
it 'represents "chr1:123-123" by the to_s method' do
|
50
|
+
Bio::GenomicInterval.parse("chr1:123").to_s.should == "chr1:123-123"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe ".zero_based" do
|
56
|
+
context 'given ("chr1", 0, 1)' do
|
57
|
+
it 'represents "chr1:1-1" by the to_s method' do
|
58
|
+
Bio::GenomicInterval.zero_based("chr1", 0, 1).to_s.should == "chr1:1-1"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# instance methods
|
65
|
+
#
|
66
|
+
describe '#zero_start for "chr1:1-1"' do
|
67
|
+
context 'when called' do
|
68
|
+
it 'returns 0' do
|
69
|
+
Bio::GenomicInterval.parse("chr1:1-1").zero_start.should == 0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#zero_end for "chr1:1-1"' do
|
75
|
+
context 'when called' do
|
76
|
+
it 'returns 1' do
|
77
|
+
Bio::GenomicInterval.parse("chr1:1-1").zero_end.should == 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
describe '#adjacent' do
|
84
|
+
context 'when called first' do
|
85
|
+
it 'returns default value' do
|
86
|
+
default = Bio::GenomicInterval::DEFAULT_ADJACENT
|
87
|
+
Bio::GenomicInterval.new.adjacent.should == default
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when set by #adjacent = 10' do
|
92
|
+
it 'returns 10' do
|
93
|
+
obj = Bio::GenomicInterval.new
|
94
|
+
obj.adjacent = 10
|
95
|
+
obj.adjacent.should == 10
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#compare for "chr1:400-600"' do
|
101
|
+
context 'given "chrX:123-234"' do
|
102
|
+
it 'returns :different_chr' do
|
103
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
104
|
+
subject = Bio::GenomicInterval.parse("chrX:123-234")
|
105
|
+
receiver.compare(subject).should == :different_chrom
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'given "chr1:123-234"' do
|
110
|
+
it 'returns :left_off' do
|
111
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
112
|
+
subject = Bio::GenomicInterval.parse("chr1:123-234")
|
113
|
+
receiver.compare(subject).should == :left_off
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'given "chr1:789-890"' do
|
118
|
+
it 'returns :right_off' do
|
119
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
120
|
+
subject = Bio::GenomicInterval.parse("chr1:789-890")
|
121
|
+
receiver.compare(subject).should == :right_off
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'given "chr1:450-550"' do
|
126
|
+
it 'returns :contained' do
|
127
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
128
|
+
subject = Bio::GenomicInterval.parse("chr1:450-550")
|
129
|
+
receiver.compare(subject).should == :contained
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'given "chr1:400-400" (size == 1)' do
|
134
|
+
it 'returns :contained' do
|
135
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
136
|
+
subject = Bio::GenomicInterval.parse("chr1:400-400")
|
137
|
+
receiver.compare(subject).should == :contained
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'given "chr1:300-700"' do
|
142
|
+
it 'returns :containing' do
|
143
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
144
|
+
subject = Bio::GenomicInterval.parse("chr1:300-700")
|
145
|
+
receiver.compare(subject).should == :containing
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'given "chr1:300-500"' do
|
150
|
+
it 'returns :left_overlapped' do
|
151
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
152
|
+
subject = Bio::GenomicInterval.parse("chr1:300-500")
|
153
|
+
receiver.compare(subject).should == :left_overlapped
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'given "chr1:500-700"' do
|
158
|
+
it 'returns :right_overlapped' do
|
159
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
160
|
+
subject = Bio::GenomicInterval.parse("chr1:500-700")
|
161
|
+
receiver.compare(subject).should == :right_overlapped
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'given same interval' do
|
166
|
+
it 'returns :equal' do
|
167
|
+
receiver = subject = Bio::GenomicInterval.parse("chr1:400-600")
|
168
|
+
receiver.compare(subject).should == :equal
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'given "chr1:300-398"' do
|
173
|
+
it 'returns :right_adjacent' do
|
174
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
175
|
+
subject = Bio::GenomicInterval.parse("chr1:300-398")
|
176
|
+
receiver.compare(subject).should == :left_adjacent
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'given "chr1:399-399" (size == 1)' do
|
181
|
+
it 'returns :right_adjacent' do
|
182
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
183
|
+
subject = Bio::GenomicInterval.parse("chr1:399-399")
|
184
|
+
receiver.compare(subject).should == :left_adjacent
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'given "chr1:603-800"' do
|
189
|
+
it 'returns :right_adjacent' do
|
190
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
191
|
+
subject = Bio::GenomicInterval.parse("chr1:603-800")
|
192
|
+
receiver.compare(subject).should == :right_adjacent
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#nearly_overlapped? for "chr1:400-600"' do
|
198
|
+
context 'given "chr1:300-500"' do
|
199
|
+
it 'returens true' do
|
200
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
201
|
+
subject = Bio::GenomicInterval.parse("chr1:300-500")
|
202
|
+
receiver.nearly_overlapped?(subject).should be_true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'given "chr1:300-390"' do
|
207
|
+
it 'returens true' do
|
208
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
209
|
+
receiver.adjacent = 20
|
210
|
+
subject = Bio::GenomicInterval.parse("chr1:300-390")
|
211
|
+
receiver.nearly_overlapped?(subject).should be_true
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe '#overlapped? for "chr1:400-600"' do
|
217
|
+
context 'given "chr1:300-500"' do
|
218
|
+
it 'returens true' do
|
219
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
220
|
+
subject = Bio::GenomicInterval.parse("chr1:300-500")
|
221
|
+
receiver.overlapped?(subject).should be_true
|
222
|
+
end
|
223
|
+
end
|
224
|
+
context 'given "chr1:300-370"' do
|
225
|
+
it 'returens false' do
|
226
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
227
|
+
receiver.adjacent = 20
|
228
|
+
subject = Bio::GenomicInterval.parse("chr1:300-370")
|
229
|
+
receiver.overlapped?(subject).should be_false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe '#expand for "chr1:400-600"' do
|
235
|
+
context 'given "chr1:603-800"' do
|
236
|
+
it 'returns "chr1:400-800" by the to_s method' do
|
237
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
238
|
+
subject = Bio::GenomicInterval.parse("chr1:603-800")
|
239
|
+
receiver.expand(subject).to_s.should == "chr1:400-800"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'given "chrX:603-800"' do
|
244
|
+
it 'raises ArgumentError' do
|
245
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-600")
|
246
|
+
subject = Bio::GenomicInterval.parse("chrX:603-800")
|
247
|
+
expect{receiver.expand(subject)}.to raise_error(ArgumentError)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#size' do
|
253
|
+
context 'when initialized by "chr1:400-410"' do
|
254
|
+
it 'returens 11' do
|
255
|
+
Bio::GenomicInterval.parse("chr1:400-410").size.should == 11
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe '#center' do
|
261
|
+
context 'when initialized by "chr1:11-15"' do
|
262
|
+
it 'returns "chr1:13-13" by the to_s method' do
|
263
|
+
Bio::GenomicInterval.parse("chr1:11-15").center.to_s.should == "chr1:13-13"
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'when initialize by "chr1:10-15"' do
|
268
|
+
it 'returns "chr1:12-12" by the to_s method' do
|
269
|
+
Bio::GenomicInterval.parse("chr1:10-15").center.to_s.should == "chr1:12-12"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe '#overlap for "chr1:400-500"' do
|
275
|
+
context 'given "chr1:100-200"' do
|
276
|
+
it 'returns -199' do
|
277
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
278
|
+
subject = Bio::GenomicInterval.parse("chr1:100-200")
|
279
|
+
receiver.overlap(subject).should == -199
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context 'given "chr1:100-399"' do
|
284
|
+
it 'returns 0' do
|
285
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
286
|
+
subject = Bio::GenomicInterval.parse("chr1:100-399")
|
287
|
+
receiver.overlap(subject).should == 0
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context 'given "chr1:100-400"' do
|
292
|
+
it 'returns 1' do
|
293
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
294
|
+
subject = Bio::GenomicInterval.parse("chr1:100-400")
|
295
|
+
receiver.overlap(subject).should == 1
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context 'given "chr1:410-490"' do
|
300
|
+
it 'returns 81' do
|
301
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
302
|
+
subject = Bio::GenomicInterval.parse("chr1:410-490")
|
303
|
+
receiver.overlap(subject).should == 81
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
context 'given "chr1:300-600"' do
|
308
|
+
it 'returns 101' do
|
309
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
310
|
+
subject = Bio::GenomicInterval.parse("chr1:300-600")
|
311
|
+
receiver.overlap(subject).should == 101
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context 'given "chr1:400-500"' do
|
316
|
+
it 'returns 101' do
|
317
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
318
|
+
subject = Bio::GenomicInterval.parse("chr1:400-500")
|
319
|
+
receiver.overlap(subject).should == 101
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'given "chr1:450-550"' do
|
324
|
+
it 'returns 51' do
|
325
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
326
|
+
subject = Bio::GenomicInterval.parse("chr1:450-550")
|
327
|
+
receiver.overlap(subject).should == 51
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
context 'given "chr1:501-600"' do
|
332
|
+
it 'returns 0' do
|
333
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
334
|
+
subject = Bio::GenomicInterval.parse("chr1:501-600")
|
335
|
+
receiver.overlap(subject).should == 0
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context 'given "chr1:550-600"' do
|
340
|
+
it 'returns -49' do
|
341
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
342
|
+
subject = Bio::GenomicInterval.parse("chr1:550-600")
|
343
|
+
receiver.overlap(subject).should == -49
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
context 'given "chrX:100-900"' do
|
348
|
+
it 'returns 0' do
|
349
|
+
receiver = Bio::GenomicInterval.parse("chr1:400-500")
|
350
|
+
subject = Bio::GenomicInterval.parse("chrX:100-900")
|
351
|
+
receiver.overlap(subject).should == 0
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'bio-genomic-interval'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bio-genomic-interval
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Hiroyuki Mishima
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-07 00:00:00 +09:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
version: 2.3.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: bundler
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 23
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 0
|
48
|
+
- 0
|
49
|
+
version: 1.0.0
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: jeweler
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 7
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 5
|
64
|
+
- 2
|
65
|
+
version: 1.5.2
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rcov
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bio
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 5
|
91
|
+
segments:
|
92
|
+
- 1
|
93
|
+
- 4
|
94
|
+
- 1
|
95
|
+
version: 1.4.1
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: *id005
|
99
|
+
description: "a BioRuby plugin: handling genomic intervals,such as \"chr1:123-456\", and overlaps between two intervalsrake "
|
100
|
+
email: missy@be.to
|
101
|
+
executables: []
|
102
|
+
|
103
|
+
extensions: []
|
104
|
+
|
105
|
+
extra_rdoc_files:
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.rdoc
|
108
|
+
files:
|
109
|
+
- .document
|
110
|
+
- .rspec
|
111
|
+
- Gemfile
|
112
|
+
- Gemfile.lock
|
113
|
+
- LICENSE.txt
|
114
|
+
- README.rdoc
|
115
|
+
- Rakefile
|
116
|
+
- VERSION
|
117
|
+
- bio-genomic-interval.gemspec
|
118
|
+
- lib/bio-genomic-interval.rb
|
119
|
+
- spec/bio-genomic-interval_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
has_rdoc: true
|
122
|
+
homepage: http://github.com/misshie/bioruby-genomic-interval
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
hash: 3
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
148
|
+
requirements: []
|
149
|
+
|
150
|
+
rubyforge_project:
|
151
|
+
rubygems_version: 1.6.2
|
152
|
+
signing_key:
|
153
|
+
specification_version: 3
|
154
|
+
summary: "a BioRuby plugin: handling genomic interavals and overlaps"
|
155
|
+
test_files:
|
156
|
+
- spec/bio-genomic-interval_spec.rb
|
157
|
+
- spec/spec_helper.rb
|