Module: ViennaRna::RnaExtensions::StructureBasedClassAndInstanceMethods

Defined in:
lib/vienna_rna/modules/rna_extensions.rb

Instance Method Summary collapse

Instance Method Details

#base_pairs(structure) ⇒ Object



65
66
67
68
69
# File 'lib/vienna_rna/modules/rna_extensions.rb', line 65

def base_pairs(structure)
  get_pairings(structure).each_with_index.inject(Set.new) do |set, (j, i)|
    j >= 0 ? set << Set[i, j] : set
  end
end

#bp_distance(structure_1, structure_2) ⇒ Object



38
39
40
41
42
43
44
45
# File 'lib/vienna_rna/modules/rna_extensions.rb', line 38

def bp_distance(structure_1, structure_2)
  # Takes two structures and calculates the distance between them by |symmetric difference(bp_in_a, bp_in_b)|
  raise "The two structures are not the same length" unless structure_1.length == structure_2.length
  
  bp_set_1, bp_set_2 = base_pairs(structure_1), base_pairs(structure_2)
  
  ((bp_set_1 - bp_set_2) + (bp_set_2 - bp_set_1)).count
end

#get_pairings(structure) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/vienna_rna/modules/rna_extensions.rb', line 71

def get_pairings(structure)
	stack = []

  structure.each_char.each_with_index.inject(Array.new(structure.length, -1)) do |array, (symbol, index)|
	  array.tap do      
	    case symbol
	    when "(" then stack.push(index)
	    when ")" then 
	      if stack.empty?
	        raise "Too many ')' in '#{structure}'"
	      else
	        stack.pop.tap do |opening|
	          array[opening] = index
	          array[index]   = opening
	        end
	      end
	    end
	  end
	end.tap do
	  raise "Too many '(' in '#{structure}'" unless stack.empty?
	end
end

#max_bp_distance(structure) ⇒ Object



61
62
63
# File 'lib/vienna_rna/modules/rna_extensions.rb', line 61

def max_bp_distance(structure)
  base_pairs(structure).count + ((structure.length - 3) / 2.0).floor
end

#symmetric_bp_distance(structure_1, structure_2) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/vienna_rna/modules/rna_extensions.rb', line 47

def symmetric_bp_distance(structure_1, structure_2)
  # Takes two structures and calculates the distance between them by: sum { ((x_j - x_i) - (y_j - y_i)).abs }
  raise "The two structures are not the same length" unless structure_1.length == structure_2.length
  
  bp_dist = ->(array, i) { array[i] == -1 ? 0 : array[i] - i }
  
  structure_1_pairings = get_pairings(structure_1)
  structure_2_pairings = get_pairings(structure_2)
  
  structure_1.length.times.inject(0) do |distance, i|
    distance + (bp_dist[structure_1_pairings, i] - bp_dist[structure_2_pairings, i]).abs
  end
end