Class: Wrnap::Rna::TreePlanter

Inherits:
Object
  • Object
show all
Includes:
MetaMissing
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.



111
112
113
114
# File 'lib/wrnap/rna/tree.rb', line 111

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

Instance Attribute Details

#rnaObject (readonly)

Returns the value of attribute rna.



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

def rna
  @rna
end

#rootObject (readonly)

Returns the value of attribute root.



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

def root
  @root
end

Instance Method Details

#add_node(subtree, node) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/wrnap/rna/tree.rb', line 134

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



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

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

RNA.from_fa(“xpt.fa”).trunk.pp

  • root

|—+ (5..12, 66..73 [8]) | |—> (18..22, 30..34 [5]) | —> (45..50, 58..63 [6]) |— (75..78, 102..105 [4]) <- | —> (80..86, 95..101 [7]) <- —> (112..125, 133..146 [14])

RNA.from_fa(“xpt.fa”).trunk.coalesce.pp

  • root

|—+ (5..12, 66..73 [8]) | |—> (18..22, 30..34 [5]) | —> (45..50, 58..63 [6]) |—> (80..86, 95..101 [7]) <- —> (112..125, 133..146 [14])



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

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

#coalesce!Object



175
176
177
# File 'lib/wrnap/rna/tree.rb', line 175

def coalesce!
  tap { merge_interior_loops! }
end

#depth_signatureObject



230
231
232
# File 'lib/wrnap/rna/tree.rb', line 230

def depth_signature
  root.map(&:node_depth)
end

#extend_interior_loops!Object



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

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



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

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

#extend_tree!(*helices) ⇒ Object



126
127
128
# File 'lib/wrnap/rna/tree.rb', line 126

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

#fuseObject

RNA.from_fa(“xpt.fa”).trunk.pp

  • root

|—+ (5..12, 66..73 [8]) | |—> (18..22, 30..34 [5]) | —> (45..50, 58..63 [6]) |— (75..78, 102..105 [4]) <- | —> (80..86, 95..101 [7]) <- —> (112..125, 133..146 [14])

RNA.from_fa(“xpt.fa”).trunk.fuse.pp

  • root

|—+ (5..12, 66..73 [8]) | |—> (18..22, 30..34 [5]) | —> (45..50, 58..63 [6]) |—> (75..86, 94..105 [12]) <- —> (112..125, 133..146 [14])



195
196
197
# File 'lib/wrnap/rna/tree.rb', line 195

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

#fuse!Object



199
200
201
# File 'lib/wrnap/rna/tree.rb', line 199

def fuse!
  tap { extend_interior_loops! }
end

#handle_interior_loops!(&block) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
# File 'lib/wrnap/rna/tree.rb', line 218

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

#merge_interior_loops!Object



211
212
213
214
215
216
# File 'lib/wrnap/rna/tree.rb', line 211

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

#ppObject



234
235
236
# File 'lib/wrnap/rna/tree.rb', line 234

def pp
  root.print_tree and nil
end

#rebuild_tree(helices) ⇒ Object



130
131
132
# File 'lib/wrnap/rna/tree.rb', line 130

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