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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a389b503ea7faf4bfb02eb55a8ec8d5802e4b9b
4
- data.tar.gz: 3bcbe5611e4c409f7aa3c1f4dd730fde6ff9e24d
3
+ metadata.gz: 5a49216040e651785e22f2fe010a08ad6ace0800
4
+ data.tar.gz: beb5164b299e498a0a0c1d59ca579efb723aef46
5
5
  SHA512:
6
- metadata.gz: d3d2dcd9a391a7ef41c0e76562132168847a0968c95cb2fc8b359349cffed8445677e0699d5758ec779b144676750304b9b8103cc616154a3b8ca5afd0c9069e
7
- data.tar.gz: b34295c88b411d8195fbff6ef60ad863a9607a927c5e2eb94e8f326c76932c5ffd2d37cbc4919e56083e0d08b6fb76e7f6fb6a6d38ac70ee9ae45cf3c696204e
6
+ metadata.gz: b4262912d96fa147269069032324e0319cc8deb5391dd56376acdea9165c9cc48ddf3d3755c221d9bdc1d503d6bda8840962b5437dc7522a1244571ed089d017
7
+ data.tar.gz: 29c9eb3b9c20d32c6cdda08a6629fbf5917bfb482a3b76e2ac1f9150ecc54c799320789387a9d97fc4f8b35810fc4877d0e1667fc3166834a548b7f43d0f06eb
@@ -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
- begin; R.quit; rescue IOError; end
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/ }.each do |file|
40
- autoload(File.basename(file, ".rb").camelize.to_sym, "wrnap/package/#{File.basename(file, '.rb')}")
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
- # This dirties up the public namespace, but I use it so many times that I want a shorthand to it
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
- def self.load_all(pattern = "*.fa", &block)
80
- Dir[File.directory?(pattern) ? pattern + "/*.fa" : pattern].map { |file| RNA.from_fasta(file, &block) }
81
- end
76
+ module RNA
77
+ def self.load_all(pattern = "*.fa", &block)
78
+ Wrnap::Rna::Box.load_all(pattern, &block)
79
+ end
82
80
 
83
- def self.random(size, *args, &block)
84
- RNA.from_array(args.unshift(Wrnap::Global::Rna.generate_sequence(size).seq), &block)
85
- end
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
- def self.method_missing(name, *args, &block)
88
- if "#{name}" =~ /^from_\w+$/
89
- Wrnap::Global::Rna.send("init_#{name}", *args, &block)
90
- else super end
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
@@ -1,9 +1,10 @@
1
1
  module Wrnap
2
2
  module Etl
3
3
  module Infernal
4
- NAME_REGEX = />>\s+(\S+)(.*\n){3}.*\s(\d+)\s+(\d+)\s+[\+-].*\n/
5
- HIT_SEQUENCE = /^.*\d+\s+(.*)\s+\d+\s*$/
6
- LOCAL_END = /\*\[\s*\d+\s*\]\*/
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 output =~ NAME_REGEX
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, _ = output.match(NAME_REGEX).to_a
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.split(?\n).select { |line| line =~ HIT_SEQUENCE }.last.match(HIT_SEQUENCE)[1].upcase.gsub(?-, ?.)
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.split(?\n).find { |line| line =~ /CS\s*$/ }.gsub(/\s+CS\s*$/, "").strip)
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(/[:,_-]/, ?.).gsub(/[<\[\{]/, ?().gsub(/[>\]\}]/, ?))
46
+ structure.gsub(/[_~,.:]/, ?.).gsub(/[(<{\[]/, ?().gsub(/[)>}\]]/, ?))
46
47
  end
47
48
  end
48
49
  end
@@ -19,12 +19,12 @@ module Wrnap
19
19
  end
20
20
 
21
21
  def balanced_consensus_from_sequence(sequence, structure)
22
- Wrnap::Global::Rna.init_from_string(
22
+ Wrnap::Rna.init_from_string(
23
23
  sequence,
24
- Wrnap::Global::Rna.structure_from_bp_list(
24
+ Wrnap::Rna.structure_from_bp_list(
25
25
  sequence.length,
26
26
  sequence.split(//).zip(structure.split(//)).each_with_index.inject(
27
- Wrnap::Global::Rna.base_pairs(structure).map(&:to_a).select { |i, j| Wrnap::Global::Rna::CANONICAL_BASES.include?(Set.new([sequence[i], sequence[j]])) }
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::Global::Rna.init_from_array(rna.seq.split(//).zip(rna.str.split(//)).reject { |nucleotide, _| nucleotide == ?. }.transpose.map(&:join))
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::Global::Rna.init_from_string(
41
+ Wrnap::Rna.init_from_string(
42
42
  rna.seq,
43
- Wrnap::Global::Rna.structure_from_bp_list(rna.seq.length, rna.base_pairs.map(&:to_a).select { |i, j| (j - i).abs > 3 })
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
@@ -3,10 +3,14 @@ module Wrnap
3
3
  module R
4
4
  class << self
5
5
  def graph(&block)
6
- begin
7
- (yield (r_instance = RinRuby.new)).tap { r_instance.close }
8
- rescue RuntimeError => e
9
- raise unless e.message == "Unsupported data type on R's end"
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
 
@@ -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::Global::Rna], [Wrnap::Global::Rna::Context] then data.first
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::Global::Rna.placeholder
47
- else raise TypeError.new("Unsupported Wrnap::Global::Rna#initialize format: #{data}")
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
@@ -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.seq.length == structure.length
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
@@ -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.seq.length, D: context.data.bp_distance, Q: "1e-8" } }
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
@@ -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.seq.length - non_zero_counts.length + 1)
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.seq.length - non_zero_distribution.length + 1)
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
 
@@ -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)
@@ -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.seq.length - distribution.length + 1) < 0 ? 0 : differnece))
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.seq.length]
35
+ full_distribution.each_with_index.to_a.map(&:reverse)[0..data.len]
36
36
  end
37
37
 
38
38
  def expected_k
@@ -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