/** Pop the specified bubble if it is simple, otherwise scaffold. */ static void popOrScaffoldBubble(Graph& g, const Bubble& bubble) { #pragma omp atomic g_count.bubbles++; if (!popSimpleBubble(&g, bubble.front()) && opt::scaffold) { #pragma omp atomic g_count.scaffold++; scaffoldBubble(g, bubble); } }
/** Scaffold over the bubble between vertices u and w. * Add an edge (u,w) with the distance property set to the length of * the largest branch of the bubble. */ static void scaffoldBubble(Graph& g, const Bubble& bubble) { typedef graph_traits<Graph>::vertex_descriptor V; assert(opt::scaffold); assert(bubble.size() > 2); V u = bubble.front(), w = bubble.back(); if (edge(u, w, g).second) { // Already scaffolded. return; } assert(isBubble(g, bubble.begin(), bubble.end())); assert(bubble.size() > 2); size_t n = bubble.size() - 2; g_popped.reserve(g_popped.size() + n); for (Bubble::const_iterator it = bubble.begin() + 1; it != bubble.end() - 1; ++it) g_popped.push_back(it->contigIndex()); add_edge(u, w, max(longestPath(g, bubble), 1), g); }
/** Return the length of the longest path through the bubble. */ static int longestPath(const Graph& g, const Bubble& topo) { typedef graph_traits<Graph>::edge_descriptor E; typedef graph_traits<Graph>::out_edge_iterator Eit; typedef graph_traits<Graph>::vertex_descriptor V; EdgeWeightMap<Graph> weight(g); map<ContigNode, int> distance; distance[topo.front()] = 0; for (Bubble::const_iterator it = topo.begin(); it != topo.end(); ++it) { V u = *it; Eit eit, elast; for (tie(eit, elast) = out_edges(u, g); eit != elast; ++eit) { E e = *eit; V v = target(e, g); distance[v] = max(distance[v], distance[u] + weight[e]); } } V v = topo.back(); return distance[v] - g[v].length; }