Class: Bio::Assembly::ABVisualiser

Inherits:
Object
  • Object
show all
Includes:
FinishM::Logging
Defined in:
lib/assembly/a_b_visualiser.rb

Defined Under Namespace

Classes: SimplifiedGraph

Instance Method Summary collapse

Methods included from FinishM::Logging

#log

Instance Method Details

#graphviz(graph, options = {}) ⇒ Object

Visualise a (velvet) graph, as a graphviz object

Possible options: :start_kmers: list of kmers to denote the start node(s) :end_kmers: list of kmers to denote the end node(s) :start_node_id: ID of node to mark as a start :end_node_id:ID of node to mark as a end :start_node_ids: array of node IDs to mark as a start :end_node_ids:array of node IDs to mark as a end :coverage_cutoff: ignore nodes with less coverage than this cutoff :digraph: output as a digraph (default true, else output undirected graph) :nodes: an Enumerable of nodes to be visualised. :node_id_to_nickname: add these names to the node descriptions. Hash of integer node id to String. :paired_nodes_hash: a hash of node_id to Enumerable of node_ids where there is paired-end connections



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/assembly/a_b_visualiser.rb', line 32

def graphviz(graph, options={})
  opts = {}
  opts[:type] = :digraph unless options[:digraph] == false
  opts[:overlap] = :scale
  graphviz = GraphViz.new(:G, opts)

  nodes_to_explore = Set.new(options[:nodes].to_a)
  nodes_to_explore ||= Set.new(graph.nodes)

  # Add all the nodes
  blacklisted_node_ids = Set.new
  log.debug "Converting nodes to GraphViz format"
  nodes_to_explore.each do |node|
    cov = node.coverage
    if options[:coverage_cutoff] and cov < options[:coverage_cutoff] and !cov.nil?
      blacklisted_node_ids.add node.node_id
    else
      cov_string = cov.nil? ? '' : cov.round
      label = "n#{node.node_id}_length#{node.ends_of_kmers_of_node.length}_coverage#{cov_string}"
      if options[:node_id_to_nickname] and options[:node_id_to_nickname].key?(node.node_id)
        label += ' ' + options[:node_id_to_nickname][node.node_id]
      end
      mods = {
        :label => label,
      }
      includes_start = false
      includes_end = false
      if options[:start_kmers]
        includes_start = node.includes_kmers?(options[:start_kmers])
      end
      if options[:end_kmers]
        includes_end = node.includes_kmers?(options[:end_kmers])
      end
      if options[:start_node_id]
        includes_start = true if node.node_id == options[:start_node_id]
      end
      if options[:end_node_id]
        includes_end = true if node.node_id == options[:end_node_id]
      end
      if options[:start_node_ids]
        includes_start = true if options[:start_node_ids].include? node.node_id
      end
      if options[:end_node_ids]
        includes_end = true if options[:end_node_ids].include? node.node_id
      end

      if includes_start and includes_end
        log.warn "Start and end kmers detected in the same node!"
      elsif includes_start
        mods[:color] = "red"
      elsif includes_end
        mods[:color] = "green"
      end

      graphviz.add_nodes node.node_id.to_s, mods
    end
  end

  # Add all the edges
  arcs_of_interest = graph.arcs
  if options[:nodes]
    arcs_of_interest = Set.new
    nodes_to_explore.each do |node|
      graph.arcs.get_arcs_by_node_id(node.node_id).each do |arc|
        arcs_of_interest << arc
      end
    end
  end

  log.info "Converting #{arcs_of_interest.length} arcs to GraphViz format"
  arcs_of_interest.each do |arc|
    # Add unless the node has been blacklisted
    unless blacklisted_node_ids.include? arc.begin_node_id or
      blacklisted_node_ids.include? arc.end_node_id or
      !nodes_to_explore.include?(graph.nodes[arc.begin_node_id]) or
      !nodes_to_explore.include?(graph.nodes[arc.end_node_id])

      # Direction of the arrows, to denote connection to beginning of node (connects to start = in-arrow-head to node on output graph)
      if arc.connects_end_to_beginning?(arc.begin_node_id, arc.end_node_id)
        graphviz.add_edges arc.begin_node_id.to_s, arc.end_node_id.to_s
      elsif  arc.connects_end_to_end?(arc.begin_node_id, arc.end_node_id)
        graphviz.add_edges arc.begin_node_id.to_s, arc.end_node_id.to_s, {:dir => "none"}
      elsif  arc.connects_beginning_to_beginning?(arc.begin_node_id, arc.end_node_id)
        graphviz.add_edges arc.begin_node_id.to_s, arc.end_node_id.to_s, {:dir => "both"}
      elsif  arc.connects_beginning_to_end?(arc.begin_node_id, arc.end_node_id)
        graphviz.add_edges arc.end_node_id.to_s, arc.begin_node_id.to_s
      end
    end
  end

  # Add paired_nodes_hash pairs
  unless options[:paired_nodes_hash].nil?
    # Create a list of arc node pairs for len calculation
    arc_pairs = arcs_of_interest.collect do |arc|
      [arc.begin_node_id, arc.end_node_id].sort
    end
    directly_connected_node_pairs = Set.new(arc_pairs)

    # Keep track of pairs so multiple arcs are not drawn e.g. node1 => node2 and node2=>node1
    pairs_added = Set.new
    log.info "Adding paired-end linkages to GraphViz format.."
    options[:paired_nodes_hash].each do |node1_id, connected_node_ids|
      connected_node_ids.each do |node2_id|
        next if node1_id == node2_id #skip within-node connections
        sorted = [node1_id, node2_id].sort #sort so only a single connection is shown
        unless pairs_added.include?(sorted) or
          !nodes_to_explore.include?(graph.nodes[node1_id]) or
          !nodes_to_explore.include?(graph.nodes[node2_id]) or
          directly_connected_node_pairs.include?([node1_id, node2_id].sort)

          graphviz.add_edges sorted[0].to_s, sorted[1].to_s, {:color => "grey", :dir => "none", :style => 'dashed'}
          pairs_added << sorted
        end
      end
    end
  end

  return graphviz
end