Class: Wrnap::Rna::TreePlanter

Inherits:
Object
  • Object
show all
Defined in:
lib/wrnap/rna/tree.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rna, tree = false) ⇒ TreePlanter

Returns a new instance of TreePlanter.



103
104
105
106
# File 'lib/wrnap/rna/tree.rb', line 103

def initialize(rna, tree = false)
  @rna  = rna
  @root = tree || build_tree(rna.collapsed_helices)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



203
204
205
206
207
# File 'lib/wrnap/rna/tree.rb', line 203

def method_missing(name, *args, &block)
  if name.to_s =~ TreeStem::STEM_NOTATION_REGEX
    root.send(name, *args, &block)
  else super end
end

Instance Attribute Details

#rnaObject (readonly)

Returns the value of attribute rna.



101
102
103
# File 'lib/wrnap/rna/tree.rb', line 101

def rna
  @rna
end

#rootObject (readonly)

Returns the value of attribute root.



101
102
103
# File 'lib/wrnap/rna/tree.rb', line 101

def root
  @root
end

Instance Method Details

#add_node(subtree, node) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/wrnap/rna/tree.rb', line 126

def add_node(subtree, node)
  # This function has an implicit, *very important* expectation that nodes are added in a depth-first, preorder traversal fashion.
  # What this means is that given a tree containing two sibling nodes (i, j), (k, l), you can't later add another node (m, n) which
  # makes (i, j), (k, l) into a multiloop. (m, n) *must* be added before any of it's children for the resulting structure to be accurate.

  # Case 1: the tree is empty.
  if subtree.is_root? && subtree.size == 1
    subtree << node
  # Case 2: the node to add is after the current stem.
  elsif node.i > subtree.j
    # It's a sibling, pop up until we're at its parent node.
    subtree = subtree.parent until subtree.is_root? || subtree.j > node.i
    node.tap { subtree << node }
  # Case 3: the node to add is within the current stem.
  elsif node.j < subtree.j
    # Going deeper.
    subtree << node
  end
end

#build_tree(helices) ⇒ Object



108
109
110
111
112
# File 'lib/wrnap/rna/tree.rb', line 108

def build_tree(helices)
  helices.inject(TreeStem.new(:root, rna)) do |tree, helix|
    add_node(tree, TreeStem.new(helix.name, helix))
  end.root
end

#coalesceObject



146
147
148
# File 'lib/wrnap/rna/tree.rb', line 146

def coalesce
  self.class.new(rna, root.dup).tap { |tree| tree.merge_interior_loops! }
end

#coalesce!Object



150
151
152
# File 'lib/wrnap/rna/tree.rb', line 150

def coalesce!
  tap { merge_interior_loops! }
end

#depth_signatureObject



189
190
191
# File 'lib/wrnap/rna/tree.rb', line 189

def depth_signature
  root.map(&:node_depth)
end

#extend_interior_loops!Object



162
163
164
165
166
167
168
# File 'lib/wrnap/rna/tree.rb', line 162

def extend_interior_loops!
  handle_interior_loops! do |node, child|
    node.content.merge!(child.content)
    child.remove_from_parent!
    child.children.each { |grandchild| node.add(grandchild) }
  end
end

#extend_tree(*helices) ⇒ Object



114
115
116
# File 'lib/wrnap/rna/tree.rb', line 114

def extend_tree(*helices)
  self.class.new(rna, rebuild_tree(helices))
end

#extend_tree!(*helices) ⇒ Object



118
119
120
# File 'lib/wrnap/rna/tree.rb', line 118

def extend_tree!(*helices)
  tap { @root = rebuild_tree(helices) }
end

#fuseObject



154
155
156
# File 'lib/wrnap/rna/tree.rb', line 154

def fuse
  self.class.new(rna, root.dup).tap { |tree| tree.extend_interior_loops! }
end

#fuse!Object



158
159
160
# File 'lib/wrnap/rna/tree.rb', line 158

def fuse!
  tap { extend_interior_loops! }
end

#handle_interior_loops!(&block) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/wrnap/rna/tree.rb', line 177

def handle_interior_loops!(&block)
  root.tap do
    root.postorder_traversal do |node|
      if node.children.count == 1 && !node.is_root?              
        yield(node, node.children.first)
      end
    end
    
    extend_tree!
  end
end

#inspectObject Also known as: to_s



197
198
199
# File 'lib/wrnap/rna/tree.rb', line 197

def inspect
  "#<TreePlanter: %s>" % depth_signature.inspect
end

#merge_interior_loops!Object



170
171
172
173
174
175
# File 'lib/wrnap/rna/tree.rb', line 170

def merge_interior_loops!
  handle_interior_loops! do |node, child|
    node.parent.add(child)
    node.remove_from_parent!
  end
end

#ppObject



193
194
195
# File 'lib/wrnap/rna/tree.rb', line 193

def pp
  root.print_tree and nil
end

#rebuild_tree(helices) ⇒ Object



122
123
124
# File 'lib/wrnap/rna/tree.rb', line 122

def rebuild_tree(helices)
  build_tree((root.map(&:content).select { |helix| helix.is_a?(Helix) } + helices.flatten).sort_by(&:i))
end