scaffolder 0.2.6
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/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +25 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/lib/scaffolder.rb +51 -0
- data/lib/scaffolder/insert.rb +32 -0
- data/lib/scaffolder/region.rb +1 -0
- data/lib/scaffolder/sequence.rb +50 -0
- data/scaffolder.gemspec +76 -0
- data/test/data/sequences.fna +4 -0
- data/test/helper.rb +15 -0
- data/test/test_insert.rb +60 -0
- data/test/test_region.rb +11 -0
- data/test/test_scaffolder.rb +85 -0
- data/test/test_sequence.rb +124 -0
- metadata +159 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Michael Barton
|
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,25 @@
|
|
1
|
+
= scaffolder
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Michael Barton. See LICENSE for details.
|
18
|
+
|
19
|
+
== Notes
|
20
|
+
|
21
|
+
Inserts processed are processed in reverse order according to end position. Last insert added up until first insert. Done to preserve insert coordinates.
|
22
|
+
|
23
|
+
Overlapping inserts may cause unexpected behaviour
|
24
|
+
|
25
|
+
Sequence reversed after inserts have been added.
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "scaffolder"
|
8
|
+
gem.summary = %Q{Scaffolder for genome sequence data}
|
9
|
+
gem.description = %Q{Organise genome sequence data into scaffolds using YAML configuration files.}
|
10
|
+
gem.email = "mail@michaelbarton.me.uk"
|
11
|
+
gem.homepage = "http://github.com/michaelbarton/scaffolder"
|
12
|
+
gem.authors = ["Michael Barton"]
|
13
|
+
gem.add_dependency "bio", ">= 0"
|
14
|
+
gem.add_development_dependency "rr", ">= 0.10.11"
|
15
|
+
gem.add_development_dependency "shoulda", ">= 0"
|
16
|
+
gem.add_development_dependency "redgreen", ">= 0"
|
17
|
+
gem.add_development_dependency "yard", ">= 0"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
Rake::TestTask.new(:test) do |test|
|
27
|
+
test.libs << 'lib' << 'test'
|
28
|
+
test.pattern = 'test/**/test_*.rb'
|
29
|
+
test.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rcov/rcovtask'
|
34
|
+
Rcov::RcovTask.new do |test|
|
35
|
+
test.libs << 'test'
|
36
|
+
test.pattern = 'test/**/test_*.rb'
|
37
|
+
test.verbose = true
|
38
|
+
end
|
39
|
+
rescue LoadError
|
40
|
+
task :rcov do
|
41
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
task :test => :check_dependencies
|
46
|
+
|
47
|
+
task :default => :test
|
48
|
+
|
49
|
+
begin
|
50
|
+
require 'yard'
|
51
|
+
YARD::Rake::YardocTask.new
|
52
|
+
rescue LoadError
|
53
|
+
task :yardoc do
|
54
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
55
|
+
end
|
56
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.6
|
data/lib/scaffolder.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'bio'
|
3
|
+
|
4
|
+
class Scaffolder < DelegateClass(Array)
|
5
|
+
autoload :Region, 'scaffolder/region'
|
6
|
+
autoload :Insert, 'scaffolder/insert'
|
7
|
+
autoload :Sequence, 'scaffolder/sequence'
|
8
|
+
|
9
|
+
def initialize(assembly,sequence)
|
10
|
+
@sequences = Hash[ *Bio::FlatFile::auto(sequence).collect { |s|
|
11
|
+
[s.definition.split.first,s.seq]
|
12
|
+
}.flatten]
|
13
|
+
|
14
|
+
super(assembly.map do |entry|
|
15
|
+
type, data = entry.keys.first, entry.values.first
|
16
|
+
|
17
|
+
case type
|
18
|
+
when 'unresolved'
|
19
|
+
Scaffolder::Region.new(:unresolved,'N'*data['length'])
|
20
|
+
when 'sequence'
|
21
|
+
sequence = Scaffolder::Sequence.new(
|
22
|
+
:name => data['source'],
|
23
|
+
:start => data['start'],
|
24
|
+
:end => data['end'],
|
25
|
+
:reverse => data['reverse'],
|
26
|
+
:sequence => fetch_sequence(data['source'])
|
27
|
+
)
|
28
|
+
if data['inserts']
|
29
|
+
sequence.add_inserts(data['inserts'].map do |insert|
|
30
|
+
Scaffolder::Insert.new(
|
31
|
+
:start => insert['start'],
|
32
|
+
:stop => insert['stop'],
|
33
|
+
:reverse => insert['reverse'],
|
34
|
+
:sequence => fetch_sequence(insert['source'])
|
35
|
+
)
|
36
|
+
end)
|
37
|
+
end
|
38
|
+
sequence
|
39
|
+
else
|
40
|
+
raise ArgumentError.new("Unknown tag: #{type}")
|
41
|
+
end
|
42
|
+
end)
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_sequence(name)
|
46
|
+
sequence = @sequences[name]
|
47
|
+
raise ArgumentError.new("Missing sequence: #{name}") unless sequence
|
48
|
+
sequence
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Scaffolder
|
2
|
+
class Insert
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
attr_accessor :start, :stop, :sequence
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@sequence = options[:sequence]
|
9
|
+
@start = options[:start]
|
10
|
+
@stop = options[:stop]
|
11
|
+
|
12
|
+
m = "Either insert start or stop must be provided"
|
13
|
+
raise ArgumentError.new(m) if @start.nil? and @stop.nil?
|
14
|
+
|
15
|
+
@start ||= (@stop - @sequence.length - 1)
|
16
|
+
@stop ||= (@start + @sequence.length - 1)
|
17
|
+
|
18
|
+
if options[:reverse]
|
19
|
+
@sequence = Bio::Sequence::NA.new(@sequence).reverse_complement.seq.upcase
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def position
|
24
|
+
@start-1..@stop-1
|
25
|
+
end
|
26
|
+
|
27
|
+
def <=>(other)
|
28
|
+
self.stop <=> other.stop
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Scaffolder::Region = Struct.new(:entry_type,:sequence)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class Scaffolder
|
2
|
+
class Sequence
|
3
|
+
|
4
|
+
attr_accessor :entry_type, :start, :end, :name, :inserts, :raw_sequence
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@entry_type = :sequence
|
8
|
+
@name = options[:name]
|
9
|
+
@start = options[:start] || 1
|
10
|
+
@end = options[:end] || options[:sequence].length
|
11
|
+
@sequence = options[:sequence]
|
12
|
+
@raw_sequence = @sequence.clone
|
13
|
+
@reverse = options[:reverse]
|
14
|
+
@inserts = []
|
15
|
+
|
16
|
+
raise ArgumentError.new("Sequence end greater than length") if @end > @raw_sequence.length
|
17
|
+
raise ArgumentError.new("Sequence start less than 0") if @start < 1
|
18
|
+
raise ArgumentError.new("Sequence start greater than end") if @start > @end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_inserts(inserts)
|
23
|
+
@inserts = inserts.sort.reverse
|
24
|
+
@inserts.each do |insert|
|
25
|
+
if insert.start > @sequence.length
|
26
|
+
raise ArgumentError.new("Insert start greater than length")
|
27
|
+
end
|
28
|
+
if insert.stop < 1
|
29
|
+
raise ArgumentError.new("Insert end less than 1")
|
30
|
+
end
|
31
|
+
if insert.stop <= insert.start
|
32
|
+
raise ArgumentError.new("Insert end less than start")
|
33
|
+
end
|
34
|
+
|
35
|
+
before_size = @sequence.length
|
36
|
+
@sequence[insert.position] = insert.sequence
|
37
|
+
|
38
|
+
# Update sequence end after adding inserts
|
39
|
+
diff = @sequence.length - before_size
|
40
|
+
@end += diff
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def sequence
|
45
|
+
seq = @sequence[(@start-1)..(@end-1)]
|
46
|
+
seq = Bio::Sequence::NA.new(seq).reverse_complement if @reverse
|
47
|
+
seq.to_s.upcase
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/scaffolder.gemspec
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{scaffolder}
|
8
|
+
s.version = "0.2.6"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Barton"]
|
12
|
+
s.date = %q{2010-10-10}
|
13
|
+
s.description = %q{Organise genome sequence data into scaffolds using YAML configuration files.}
|
14
|
+
s.email = %q{mail@michaelbarton.me.uk}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/scaffolder.rb",
|
27
|
+
"lib/scaffolder/insert.rb",
|
28
|
+
"lib/scaffolder/region.rb",
|
29
|
+
"lib/scaffolder/sequence.rb",
|
30
|
+
"scaffolder.gemspec",
|
31
|
+
"test/data/sequences.fna",
|
32
|
+
"test/helper.rb",
|
33
|
+
"test/test_insert.rb",
|
34
|
+
"test/test_region.rb",
|
35
|
+
"test/test_scaffolder.rb",
|
36
|
+
"test/test_sequence.rb"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/michaelbarton/scaffolder}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.7}
|
42
|
+
s.summary = %q{Scaffolder for genome sequence data}
|
43
|
+
s.test_files = [
|
44
|
+
"test/helper.rb",
|
45
|
+
"test/test_insert.rb",
|
46
|
+
"test/test_region.rb",
|
47
|
+
"test/test_scaffolder.rb",
|
48
|
+
"test/test_sequence.rb"
|
49
|
+
]
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
53
|
+
s.specification_version = 3
|
54
|
+
|
55
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
56
|
+
s.add_runtime_dependency(%q<bio>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<rr>, [">= 0.10.11"])
|
58
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
59
|
+
s.add_development_dependency(%q<redgreen>, [">= 0"])
|
60
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<bio>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rr>, [">= 0.10.11"])
|
64
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
65
|
+
s.add_dependency(%q<redgreen>, [">= 0"])
|
66
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
67
|
+
end
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<bio>, [">= 0"])
|
70
|
+
s.add_dependency(%q<rr>, [">= 0.10.11"])
|
71
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
72
|
+
s.add_dependency(%q<redgreen>, [">= 0"])
|
73
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'redgreen'
|
5
|
+
require 'rr'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
require 'scaffolder'
|
11
|
+
|
12
|
+
class Test::Unit::TestCase
|
13
|
+
require 'tempfile'
|
14
|
+
include RR::Adapters::TestUnit
|
15
|
+
end
|
data/test/test_insert.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestInsert < Test::Unit::TestCase
|
4
|
+
context Scaffolder::Insert do
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@options = {
|
8
|
+
:start => 5,
|
9
|
+
:stop => 10,
|
10
|
+
:sequence => "ATGCGGGC"
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
should "correctly store the passed options" do
|
15
|
+
i = Scaffolder::Insert.new @options
|
16
|
+
assert_equal(i.start, @options[:start])
|
17
|
+
assert_equal(i.stop, @options[:stop])
|
18
|
+
assert_equal(i.sequence, @options[:sequence])
|
19
|
+
end
|
20
|
+
|
21
|
+
should "reverse the sequence when passed the reverse tag" do
|
22
|
+
i = Scaffolder::Insert.new @options.merge(:reverse => true)
|
23
|
+
rev = Bio::Sequence::NA.new(@options[:sequence]).reverse_complement
|
24
|
+
assert_equal(i.sequence, rev.upcase)
|
25
|
+
end
|
26
|
+
|
27
|
+
should "correctly generate the position" do
|
28
|
+
i = Scaffolder::Insert.new @options
|
29
|
+
assert_equal(i.position, (@options[:start]-1)..(@options[:stop]-1))
|
30
|
+
end
|
31
|
+
|
32
|
+
should "estimate the sequence end position" do
|
33
|
+
@options.delete(:stop)
|
34
|
+
i = Scaffolder::Insert.new @options
|
35
|
+
assert_equal(i.stop, @options[:start] + @options[:sequence].length - 1)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "estimate the sequence start position" do
|
39
|
+
@options.delete(:start)
|
40
|
+
i = Scaffolder::Insert.new @options
|
41
|
+
assert_equal(i.start, @options[:stop] - @options[:sequence].length - 1)
|
42
|
+
end
|
43
|
+
|
44
|
+
should "throw error when neither start or stop are provided" do
|
45
|
+
@options.delete(:start)
|
46
|
+
@options.delete(:stop)
|
47
|
+
assert_raise ArgumentError do
|
48
|
+
Scaffolder::Insert.new @options
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
should "be comparable by end position" do
|
53
|
+
a = Scaffolder::Insert.new @options
|
54
|
+
b = Scaffolder::Insert.new @options.merge(:stop => @options[:stop] + 1)
|
55
|
+
c = Scaffolder::Insert.new @options.merge(:stop => @options[:stop] + 2)
|
56
|
+
assert_equal([c,a,b].sort, [a,b,c])
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/test/test_region.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestScaffolder < Test::Unit::TestCase
|
4
|
+
context Scaffolder::Region do
|
5
|
+
should "be created from parameters" do
|
6
|
+
region = Scaffolder::Region.new(:unresolved,'NNNN')
|
7
|
+
assert_equal(region.entry_type,:unresolved)
|
8
|
+
assert_equal(region.sequence,'NNNN')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestScaffolder < Test::Unit::TestCase
|
4
|
+
context Scaffolder do
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@sequence = File.join(File.dirname(__FILE__),'data','sequences.fna')
|
8
|
+
@assembly = [ {"sequence" => { "source" => "sequence1" } } ]
|
9
|
+
@expect = {:name => 'sequence1', :start => nil, :end => nil,
|
10
|
+
:sequence => 'ATGCCAGATAACTGACTAGCATG', :reverse => nil}
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when parsing a sequence tag" do
|
14
|
+
|
15
|
+
should "create sequence" do
|
16
|
+
mock(Scaffolder::Sequence).new(@expect)
|
17
|
+
Scaffolder.new @assembly, @sequence
|
18
|
+
end
|
19
|
+
|
20
|
+
should "create sequence with coordinates" do
|
21
|
+
@assembly.first['sequence'].update('start' => 2, 'end' => 5)
|
22
|
+
mock(Scaffolder::Sequence).new(@expect.update({:start => 2, :end => 5 }))
|
23
|
+
Scaffolder.new @assembly, @sequence
|
24
|
+
end
|
25
|
+
|
26
|
+
should "create sequence with reverse" do
|
27
|
+
@assembly.first['sequence'].update('reverse' => true)
|
28
|
+
mock(Scaffolder::Sequence).new(@expect.update({:reverse => true }))
|
29
|
+
Scaffolder.new @assembly, @sequence
|
30
|
+
end
|
31
|
+
|
32
|
+
should "throw an error when source doesn't have a matching sequence" do
|
33
|
+
@assembly.first['sequence'].update('source' => 'sequence3')
|
34
|
+
assert_raise(ArgumentError){ Scaffolder.new @assembly, @sequence }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "parsing an assembly with sequence inserts" do
|
39
|
+
|
40
|
+
setup do
|
41
|
+
@assembly.first['sequence'].update({"inserts" => [{
|
42
|
+
"source" => "insert1", "start" => 5, "stop" => 10, "reverse" => true
|
43
|
+
}]})
|
44
|
+
end
|
45
|
+
|
46
|
+
should "pass inserts to sequence object" do
|
47
|
+
params = {:start => 5, :stop => 10,
|
48
|
+
:sequence => 'GGTAGTA', :reverse => true}
|
49
|
+
|
50
|
+
insert = Scaffolder::Insert.new(params)
|
51
|
+
|
52
|
+
mock.instance_of(Scaffolder::Sequence).add_inserts([insert])
|
53
|
+
mock(Scaffolder::Insert).new(params){insert}
|
54
|
+
|
55
|
+
Scaffolder.new @assembly, @sequence
|
56
|
+
end
|
57
|
+
|
58
|
+
should "throw and error when insert does not have a matching sequence" do
|
59
|
+
@assembly.first['sequence']['inserts'].first.update({
|
60
|
+
"source" => "missing"})
|
61
|
+
assert_raise(ArgumentError){ Scaffolder.new @assembly, @sequence }
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when parsing an assembly with an unresolved region" do
|
67
|
+
|
68
|
+
setup{ @assembly = [ {"unresolved" => { "length" => 5 } } ] }
|
69
|
+
|
70
|
+
should 'create an unresolved region' do
|
71
|
+
mock(Scaffolder::Region).new(:unresolved,'N'*5)
|
72
|
+
Scaffolder.new @assembly, @sequence
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when parsing an unknown tag" do
|
78
|
+
setup{ @assembly = [{'non_standard_tag' => []}] }
|
79
|
+
should "throw an argument error" do
|
80
|
+
assert_raise(ArgumentError){ Scaffolder.new @assembly, @sequence }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestScaffolder < Test::Unit::TestCase
|
4
|
+
context Scaffolder::Sequence do
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@options = { :name => "sequence1",
|
8
|
+
:sequence => 'ATGCCAGATAACTGACTAGCATG' }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "processing a simple sequence tag" do
|
12
|
+
|
13
|
+
should "create sequence object" do
|
14
|
+
sequence = Scaffolder::Sequence.new @options
|
15
|
+
assert_equal(sequence.entry_type,:sequence)
|
16
|
+
assert_equal(sequence.start,1)
|
17
|
+
assert_equal(sequence.end,23)
|
18
|
+
assert_equal(sequence.name,'sequence1')
|
19
|
+
assert_equal(sequence.sequence,'ATGCCAGATAACTGACTAGCATG')
|
20
|
+
assert_equal(sequence.raw_sequence,'ATGCCAGATAACTGACTAGCATG')
|
21
|
+
end
|
22
|
+
|
23
|
+
should "reverse sequence when passed the reverse option" do
|
24
|
+
sequence = Scaffolder::Sequence.new @options.merge(:reverse => true)
|
25
|
+
assert_equal(sequence.sequence,'CATGCTAGTCAGTTATCTGGCAT')
|
26
|
+
assert_equal(sequence.raw_sequence,'ATGCCAGATAACTGACTAGCATG')
|
27
|
+
end
|
28
|
+
|
29
|
+
should "create subsequence object when passed sequence coordinates" do
|
30
|
+
sequence = Scaffolder::Sequence.new @options.merge(:start => 5,:end => 20)
|
31
|
+
assert_equal(sequence.start,5)
|
32
|
+
assert_equal(sequence.end,20)
|
33
|
+
assert_equal(sequence.sequence,'CAGATAACTGACTAGC')
|
34
|
+
end
|
35
|
+
|
36
|
+
should "throw an error when the start position is outside the sequence length" do
|
37
|
+
begin
|
38
|
+
Scaffolder::Sequence.new @options.merge(:start => 0)
|
39
|
+
flunk "Should throw an argument error"
|
40
|
+
rescue ArgumentError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
should "throw an error when the end position is outside the sequence length" do
|
45
|
+
begin
|
46
|
+
Scaffolder::Sequence.new @options.merge(:end => 24)
|
47
|
+
flunk "Should throw an argument error"
|
48
|
+
rescue ArgumentError
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
should "throw an error when the start is greater than the end" do
|
53
|
+
begin
|
54
|
+
Scaffolder::Sequence.new @options.merge(:end => 5,:start => 10)
|
55
|
+
flunk "Should throw an argument error"
|
56
|
+
rescue ArgumentError
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
context "processing a sequence tag with inserts" do
|
63
|
+
|
64
|
+
setup do
|
65
|
+
@insert = {:start => 5, :stop => 10, :sequence => 'GGTAGTA'}
|
66
|
+
@sequence = Scaffolder::Sequence.new @options
|
67
|
+
end
|
68
|
+
|
69
|
+
should "raise when the insert start is after the sequence end" do
|
70
|
+
@insert.update(:start => 24,:stop => nil)
|
71
|
+
assert_raise(ArgumentError) do
|
72
|
+
@sequence.add_inserts([Scaffolder::Insert.new @insert])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
should "raise when the insert stop is before the sequence start" do
|
77
|
+
@insert.update(:start => -5,:stop => 0)
|
78
|
+
assert_raise(ArgumentError) do
|
79
|
+
@sequence.add_inserts([Scaffolder::Insert.new @insert])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
should "raise when insert start is greater than end" do
|
84
|
+
@insert.update(:start => 11)
|
85
|
+
assert_raise(ArgumentError) do
|
86
|
+
@sequence.add_inserts([Scaffolder::Insert.new @insert])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
should "update the sequence" do
|
91
|
+
@sequence.add_inserts([Scaffolder::Insert.new @insert])
|
92
|
+
assert_equal(@sequence.sequence,'ATGCGGTAGTAACTGACTAGCATG')
|
93
|
+
assert_equal(@sequence.end,24)
|
94
|
+
assert_equal(@sequence.raw_sequence,'ATGCCAGATAACTGACTAGCATG')
|
95
|
+
end
|
96
|
+
|
97
|
+
should "return added insert as an attribute" do
|
98
|
+
inserts = [Scaffolder::Insert.new @insert]
|
99
|
+
@sequence.add_inserts(inserts)
|
100
|
+
assert_equal(@sequence.inserts,inserts)
|
101
|
+
end
|
102
|
+
|
103
|
+
should "return empty array when no inserts and inserts method called" do
|
104
|
+
assert_equal(@sequence.inserts,[])
|
105
|
+
end
|
106
|
+
|
107
|
+
should "update the sequence when reversed" do
|
108
|
+
@sequence = Scaffolder::Sequence.new @options.update(:reverse => true)
|
109
|
+
@sequence.add_inserts([Scaffolder::Insert.new @insert])
|
110
|
+
assert_equal(@sequence.sequence,"CATGCTAGTCAGTTACTACCGCAT")
|
111
|
+
assert_equal(@sequence.raw_sequence,'ATGCCAGATAACTGACTAGCATG')
|
112
|
+
end
|
113
|
+
|
114
|
+
should "update the sequence with two inserts" do
|
115
|
+
@sequence.add_inserts([Scaffolder::Insert.new(@insert),
|
116
|
+
Scaffolder::Insert.new(@insert.update(:start => 12, :stop => 15))])
|
117
|
+
assert_equal(@sequence.sequence,"ATGCGGTAGTAAGGTAGTACTAGCATG")
|
118
|
+
assert_equal(@sequence.end,27)
|
119
|
+
assert_equal(@sequence.raw_sequence,'ATGCCAGATAACTGACTAGCATG')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: scaffolder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 6
|
10
|
+
version: 0.2.6
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Michael Barton
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-10 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bio
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rr
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 33
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 10
|
47
|
+
- 11
|
48
|
+
version: 0.10.11
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: shoulda
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
type: :development
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: redgreen
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
type: :development
|
78
|
+
version_requirements: *id004
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: yard
|
81
|
+
prerelease: false
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id005
|
93
|
+
description: Organise genome sequence data into scaffolds using YAML configuration files.
|
94
|
+
email: mail@michaelbarton.me.uk
|
95
|
+
executables: []
|
96
|
+
|
97
|
+
extensions: []
|
98
|
+
|
99
|
+
extra_rdoc_files:
|
100
|
+
- LICENSE
|
101
|
+
- README.rdoc
|
102
|
+
files:
|
103
|
+
- .document
|
104
|
+
- .gitignore
|
105
|
+
- LICENSE
|
106
|
+
- README.rdoc
|
107
|
+
- Rakefile
|
108
|
+
- VERSION
|
109
|
+
- lib/scaffolder.rb
|
110
|
+
- lib/scaffolder/insert.rb
|
111
|
+
- lib/scaffolder/region.rb
|
112
|
+
- lib/scaffolder/sequence.rb
|
113
|
+
- scaffolder.gemspec
|
114
|
+
- test/data/sequences.fna
|
115
|
+
- test/helper.rb
|
116
|
+
- test/test_insert.rb
|
117
|
+
- test/test_region.rb
|
118
|
+
- test/test_scaffolder.rb
|
119
|
+
- test/test_sequence.rb
|
120
|
+
has_rdoc: true
|
121
|
+
homepage: http://github.com/michaelbarton/scaffolder
|
122
|
+
licenses: []
|
123
|
+
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options:
|
126
|
+
- --charset=UTF-8
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
hash: 3
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
version: "0"
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
hash: 3
|
144
|
+
segments:
|
145
|
+
- 0
|
146
|
+
version: "0"
|
147
|
+
requirements: []
|
148
|
+
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 1.3.7
|
151
|
+
signing_key:
|
152
|
+
specification_version: 3
|
153
|
+
summary: Scaffolder for genome sequence data
|
154
|
+
test_files:
|
155
|
+
- test/helper.rb
|
156
|
+
- test/test_insert.rb
|
157
|
+
- test/test_region.rb
|
158
|
+
- test/test_scaffolder.rb
|
159
|
+
- test/test_sequence.rb
|