wrnap 0.12.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/wrnap.rb +34 -35
- data/lib/wrnap/etl/infernal.rb +9 -8
- data/lib/wrnap/etl/stockholm.rb +6 -6
- data/lib/wrnap/global/yaml.rb +14 -0
- data/lib/wrnap/graphing/r.rb +8 -4
- data/lib/wrnap/package/base.rb +4 -7
- data/lib/wrnap/package/fold.rb +1 -1
- data/lib/wrnap/package/fold_constrained.rb +24 -0
- data/lib/wrnap/package/mfpt.rb +1 -1
- data/lib/wrnap/package/rnabor.rb +2 -2
- data/lib/wrnap/package/varna.rb +4 -3
- data/lib/wrnap/package/xbor.rb +2 -2
- data/lib/wrnap/rna.rb +197 -0
- data/lib/wrnap/rna/box.rb +43 -0
- data/lib/wrnap/rna/constraints.rb +119 -0
- data/lib/wrnap/rna/context.rb +139 -0
- data/lib/wrnap/rna/extensions.rb +102 -0
- data/lib/wrnap/rna/metadata.rb +46 -0
- data/lib/wrnap/rna/motifs.rb +72 -0
- data/lib/wrnap/rna/tree.rb +136 -0
- data/lib/wrnap/rna/wrapper.rb +9 -0
- data/lib/wrnap/version.rb +1 -1
- metadata +14 -9
- data/lib/wrnap/global/rna.rb +0 -190
- data/lib/wrnap/global/rna/context.rb +0 -141
- data/lib/wrnap/global/rna/extensions.rb +0 -104
- data/lib/wrnap/global/rna/helix.rb +0 -36
- data/lib/wrnap/global/rna/metadata.rb +0 -48
- data/lib/wrnap/global/rna/tree.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a49216040e651785e22f2fe010a08ad6ace0800
|
4
|
+
data.tar.gz: beb5164b299e498a0a0c1d59ca579efb723aef46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4262912d96fa147269069032324e0319cc8deb5391dd56376acdea9165c9cc48ddf3d3755c221d9bdc1d503d6bda8840962b5437dc7522a1244571ed089d017
|
7
|
+
data.tar.gz: 29c9eb3b9c20d32c6cdda08a6629fbf5917bfb482a3b76e2ac1f9150ecc54c799320789387a9d97fc4f8b35810fc4877d0e1667fc3166834a548b7f43d0f06eb
|
data/lib/wrnap.rb
CHANGED
@@ -3,7 +3,6 @@ require "benchmark"
|
|
3
3
|
require "set"
|
4
4
|
require "tree"
|
5
5
|
require "shuffle"
|
6
|
-
require "rinruby"
|
7
6
|
require "tempfile"
|
8
7
|
require "bigdecimal"
|
9
8
|
require "rroc"
|
@@ -13,31 +12,30 @@ require "entrez"
|
|
13
12
|
require "active_support/inflector"
|
14
13
|
require "active_support/core_ext/class"
|
15
14
|
|
15
|
+
unless %x[which R].empty?
|
16
|
+
require "rinruby"
|
17
|
+
# RinRuby opens up a connection to R by default, we don't want that. Connections are opened on-demand.
|
18
|
+
begin; R.quit; rescue IOError; end
|
19
|
+
end
|
20
|
+
|
16
21
|
require "wrnap/version"
|
17
|
-
require "wrnap/global/rna/extensions"
|
18
|
-
require "wrnap/global/rna/metadata"
|
19
|
-
require "wrnap/global/rna/tree"
|
20
|
-
require "wrnap/global/rna/helix"
|
21
|
-
require "wrnap/global/rna"
|
22
|
-
require "wrnap/global/rna/context"
|
23
|
-
require "wrnap/global/chainer"
|
24
|
-
require "wrnap/global/entrez"
|
25
|
-
require "wrnap/global/parser"
|
26
|
-
require "wrnap/global/runner"
|
27
|
-
require "wrnap/etl/infernal"
|
28
|
-
require "wrnap/etl/stockholm"
|
29
|
-
require "wrnap/graphing/r"
|
30
|
-
require "wrnap/package/base"
|
31
22
|
|
32
|
-
|
23
|
+
%w|global rna etl graphing|.each do |subfolder|
|
24
|
+
Dir[File.join(File.dirname(__FILE__), "wrnap", subfolder, "*.rb")].each do |file|
|
25
|
+
require file
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
require "wrnap/rna"
|
30
|
+
require "wrnap/package/base"
|
33
31
|
|
34
32
|
module Wrnap
|
35
33
|
RT = 1e-3 * 1.9872041 * (273.15 + 37) # kcal / K / mol @ 37C
|
36
34
|
@debug = true
|
37
35
|
|
38
36
|
module Package
|
39
|
-
Dir[File.join(File.dirname(__FILE__), "wrnap", "package", "*.rb")].reject { |file| file =~ /\/base.rb
|
40
|
-
autoload(File.basename(file, ".rb").camelize.to_sym, "wrnap
|
37
|
+
Dir[File.join(File.dirname(__FILE__), "wrnap", "package", "*.rb")].reject { |file| file =~ /\/base.rb$/ }.each do |file|
|
38
|
+
autoload(File.basename(file, ".rb").camelize.to_sym, File.join("wrnap", "package", File.basename(file, ".rb")))
|
41
39
|
end
|
42
40
|
|
43
41
|
def self.const_missing(name)
|
@@ -51,10 +49,6 @@ module Wrnap
|
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
54
|
-
def self.deserialize(string)
|
55
|
-
YAML.load(File.exist?(string) ? File.read(string) : string)
|
56
|
-
end
|
57
|
-
|
58
52
|
def self.debugger
|
59
53
|
STDERR.puts yield if Wrnap.debug
|
60
54
|
end
|
@@ -68,25 +62,30 @@ module Wrnap
|
|
68
62
|
end
|
69
63
|
end
|
70
64
|
|
71
|
-
#
|
65
|
+
# -----------------------------------------------------------------------------------------------
|
66
|
+
# This dirties up the public namespace, but I use it so many times that I want a shorthand to it.
|
67
|
+
# -----------------------------------------------------------------------------------------------
|
68
|
+
|
69
|
+
class Array; include Wrnap::Rna::Wrnapper; end
|
70
|
+
|
72
71
|
unless defined? RNA
|
73
72
|
def RNA(*args, &block)
|
74
73
|
RNA.from_array(args, &block)
|
75
74
|
end
|
76
|
-
end
|
77
75
|
|
78
|
-
module RNA
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
module RNA
|
77
|
+
def self.load_all(pattern = "*.fa", &block)
|
78
|
+
Wrnap::Rna::Box.load_all(pattern, &block)
|
79
|
+
end
|
82
80
|
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
def self.random(size, *args, &block)
|
82
|
+
RNA.from_array(args.unshift(Wrnap::Rna.generate_sequence(size).seq), &block)
|
83
|
+
end
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
def self.method_missing(name, *args, &block)
|
86
|
+
if "#{name}" =~ /^from_\w+$/
|
87
|
+
Wrnap::Rna.send("init_#{name}", *args, &block)
|
88
|
+
else super end
|
89
|
+
end
|
91
90
|
end
|
92
91
|
end
|
data/lib/wrnap/etl/infernal.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Wrnap
|
2
2
|
module Etl
|
3
3
|
module Infernal
|
4
|
-
NAME_REGEX
|
5
|
-
HIT_SEQUENCE
|
6
|
-
|
4
|
+
NAME_REGEX = />>\s+(\S+)(.*\n){3}.*\s(\d+)\s+(\d+)\s+[\+-].*\n/
|
5
|
+
HIT_SEQUENCE = /^.*\d+\s+(.*)\s+\d+\s*$/
|
6
|
+
HIT_STRUCTURE = /([()<>{}\[\]\-_~,.:]+)\s+CS/
|
7
|
+
LOCAL_END = /\*\[\s*\d+\s*\]\*/
|
7
8
|
|
8
9
|
class << self
|
9
10
|
def parse_file(file)
|
@@ -20,9 +21,9 @@ module Wrnap
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def parse_hit(output)
|
23
|
-
name = if
|
24
|
+
name = if (name_match = output.match(NAME_REGEX))
|
24
25
|
# This is a pretty fancy regex, and there's no guarantee that the data has this info, so let's just test the waters here.
|
25
|
-
_, id, _, seq_from, seq_to, _ =
|
26
|
+
_, id, _, seq_from, seq_to, _ = name_match.to_a
|
26
27
|
"%s %d %d" % [id.split(?|).last, seq_from, seq_to]
|
27
28
|
end
|
28
29
|
|
@@ -33,16 +34,16 @@ module Wrnap
|
|
33
34
|
|
34
35
|
def pull_infernal_hit_sequence(output)
|
35
36
|
# Dots are gaps in Stockholm format, and this uses the Stockholm parser underneath.
|
36
|
-
output.
|
37
|
+
output.scan(HIT_SEQUENCE)[-1][-1].upcase.gsub(?-, ?.)
|
37
38
|
end
|
38
39
|
|
39
40
|
def pull_infernal_hit_structure(output)
|
40
|
-
convert_infernal_to_dot_bracket(output.
|
41
|
+
convert_infernal_to_dot_bracket(output.match(HIT_STRUCTURE)[1])
|
41
42
|
end
|
42
43
|
|
43
44
|
def convert_infernal_to_dot_bracket(structure)
|
44
45
|
# http://jalview-rnasupport.blogspot.com/2010/06/parsing-wuss-notation-of-rna-secondary.html
|
45
|
-
structure.gsub(/[
|
46
|
+
structure.gsub(/[_~,.:]/, ?.).gsub(/[(<{\[]/, ?().gsub(/[)>}\]]/, ?))
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
data/lib/wrnap/etl/stockholm.rb
CHANGED
@@ -19,12 +19,12 @@ module Wrnap
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def balanced_consensus_from_sequence(sequence, structure)
|
22
|
-
Wrnap::
|
22
|
+
Wrnap::Rna.init_from_string(
|
23
23
|
sequence,
|
24
|
-
Wrnap::
|
24
|
+
Wrnap::Rna.structure_from_bp_list(
|
25
25
|
sequence.length,
|
26
26
|
sequence.split(//).zip(structure.split(//)).each_with_index.inject(
|
27
|
-
Wrnap::
|
27
|
+
Wrnap::Rna.base_pairs(structure).map(&:to_a).select { |i, j| Wrnap::Rna::CANONICAL_BASES.include?(Set.new([sequence[i], sequence[j]])) }
|
28
28
|
) do |valid_bases, ((bp, symbol), i)|
|
29
29
|
valid_bases - (bp == ?. && symbol != ?. ? (valid_bases.select { |bps| bps.any? { |j| i == j } }) : [])
|
30
30
|
end
|
@@ -33,14 +33,14 @@ module Wrnap
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def prune_gaps(rna)
|
36
|
-
Wrnap::
|
36
|
+
Wrnap::Rna.init_from_array(rna.seq.split(//).zip(rna.str.split(//)).reject { |nucleotide, _| nucleotide == ?. }.transpose.map(&:join))
|
37
37
|
end
|
38
38
|
|
39
39
|
def theta_filter(rna)
|
40
40
|
# Needs to happen after gap pruning.
|
41
|
-
Wrnap::
|
41
|
+
Wrnap::Rna.init_from_string(
|
42
42
|
rna.seq,
|
43
|
-
Wrnap::
|
43
|
+
Wrnap::Rna.structure_from_bp_list(rna.len, rna.base_pairs.map(&:to_a).select { |i, j| (j - i).abs > 3 })
|
44
44
|
)
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Wrnap
|
2
|
+
module Global
|
3
|
+
module Yaml
|
4
|
+
def serialize(filename = false)
|
5
|
+
cereal = YAML.dump(self)
|
6
|
+
filename ? File.open(filename, ?w) { |file| file.write(cereal) } : cereal
|
7
|
+
end
|
8
|
+
|
9
|
+
def deserialize(string)
|
10
|
+
YAML.load(File.exist?(string) ? File.read(string) : string)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/wrnap/graphing/r.rb
CHANGED
@@ -3,10 +3,14 @@ module Wrnap
|
|
3
3
|
module R
|
4
4
|
class << self
|
5
5
|
def graph(&block)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
if const_defined?(:RinRuby)
|
7
|
+
begin
|
8
|
+
(yield (r_instance = RinRuby.new(false))).tap { r_instance.close }
|
9
|
+
rescue RuntimeError => e
|
10
|
+
raise unless e.message == "Unsupported data type on R's end"
|
11
|
+
end
|
12
|
+
else
|
13
|
+
raise RuntimeError.new("Your system does not appear to have R installed, and thus the RinRuby gem was not loaded.")
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
data/lib/wrnap/package/base.rb
CHANGED
@@ -7,6 +7,7 @@ module Wrnap
|
|
7
7
|
class Base
|
8
8
|
include Wrnap::Global::Runner
|
9
9
|
include Wrnap::Global::Chainer
|
10
|
+
include Wrnap::Global::Yaml
|
10
11
|
|
11
12
|
class_attribute :executable_name
|
12
13
|
self.executable_name = ->(context) { "RNA#{context.class.name.split('::').last.underscore}" }
|
@@ -39,22 +40,18 @@ module Wrnap
|
|
39
40
|
data = [data] unless data.is_a?(Array)
|
40
41
|
|
41
42
|
@data = case data.map(&:class)
|
42
|
-
when [Wrnap::
|
43
|
+
when [Wrnap::Rna], [Wrnap::Rna::Context] then data.first
|
43
44
|
when *(1..3).map { |i| [String] * i } then RNA.from_string(*data)
|
44
45
|
when [Hash] then RNA.from_hash(*data)
|
45
46
|
when [Array] then RNA.from_array(*data)
|
46
|
-
when [NilClass] then Wrnap::
|
47
|
-
else raise TypeError.new("Unsupported Wrnap::
|
47
|
+
when [NilClass] then Wrnap::Rna.placeholder
|
48
|
+
else raise TypeError.new("Unsupported Wrnap::Rna#initialize format: #{data}")
|
48
49
|
end
|
49
50
|
else
|
50
51
|
@data = transform_for_chaining(data)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
def serialize
|
55
|
-
YAML.dump(self)
|
56
|
-
end
|
57
|
-
|
58
55
|
def debugger(&block)
|
59
56
|
self.class.debugger(&block)
|
60
57
|
end
|
data/lib/wrnap/package/fold.rb
CHANGED
@@ -10,7 +10,7 @@ module Wrnap
|
|
10
10
|
def post_process
|
11
11
|
structure = Wrnap::Global::Parser.rnafold_mfe_structure(response)
|
12
12
|
|
13
|
-
unless data.
|
13
|
+
unless data.len == structure.length
|
14
14
|
raise "Sequence: '#{data.seq}'\nStructure: '#{structure}'"
|
15
15
|
else
|
16
16
|
@mfe_rna, @structure, @mfe = RNA.from_string(data.seq, structure), structure, Wrnap::Global::Parser.rnafold_mfe(response)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Wrnap
|
2
|
+
module Package
|
3
|
+
class FoldConstrained < Base
|
4
|
+
self.executable_name = "RNAfold"
|
5
|
+
self.call_with = [:seq, :constraint_mask]
|
6
|
+
self.default_flags = {
|
7
|
+
:C => true,
|
8
|
+
"-noPS" => :empty
|
9
|
+
}
|
10
|
+
|
11
|
+
attr_reader :mfe_rna, :structure, :mfe, :ensemble_energy
|
12
|
+
|
13
|
+
def post_process
|
14
|
+
structure = Wrnap::Global::Parser.rnafold_mfe_structure(response)
|
15
|
+
|
16
|
+
unless data.len == structure.length
|
17
|
+
raise "Sequence: '#{data.seq}'\nStructure: '#{structure}'"
|
18
|
+
else
|
19
|
+
@mfe_rna, @structure, @mfe = RNA.from_string(data.seq, structure), structure, Wrnap::Global::Parser.rnafold_mfe(response)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/wrnap/package/mfpt.rb
CHANGED
@@ -5,7 +5,7 @@ module Wrnap
|
|
5
5
|
module Package
|
6
6
|
class Mfpt < Base
|
7
7
|
self.chains_from = Wrnap::Package::EnergyGrid2d
|
8
|
-
self.default_flags = ->(context, flags) { { X: :empty, H: :empty, N: context.data.
|
8
|
+
self.default_flags = ->(context, flags) { { X: :empty, H: :empty, N: context.data.len, D: context.data.bp_distance, Q: "1e-8" } }
|
9
9
|
# These flags aren't well setup for alternative options at the moment.
|
10
10
|
|
11
11
|
attr_reader :mfpt
|
data/lib/wrnap/package/rnabor.rb
CHANGED
@@ -14,13 +14,13 @@ module Wrnap
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def counts
|
17
|
-
(non_zero_counts = self.class.parse(response).map { |row| BigDecimal.new(row[2]).to_i }) + [0] * (data.
|
17
|
+
(non_zero_counts = self.class.parse(response).map { |row| BigDecimal.new(row[2]).to_i }) + [0] * (data.len - non_zero_counts.length + 1)
|
18
18
|
end
|
19
19
|
|
20
20
|
def distribution(options = {})
|
21
21
|
options = { precision: 4 }.merge(options)
|
22
22
|
|
23
|
-
distribution_before_precision = (non_zero_distribution = non_zero_shells.map { |i| i / partition }) + [0.0] * (data.
|
23
|
+
distribution_before_precision = (non_zero_distribution = non_zero_shells.map { |i| i / partition }) + [0.0] * (data.len - non_zero_distribution.length + 1)
|
24
24
|
distribution_before_precision.map { |value| options[:precision].zero? ? value : (value * 10 ** options[:precision]).truncate / 10.0 ** options[:precision] }
|
25
25
|
end
|
26
26
|
|
data/lib/wrnap/package/varna.rb
CHANGED
@@ -3,15 +3,16 @@ module Wrnap
|
|
3
3
|
class Varna < Base
|
4
4
|
self.executable_name = "java"
|
5
5
|
self.default_flags = ->(context, flags) do
|
6
|
-
{
|
6
|
+
defaults = {
|
7
7
|
sequenceDBN: context.data.seq,
|
8
8
|
structureDBN: context.data.str,
|
9
|
-
title: context.data.name,
|
10
9
|
titleSize: 8,
|
11
10
|
resolution: 2
|
12
11
|
}
|
12
|
+
|
13
|
+
context.data.name ? defaults.merge(title: context.data.name) : defaults
|
13
14
|
end
|
14
|
-
self.quote_flag_params = %w|sequenceDBN structureDBN|
|
15
|
+
self.quote_flag_params = %w|sequenceDBN structureDBN title|
|
15
16
|
|
16
17
|
def run_command(flags)
|
17
18
|
"java fr.orsay.lri.varna.applications.VARNAcmd %s" % stringify_flags(flags)
|
data/lib/wrnap/package/xbor.rb
CHANGED
@@ -28,11 +28,11 @@ module Wrnap
|
|
28
28
|
|
29
29
|
def full_distribution
|
30
30
|
distribution = run.distribution
|
31
|
-
full_distribution = distribution + ([0.0] * ((differnece = data.
|
31
|
+
full_distribution = distribution + ([0.0] * ((differnece = data.len - distribution.length + 1) < 0 ? 0 : differnece))
|
32
32
|
end
|
33
33
|
|
34
34
|
def k_p_points
|
35
|
-
full_distribution.each_with_index.to_a.map(&:reverse)[0..data.
|
35
|
+
full_distribution.each_with_index.to_a.map(&:reverse)[0..data.len]
|
36
36
|
end
|
37
37
|
|
38
38
|
def expected_k
|
data/lib/wrnap/rna.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
module Wrnap
|
2
|
+
class Rna
|
3
|
+
extend Forwardable
|
4
|
+
include Wrnap::Global::Yaml
|
5
|
+
include Wrnap::Rna::Extensions
|
6
|
+
include Wrnap::Rna::Wrnapper
|
7
|
+
include Wrnap::Rna::Metadata
|
8
|
+
include Wrnap::Rna::Motifs
|
9
|
+
include Wrnap::Rna::TreeFunctions
|
10
|
+
include Wrnap::Rna::Constraints
|
11
|
+
|
12
|
+
CANONICAL_BASES = Set.new << Set.new([?G, ?C]) << Set.new([?A, ?U]) << Set.new([?G, ?U])
|
13
|
+
|
14
|
+
attr_accessor :comment
|
15
|
+
attr_reader :sequence, :structure, :second_structure, :metadata
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def init_from_string(sequence, structure = nil, second_structure = nil, comment = nil, &block)
|
19
|
+
new(
|
20
|
+
sequence: sequence,
|
21
|
+
structure: structure,
|
22
|
+
second_structure: second_structure,
|
23
|
+
comment: comment,
|
24
|
+
&block
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def init_from_hash(hash, &block)
|
29
|
+
new(
|
30
|
+
sequence: hash[:sequence] || hash[:seq],
|
31
|
+
structure: hash[:structure] || hash[:str_1] || hash[:str],
|
32
|
+
second_structure: hash[:second_structure] || hash[:str_2],
|
33
|
+
comment: hash[:comment] || hash[:name],
|
34
|
+
&block
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_from_array(array, &block)
|
39
|
+
init_from_string(*array, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def init_from_fasta(string, &block)
|
43
|
+
if File.exist?(string)
|
44
|
+
comment = File.basename(string, string.include?(?.) ? ".%s" % string.split(?.)[-1] : "")
|
45
|
+
string = File.read(string).chomp
|
46
|
+
end
|
47
|
+
|
48
|
+
init_from_string(*string.split(/\n/).reject { |line| line.start_with?(">") }[0, 3], &block).tap do |rna|
|
49
|
+
if (line = string.split(/\n/).first).start_with?(">") && !(file_comment = line.gsub(/^>\s*/, "")).empty?
|
50
|
+
rna.comment = file_comment
|
51
|
+
elsif comment
|
52
|
+
rna.comment = comment
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def init_from_context(*context, coords: {}, rna: {}, &block)
|
58
|
+
Context.init_from_entrez(*context, coords: coords, rna: rna, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def init_from_self(rna, &block)
|
62
|
+
# This happens when you call a Wrnap library function with the output of something like Wrnap::Fold.run(...).mfe
|
63
|
+
new(
|
64
|
+
sequence: rna.sequence,
|
65
|
+
strucutre: rna.structure,
|
66
|
+
second_strucutre: rna.second_structure,
|
67
|
+
comment: rna.comment,
|
68
|
+
&block
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
alias_method :placeholder, :new
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(sequence: "", structure: "", second_structure: "", comment: "", &block)
|
76
|
+
@sequence, @comment, @metadata = (sequence.kind_of?(Rna) ? sequence.seq : sequence).upcase, comment, Metadata::Container.new(self)
|
77
|
+
|
78
|
+
[:structure, :second_structure].each do |structure_symbol|
|
79
|
+
instance_variable_set(
|
80
|
+
:"@#{structure_symbol}",
|
81
|
+
case structure_value = eval("#{structure_symbol}")
|
82
|
+
when :empty then empty_structure
|
83
|
+
when :mfe then RNA(sequence).run(:fold).mfe_rna.structure
|
84
|
+
when String then structure_value
|
85
|
+
when Hash then
|
86
|
+
if structure_value.keys.count > 1
|
87
|
+
Wrnap.debugger { "The following options hash has more than one key. This will probably produce unpredictable results: %s" % structure_value.inspect }
|
88
|
+
end
|
89
|
+
|
90
|
+
RNA(sequence).run(*structure_value.keys, *structure_value.values).mfe_rna.structure
|
91
|
+
end
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
metadata.instance_eval(&block) if block_given?
|
96
|
+
|
97
|
+
if str && len != str.length
|
98
|
+
Wrnap.debugger { "The sequence length (%d) doesn't match the structure length (%d)" % [seq, str].map(&:length) }
|
99
|
+
end
|
100
|
+
|
101
|
+
if str_2 && str_1.length != str_2.length
|
102
|
+
Wrnap.debugger { "The first structure length (%d) doesn't match the second structure length (%d)" % [str_1, str_2].map(&:length) }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
alias :seq :sequence
|
107
|
+
alias :str :structure
|
108
|
+
alias :str_1 :structure
|
109
|
+
alias :str_2 :second_structure
|
110
|
+
alias :name :comment
|
111
|
+
|
112
|
+
def_delegator :@sequence, :length, :len
|
113
|
+
|
114
|
+
def copy_name_from(rna)
|
115
|
+
tap { @comment = rna.name }
|
116
|
+
end
|
117
|
+
|
118
|
+
def empty_structure
|
119
|
+
"." * len
|
120
|
+
end
|
121
|
+
|
122
|
+
alias :empty_str :empty_structure
|
123
|
+
|
124
|
+
def no_structure
|
125
|
+
self.class.init_from_string(seq, nil, nil, name)
|
126
|
+
end
|
127
|
+
|
128
|
+
alias :no_str :no_structure
|
129
|
+
|
130
|
+
def one_structure(structure_1)
|
131
|
+
self.class.init_from_string(seq, structure_1.is_a?(Symbol) ? send(structure_1) : structure_1, nil, name)
|
132
|
+
end
|
133
|
+
|
134
|
+
alias :one_str :one_structure
|
135
|
+
|
136
|
+
def two_structures(structure_1, structure_2)
|
137
|
+
self.class.init_from_string(
|
138
|
+
seq,
|
139
|
+
*[structure_1, structure_2].map { |argument| argument.is_a?(Symbol) ? send(argument) : argument },
|
140
|
+
name
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
alias :two_str :two_structures
|
145
|
+
|
146
|
+
def write_fa!(filename)
|
147
|
+
filename.tap do |filename|
|
148
|
+
File.open(filename, ?w) do |file|
|
149
|
+
file.write("> %s\n" % name) if name
|
150
|
+
file.write("%s\n" % seq) if seq
|
151
|
+
file.write("%s\n" % str_1) if str_1
|
152
|
+
file.write("%s\n" % str_2) if str_2
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def temp_fa_file!
|
158
|
+
write_fa!(Tempfile.new("rna")).path
|
159
|
+
end
|
160
|
+
|
161
|
+
def run(package_name, options = {})
|
162
|
+
Wrnap::Package.lookup(package_name).run(self, options)
|
163
|
+
end
|
164
|
+
|
165
|
+
def eql?(other_rna)
|
166
|
+
self == other_rna
|
167
|
+
end
|
168
|
+
|
169
|
+
def ==(other_rna)
|
170
|
+
other_rna.kind_of?(Wrnap::Rna) ? [seq, str_1, str_2] == [other_rna.seq, other_rna.str_1, other_rna.str_2] : super
|
171
|
+
end
|
172
|
+
|
173
|
+
def method_missing(name, *args, &block)
|
174
|
+
if (name_str = "#{name}") =~ /^run_\w+$/
|
175
|
+
run(name_str.gsub(/^run_/, ""), *args)
|
176
|
+
else super end
|
177
|
+
end
|
178
|
+
|
179
|
+
def pp
|
180
|
+
puts("> %s" % name) if name
|
181
|
+
puts("%s" % seq) if seq
|
182
|
+
puts("%s" % str_1) if str_1
|
183
|
+
puts("%s" % str_2) if str_2
|
184
|
+
puts("%s" % meta.inspect) if meta
|
185
|
+
end
|
186
|
+
|
187
|
+
def inspect
|
188
|
+
"#<RNA: %s>" % [
|
189
|
+
("#{seq[0, 20] + (len > 20 ? '... [%d]' % len : '')}" if seq && !seq.empty?),
|
190
|
+
("#{str_1[0, 20] + (str_1.length > 20 ? ' [%d]' % len : '')}" if str_1 && !str_1.empty?),
|
191
|
+
("#{str_2[0, 20] + (str_2.length > 20 ? ' [%d]' % len : '')}" if str_2 && !str_1.empty?),
|
192
|
+
(md.inspect unless md.nil? || md.empty?),
|
193
|
+
(name ? name : "#{self.class.name}")
|
194
|
+
].compact.join(", ")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|