/** Assemble overlapping paths. */ static void assembleOverlappingPaths(Graph& g, Paths& paths, vector<string>& pathIDs) { if (paths.empty()) return; // Find overlapping paths. Overlaps overlaps = findOverlaps(g, paths); addPathOverlapEdges(g, paths, pathIDs, overlaps); // Create a property map of path overlaps. OverlapMap overlapMap; for (Overlaps::const_iterator it = overlaps.begin(); it != overlaps.end(); ++it) overlapMap.insert(OverlapMap::value_type( OverlapMap::key_type( it->source.descriptor(), it->target.descriptor()), it->overlap)); // Assemble unambiguously overlapping paths. Paths merges; assemble_if(g, back_inserter(merges), IsPathOverlap(g, overlapMap, IsPositive<Graph>(g))); // Merge overlapping paths. g_contigNames.unlock(); assert(!pathIDs.empty()); setNextContigName(pathIDs.back()); for (Paths::const_iterator it = merges.begin(); it != merges.end(); ++it) { string name = createContigName(); if (opt::verbose > 0) cerr << name << '\t' << *it << '\n'; Vertex u(paths.size(), false); put(vertex_name, g, u.descriptor(), name); pathIDs.push_back(name); paths.push_back(mergePaths(paths, overlapMap, *it)); // Remove the merged paths. for (ContigPath::const_iterator it2 = it->begin(); it2 != it->end(); ++it2) { if (isPath(*it2)) paths[it2->id() - Vertex::s_offset].clear(); } } g_contigNames.lock(); }
/** Add the path overlap edges to the specified graph. */ static void addPathOverlapEdges(Graph& g, const Paths& paths, const vector<string>& pathIDs, const Overlaps& overlaps) { typedef graph_traits<Graph>::vertex_descriptor V; const bool allowParallelEdge = opt::mode == opt::ASSEMBLE; // Add the path vertices. g_contigNames.unlock(); for (Paths::const_iterator it = paths.begin(); it != paths.end(); ++it) { const ContigPath& path = *it; const string& id = pathIDs[it - paths.begin()]; if (!path.empty()) { V u = merge(g, path.begin(), path.end()); put(vertex_name, g, u, id); } } g_contigNames.lock(); // Remove the single-end contigs that are in paths. for (Paths::const_iterator it = paths.begin(); it != paths.end(); ++it) remove_vertex_if(g, it->begin(), it->end(), not1(std::mem_fun_ref(&ContigNode::ambiguous))); // Add the path edges. for (Overlaps::const_iterator it = overlaps.begin(); it != overlaps.end(); ++it) { V u = it->source.descriptor(); V v = it->target.descriptor(); if (allowParallelEdge || !edge(u, v, g).second) add_edge(u, v, it->distance, static_cast<DG&>(g)); else if (opt::verbose > 0) cerr << "ambiguous overlap: " << get(vertex_name, g, u) << " -> " << get(vertex_name, g, v) << '\n'; } }