static inline vector<const AlignmentColumn*> getPredecessorColumns(BoostGraph& g, Vertex v, const AlignmentColumnMap& alignmentColumnForVertex) { vector<const AlignmentColumn*> predecessorColumns; const AlignmentColumn* predCol; foreach (Edge e, in_edges(v, g)) { Vertex u = source(e, g); predCol = alignmentColumnForVertex.at(u); assert(predCol != NULL); predecessorColumns.push_back(predCol); }
void PoaGraphImpl::tracebackAndThread(std::string sequence, const AlignmentColumnMap& alignmentColumnForVertex, AlignMode alignMode, std::vector<Vertex>* outputPath) { const int I = sequence.length(); // perform traceback from (I,$), threading the new sequence into // the graph as we go. int i = I; const AlignmentColumn* curCol; VD v = null_vertex, forkVertex = null_vertex; VD u = exitVertex_; VD startSpanVertex; VD endSpanVertex = alignmentColumnForVertex.at(exitVertex_)->PreviousVertex[I]; if (outputPath) { outputPath->resize(I); std::fill(outputPath->begin(), outputPath->end(), (size_t)-1); } #define READPOS (i - 1) #define VERTEX_ON_PATH(readPos, v) \ if (outputPath) { \ (*outputPath)[(readPos)] = externalize(v); \ } while (!(u == enterVertex_ && i == 0)) { // u -> v // u: current vertex // v: vertex last visited in traceback (could be == u) // forkVertex: the vertex that will be the target of a new edge Vertex uExt = this->externalize(u); // DEBUGGING Vertex vExt = this->externalize(v); // DEBUGGING curCol = alignmentColumnForVertex.at(u); assert(curCol != NULL); PoaNode& curNodeInfo = vertexInfoMap_[u]; VD prevVertex = curCol->PreviousVertex[i]; MoveType reachingMove = curCol->ReachingMove[i]; if (reachingMove == StartMove) { assert(v != null_vertex); if (forkVertex == null_vertex) { forkVertex = v; } // In local model thread read bases, adjusting i (should stop at 0) while (i > 0) { assert(alignMode == AlignMode::LOCAL); VD newForkVertex = addVertex(sequence[READPOS]); add_edge(newForkVertex, forkVertex, g_); VERTEX_ON_PATH(READPOS, newForkVertex); forkVertex = newForkVertex; i--; } } else if (reachingMove == EndMove) { assert(forkVertex == null_vertex && u == exitVertex_ && v == null_vertex); forkVertex = exitVertex_; if (alignMode == AlignMode::LOCAL) { // Find the row # we are coming from, walk // back to there, threading read bases onto // graph via forkVertex, adjusting i. const AlignmentColumn* prevCol = alignmentColumnForVertex.at(prevVertex); int prevRow = ArgMax(prevCol->Score); while (i > static_cast<int>(prevRow)) { VD newForkVertex = addVertex(sequence[READPOS]); add_edge(newForkVertex, forkVertex, g_); VERTEX_ON_PATH(READPOS, newForkVertex); forkVertex = newForkVertex; i--; } } } else if (reachingMove == MatchMove) { VERTEX_ON_PATH(READPOS, u); // if there is an extant forkVertex, join it if (forkVertex != null_vertex) { add_edge(u, forkVertex, g_); forkVertex = null_vertex; } // add to existing node curNodeInfo.Reads++; i--; } else if (reachingMove == DeleteMove) { if (forkVertex == null_vertex) { forkVertex = v; } } else if (reachingMove == ExtraMove || reachingMove == MismatchMove) { // begin a new arc with this read base VD newForkVertex = addVertex(sequence[READPOS]); if (forkVertex == null_vertex) { forkVertex = v; } add_edge(newForkVertex, forkVertex, g_); VERTEX_ON_PATH(READPOS, newForkVertex); forkVertex = newForkVertex; i--; } else { throw std::runtime_error("unreachable"); } v = u; u = prevVertex; } startSpanVertex = v; // if there is an extant forkVertex, join it to enterVertex if (forkVertex != null_vertex) { add_edge(enterVertex_, forkVertex, g_); startSpanVertex = forkVertex; forkVertex = null_vertex; } if (startSpanVertex != exitVertex_) { tagSpan(startSpanVertex, endSpanVertex); } // all filled in? assert(outputPath == NULL || std::find(outputPath->begin(), outputPath->end(), ((size_t)-1)) == outputPath->end()); #undef READPOS #undef VERTEX_ON_PATH }