wrnap 0.12.2 → 1.0.1

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.
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