Beispiel #1
0
 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
}