static boolean isLocalDeadEnd(Node * node) { Arc *arc; for (arc = getArc(node); arc != NULL; arc = getNextArc(arc)) if (getNodeStatus(getDestination(arc)) == 1) return false; return true; }
static void absorbExtension(Node * node, Node * extension) { Arc *arc; appendNodeGaps(node, extension, graph); appendDescriptors(node, extension); // Destroy old nodes while (getArc(node) != NULL) destroyArc(getArc(node), graph); // Create new for (arc = getArc(extension); arc != NULL; arc = getNextArc(arc)) createAnalogousArc(node, getDestination(arc), arc, graph); }
static void tourBusNode_local(Node * node) { Arc *arc; Node *destination; Time nodeTime = getNodeTime(node); //velvetLog("Node %li %f %i %p\n", getNodeID(node), // times[getNodeID(node) + nodeCount(graph)], simpleArcCount(node), // node); for (arc = getArc(node); arc != NULL; arc = getNextArc(arc)) { destination = getDestination(arc); // Node doesn't belong to the marked node area if (getNodeStatus(getDestination(arc)) != 1) continue; tourBusArc_local(node, arc, nodeTime); if (getNodeStatus(node) != 1) break; } }
static NodeList *pathIsClear(Node * node, Node * oppositeNode, Coordinate distance) { Arc *arc; Node *candidate, *dest, *current; Coordinate extension_distance = 0; boolean maxRepeat = 1; Node *repeatEntrance = NULL; IDnum counter = 0; NodeList *path = NULL; NodeList *tail = path; setSingleNodeStatus(node, 2); current = node; while (true) { ////////////////////////////////// // Selecting destination // ////////////////////////////////// candidate = NULL; // First round for priority nodes for (arc = getArc(current); arc != NULL; arc = getNextArc(arc)) { dest = getDestination(arc); if (dest == node || dest == getTwinNode(node)) continue; if (getNodeStatus(dest) <= 0) continue; if (candidate == NULL || getNodeStatus(candidate) > getNodeStatus(dest) || (getNodeStatus(candidate) == getNodeStatus(dest) && extension_distance > localScaffold[getNodeID(dest) + nodeCount(graph)]. distance - getNodeLength(dest) / 2)) { extension_distance = localScaffold[getNodeID(dest) + nodeCount(graph)]. distance - getNodeLength(dest) / 2; candidate = dest; } } // In case of failure if (candidate == NULL) { for (arc = getArc(current); arc != NULL; arc = getNextArc(arc)) { dest = getDestination(arc); if (getNodeStatus(dest) == 0) continue; if (dest == node || dest == getTwinNode(node)) continue; if (candidate == NULL || getNodeStatus(candidate) < getNodeStatus(dest) || (getNodeStatus(candidate) == getNodeStatus(dest) && extension_distance < localScaffold[getNodeID(dest) + nodeCount(graph)]. distance - getNodeLength(dest) / 2)) { extension_distance = localScaffold[getNodeID(dest) + nodeCount (graph)]. distance - getNodeLength(dest) / 2; candidate = dest; } } } if (candidate == NULL) { while (path) { tail = path->next; deallocateNodeList(path); path = tail; } return false; } // Loop detection if (candidate == repeatEntrance && abs_bool(getNodeStatus(candidate)) == maxRepeat + 1) { while (path) { tail = path->next; deallocateNodeList(path); path = tail; } return false; } else if (abs_bool(getNodeStatus(candidate)) > maxRepeat) { maxRepeat = abs_bool(getNodeStatus(candidate)); repeatEntrance = candidate; } else if (abs_bool(getNodeStatus(candidate)) == 1) { maxRepeat = 1; repeatEntrance = NULL; } if (getNodeStatus(candidate) > 0) setSingleNodeStatus(candidate, getNodeStatus(candidate) + 1); else setSingleNodeStatus(candidate, getNodeStatus(candidate) - 1); if (abs_bool(getNodeStatus(candidate)) > 100 || counter > nodeCount(graph)) { while (path) { tail = path->next; deallocateNodeList(path); path = tail; } return false; } // Missassembly detection if (getUniqueness(candidate) && oppositeNode && candidate != oppositeNode && extension_distance > distance) { while (path) { tail = path->next; deallocateNodeList(path); path = tail; } return false; } if (path == NULL) { path = allocateNodeList(); path->next = NULL; path->node = candidate; tail = path; } else { tail->next = allocateNodeList(); tail = tail->next; tail->node = candidate; tail->next = NULL; } if (getUniqueness(candidate)) return path; current = candidate; } }
// 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; } }
static Node *bypass() { Node *bypass = getNode(path); Node *next = NULL; Arc *arc; PassageMarkerI nextMarker; // Remove unwanted arcs while (getArc(bypass) != NULL) destroyArc(getArc(bypass), graph); // Update extensive variables (length + descriptors + passage markers) while (!isTerminal(path)) { nextMarker = getNextInSequence(path); next = getNode(nextMarker); while (next == bypass) { disconnectNextPassageMarker(path, graph); destroyPassageMarker(nextMarker); nextMarker = getNextInSequence(path); next = getNode(nextMarker); } if (next == NULL) return bypass; // Overall node update if (!getUniqueness(next)) { adjustShortReads(bypass, getNextInSequence(path)); appendSequence(bypass, sequences, getNextInSequence(path), graph); } else { concatenateReadStarts(bypass, next, graph); #ifndef SINGLE_COV_CAT Category cat; for (cat = 0; cat < CATEGORIES; cat++) { // Update virtual coverage incrementVirtualCoverage(bypass, cat, getVirtualCoverage(next, cat)); // Update original virtual coverage incrementOriginalVirtualCoverage(bypass, cat, getOriginalVirtualCoverage(next, cat)); } #else incrementVirtualCoverage(bypass, getVirtualCoverage(next)); #endif appendDescriptors(bypass, next); } // Members updateMembers(bypass, next); // Termination if (isTerminal(path) || getUniqueness(next)) break; } // Remove unique groupies from arrival admitGroupies(next, bypass); // Copy destination arcs for (arc = getArc(next); arc != NULL; arc = getNextArc(arc)) { if (getDestination(arc) == next) continue; else if (getDestination(arc) == getTwinNode(next)) createAnalogousArc(bypass, getTwinNode(bypass), arc, graph); else createAnalogousArc(bypass, getDestination(arc), arc, graph); } destroyNode(next, graph); return bypass; }