static void concatenateLongReads(Node * node, Node * candidate, Graph * graph) { PassageMarkerI marker, tmpMarker; // Passage marker management in node: for (marker = getMarker(node); marker != NULL_IDX; marker = getNextInNode(marker)) { if (!goesToNode(marker, candidate)) incrementFinishOffset(marker, getNodeLength(candidate)); } // Swapping new born passageMarkers from candidate to node for (marker = getMarker(candidate); marker != NULL_IDX; marker = tmpMarker) { tmpMarker = getNextInNode(marker); if (!comesFromNode(marker, node)) { extractPassageMarker(marker); incrementStartOffset(marker, getNodeLength(node)); transposePassageMarker(marker, node); incrementFinishOffset(getTwinMarker(marker), getNodeLength(node)); } else { reconnectPassageMarker(marker, node, &tmpMarker); } } }
static boolean comesFromNode(PassageMarkerI marker, Node * node) { Node *source = getNode(getTwinMarker(marker)); Node *target = getTwinNode(node); PassageMarkerI current; for (current = getNextInSequence(getTwinMarker(marker)); current != NULL_IDX; current = getNextInSequence(current)) { if (getNode(current) == target) return true; else if (getNode(current) == source) continue; else if (getUniqueness(getNode(current))) return false; } return false; }
static void trimLongReadTips() { IDnum index; Node *node; PassageMarkerI marker, next; velvetLog("Trimming read tips\n"); for (index = 1; index <= nodeCount(graph); index++) { node = getNodeInGraph(graph, index); if (getUniqueness(node)) continue; for (marker = getMarker(node); marker != NULL_IDX; marker = next) { next = getNextInNode(marker); if (!isInitial(marker) && !isTerminal(marker)) continue; if (isTerminal(marker)) marker = getTwinMarker(marker); while (!getUniqueness(getNode(marker))) { if (next != NULL_IDX && (marker == next || marker == getTwinMarker(next))) next = getNextInNode(next); if (getNextInSequence(marker) != NULL_IDX) { marker = getNextInSequence(marker); destroyPassageMarker (getPreviousInSequence (marker)); } else { destroyPassageMarker(marker); break; } } } } }
static void admitGroupies(Node * source, Node * bypass) { PassageMarkerI marker, tmpMarker; for (marker = getMarker(source); marker != NULL_IDX; marker = tmpMarker) { tmpMarker = getNextInNode(marker); extractPassageMarker(marker); transposePassageMarker(marker, bypass); incrementFinishOffset(getTwinMarker(marker), getNodeLength(bypass)); } }
static void reconnectPassageMarker(PassageMarkerI marker, Node * node, PassageMarkerI * ptr) { PassageMarkerI current; PassageMarkerI next = getNextInSequence(marker); PassageMarkerI tmpMarker; for (current = marker; getNode(current) != node; current = getPreviousInSequence(current)); setPreviousInSequence(current, next); concatenatePassageMarkers(current, marker); // Removing node and all intermediaries while (marker != current) { tmpMarker = getPreviousInSequence(marker); if (*ptr == marker || *ptr == getTwinMarker(marker)) *ptr = getNextInNode(*ptr); setNextInSequence(marker, NULL_IDX); setPreviousInSequence(NULL_IDX, marker); destroyPassageMarker(marker); marker = tmpMarker; } }
// Replaces two consecutive nodes into a single equivalent node // The extra memory is freed void concatenateNodes(Node * nodeA, Node * nodeB, Graph * graph) { PassageMarkerI marker, tmpMarker; Node *twinA = getTwinNode(nodeA); Node *twinB = getTwinNode(nodeB); Arc *arc; Category cat; // Arc management: // Freeing useless arcs while (getArc(nodeA) != NULL) destroyArc(getArc(nodeA), graph); // Correct arcs for (arc = getArc(nodeB); arc != NULL; arc = getNextArc(arc)) { if (getDestination(arc) != twinB) createAnalogousArc(nodeA, getDestination(arc), arc, graph); else createAnalogousArc(nodeA, twinA, arc, graph); } // Passage marker management in node A: for (marker = getMarker(nodeA); marker != NULL_IDX; marker = getNextInNode(marker)) if (isTerminal(marker)) incrementFinishOffset(marker, getNodeLength(nodeB)); // Swapping new born passageMarkers from B to A for (marker = getMarker(nodeB); marker != NULL_IDX; marker = tmpMarker) { tmpMarker = getNextInNode(marker); if (isInitial(marker) || getNode(getPreviousInSequence(marker)) != nodeA) { extractPassageMarker(marker); transposePassageMarker(marker, nodeA); incrementFinishOffset(getTwinMarker(marker), getNodeLength(nodeA)); } else disconnectNextPassageMarker(getPreviousInSequence (marker), graph); } // Read starts concatenateReadStarts(nodeA, nodeB, graph); // Gaps appendNodeGaps(nodeA, nodeB, graph); // Descriptor management (node) appendDescriptors(nodeA, nodeB); // Update uniqueness: setUniqueness(nodeA, getUniqueness(nodeA) || getUniqueness(nodeB)); // Update virtual coverage for (cat = 0; cat < CATEGORIES; cat++) incrementVirtualCoverage(nodeA, cat, getVirtualCoverage(nodeB, cat)); // Update original virtual coverage for (cat = 0; cat < CATEGORIES; cat++) incrementOriginalVirtualCoverage(nodeA, cat, getOriginalVirtualCoverage (nodeB, cat)); // Freeing gobbled node destroyNode(nodeB, graph); }
// Replaces two consecutive nodes into a single equivalent node // The extra memory is freed void concatenateStringOfNodes(Node * nodeA, Graph * graph) { Node *twinA = getTwinNode(nodeA); Node * nodeB = nodeA; Node * twinB; Node *currentNode, *nextNode; Coordinate totalLength = 0; PassageMarkerI marker, tmpMarker; Arc *arc; Category cat; while (simpleArcCount(nodeB) == 1 && simpleArcCount(getTwinNode (getDestination(getArc(nodeB)))) == 1 && getDestination(getArc(nodeB)) != getTwinNode(nodeB) && getDestination(getArc(nodeB)) != nodeA) { totalLength += getNodeLength(nodeB); nodeB = getDestination(getArc(nodeB)); } twinB = getTwinNode(nodeB); totalLength += getNodeLength(nodeB); reallocateNodeDescriptor(nodeA, totalLength); currentNode = nodeA; while (currentNode != nodeB) { currentNode = getDestination(getArc(currentNode)); // Passage marker management in node A: for (marker = getMarker(nodeA); marker != NULL_IDX; marker = getNextInNode(marker)) if (getNode(getNextInSequence(marker)) != currentNode) incrementFinishOffset(marker, getNodeLength(currentNode)); // Swapping new born passageMarkers from B to A for (marker = getMarker(currentNode); marker != NULL_IDX; marker = tmpMarker) { tmpMarker = getNextInNode(marker); if (isInitial(marker) || getNode(getPreviousInSequence(marker)) != nodeA) { extractPassageMarker(marker); transposePassageMarker(marker, nodeA); incrementFinishOffset(getTwinMarker(marker), getNodeLength(nodeA)); } else disconnectNextPassageMarker(getPreviousInSequence (marker), graph); } // Read starts concatenateReadStarts(nodeA, currentNode, graph); // Gaps appendNodeGaps(nodeA, currentNode, graph); // Update uniqueness: setUniqueness(nodeA, getUniqueness(nodeA) || getUniqueness(currentNode)); // Update virtual coverage for (cat = 0; cat < CATEGORIES; cat++) incrementVirtualCoverage(nodeA, cat, getVirtualCoverage(currentNode, cat)); // Update original virtual coverage for (cat = 0; cat < CATEGORIES; cat++) incrementOriginalVirtualCoverage(nodeA, cat, getOriginalVirtualCoverage (currentNode, cat)); // Descriptor management (node) directlyAppendDescriptors(nodeA, currentNode, totalLength); } // Correct arcs for (arc = getArc(nodeB); arc != NULL; arc = getNextArc(arc)) { if (getDestination(arc) != twinB) createAnalogousArc(nodeA, getDestination(arc), arc, graph); else createAnalogousArc(nodeA, twinA, arc, graph); } // Freeing gobbled nodes currentNode = getTwinNode(nodeB); while (currentNode != getTwinNode(nodeA)) { arc = getArc(currentNode); nextNode = getDestination(arc); destroyNode(currentNode, graph); currentNode = nextNode; } }