Class: Bio::Velvet::Graph
- Inherits:
-
Object
- Object
- Bio::Velvet::Graph
- Defined in:
- lib/assembly/depth_first_search.rb,
lib/assembly/oriented_node_trail.rb
Direct Known Subclasses
Defined Under Namespace
Classes: Node, NodedRead, OrientedNodeTrail
Instance Method Summary collapse
-
#depth_first_search(oriented_node) ⇒ Object
Do a depth first search starting at this oriented node, yielding an OrientedNodeTrail at each new node encountered.
-
#neighbours_of(node, first_side) ⇒ Object
Return an Array of OrientedNode objects corresponding to all the nodes that are next in the graph.
-
#neighbours_of_node_id(node_id, first_side) ⇒ Object
Like #neighbours_of, except takes a velvet node id rather than a node object.
Instance Method Details
#depth_first_search(oriented_node) ⇒ Object
Do a depth first search starting at this oriented node, yielding an OrientedNodeTrail at each new node encountered. The new node is the last node in the yielded trail. The result of the yield tells whether this method whether to abandon searching further from this point (false) or keep going (true).
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/assembly/depth_first_search.rb', line 13 def depth_first_search(oriented_node) log = Bio::Log::LoggerPlus['finishm'] discovered_oriented_nodes = Set.new # Traverse through the graph, yielding at each new node current_path = Bio::Velvet::Graph::OrientedNodeTrail.new current_path.add_oriented_node oriented_node stack = DS::Stack.new stack.push current_path # While there is more on the stack while current_path = stack.pop log.debug "Perhaps #{current_path.last}?" if log.debug? if discovered_oriented_nodes.include?(path_to_searchable(current_path)) # Already seen this node, do nothing with it log.debug "Skipping #{current_path.last} since that has already been seen" if log.debug? next else log.debug "That's a new node, #{current_path.last}" if log.debug? # Found a new node for the user to play with discovered_oriented_nodes << path_to_searchable(current_path) continue = yield current_path # prep for next time if required. if continue # Sort node IDs to simplify testing next_nodes = current_path.neighbours_of_last_node(self).sort{|n1, n2| -(n1.node.node_id <=> n2.node.node_id) } next_nodes.each do |n| path = current_path.copy path.add_oriented_node n stack.push path end end end end end |
#neighbours_of(node, first_side) ⇒ Object
Return an Array of OrientedNode objects corresponding to all the nodes that are next in the graph.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/assembly/oriented_node_trail.rb', line 7 def neighbours_of(node, first_side) neighbour_nodes = nil if first_side == OrientedNodeTrail::START_IS_FIRST neighbour_nodes = neighbours_off_end(node) else neighbour_nodes = neighbours_into_start(node) end neighbours_with_orientation = [] neighbour_nodes.each do |neighbour| arcs = get_arcs_by_node node, neighbour # This if statement entered if two nodes are connected twice, # in both directions. Remove one direction as it shouldn't be here if arcs.length > 1 if first_side == OrientedNodeTrail::START_IS_FIRST arcs = arcs.select do |arc| (arc.begin_node_id == node.node_id and arc.begin_node_direction) or (arc.end_node_id == node.node_id and !arc.end_node_direction) end else arcs = arcs.select do |arc| (arc.end_node_id == node.node_id and arc.end_node_direction) or (arc.begin_node_id == node.node_id and !arc.begin_node_direction) end end end # Sometimes, but rarely, two nodes will be joined more than once, for whatever reason arcs.each do |arc| oriented = OrientedNodeTrail::OrientedNode.new oriented.node = neighbour if arc.begin_node_id == arc.end_node_id # A node connecting to itself. Happens rarely. if first_side == OrientedNodeTrail::START_IS_FIRST if arc.begin_node_direction and arc.end_node_direction oriented.first_side = OrientedNodeTrail::START_IS_FIRST elsif arc.begin_node_direction and !arc.end_node_direction oriented.first_side = OrientedNodeTrail::END_IS_FIRST elsif !arc.begin_node_direction and arc.end_node_direction raise "I don't think this is supposed to be possible. Programming error?" elsif !arc.begin_node_direction and !arc.end_node_direction oriented.first_side = OrientedNodeTrail::START_IS_FIRST else raise "programming error" end else # coming from the end of the original node if arc.begin_node_direction and arc.end_node_direction oriented.first_side = OrientedNodeTrail::END_IS_FIRST elsif arc.begin_node_direction and !arc.end_node_direction raise "I don't think this is supposed to be possible. Programming error?" elsif !arc.begin_node_direction and arc.end_node_direction oriented.first_side = OrientedNodeTrail::START_IS_FIRST elsif !arc.begin_node_direction and !arc.end_node_direction oriented.first_side = OrientedNodeTrail::END_IS_FIRST else raise "programming error" end end elsif arc.begin_node_id == neighbour.node_id # connected to a different node, the 1st in the arc's pair if arc.begin_node_direction oriented.first_side = OrientedNodeTrail::END_IS_FIRST else oriented.first_side = OrientedNodeTrail::START_IS_FIRST end elsif arc.end_node_id == neighbour.node_id # connected to a different node, the 2nd in the arc's pair if arc.end_node_direction oriented.first_side = OrientedNodeTrail::START_IS_FIRST else oriented.first_side = OrientedNodeTrail::END_IS_FIRST end end neighbours_with_orientation.push oriented end end return neighbours_with_orientation end |
#neighbours_of_node_id(node_id, first_side) ⇒ Object
Like #neighbours_of, except takes a velvet node id rather than a node object
92 93 94 |
# File 'lib/assembly/oriented_node_trail.rb', line 92 def neighbours_of_node_id(node_id, first_side) neighbours_of(@nodes[node_id], first_side) end |