static boolean extractSequence(PassageMarkerI path, TightString * sequence) { PassageMarkerI marker; Coordinate seqLength = 0; Coordinate writeIndex = 0; //velvetLog("Extracting sequence %li ... ", pathLength); //Measure length for (marker = getNextInSequence(path); !isTerminal(marker); marker = getNextInSequence(marker)) seqLength += getNodeLength(getNode(marker)); if (seqLength > MAXREADLENGTH) return false; else setTightStringLength(sequence, seqLength); //Copy sequences for (marker = getNextInSequence(path); !isTerminal(marker); marker = getNextInSequence(marker)) { appendNodeSequence(getNode(marker), sequence, writeIndex); writeIndex += getNodeLength(getNode(marker)); } return true; }
static void cleanUpRedundancy_local() { PassageMarkerI current; for (current = getNextInSequence(slowPath); !isTerminal(current); current = getNextInSequence(current)) handicapNode(getNode(current)); destroyPaths(); }
static void destroyPaths() { PassageMarkerI marker; while (slowPath != NULL_IDX) { marker = slowPath; slowPath = getNextInSequence(marker); destroyPassageMarker(marker); } while (fastPath != NULL_IDX) { marker = fastPath; fastPath = getNextInSequence(marker); destroyPassageMarker(marker); } }
static boolean goesToNode(PassageMarkerI marker, Node * node) { PassageMarkerI current; Node * start = getNode(marker); for (current = getNextInSequence(marker); current != NULL_IDX; current = getNextInSequence(current)) { if (getNode(current) == node) return true; else if (getNode(current) == start) continue; else if (getUniqueness(getNode(current))) return false; } return false; }
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 boolean goesToNode(PassageMarkerI marker, Node * node) { PassageMarkerI current; Node * start = getNode(marker); Node * twinStart = getTwinNode(start); Node * currentNode; for (current = getNextInSequence(marker); current != NULL_IDX; current = getNextInSequence(current)) { currentNode = getNode(current); if (currentNode == start || currentNode == twinStart) return false; else if (currentNode == node) return true; else if (getUniqueness(currentNode)) return false; } return false; }
static boolean goesToNode(PassageMarker * marker, Node * node) { PassageMarker *current; for (current = marker; current != NULL; current = getNextInSequence(current)) if (getNode(current) == node) return true; return false; }
static void destroyPaths() { PassageMarker *marker; while (slowPath != NULL) { marker = slowPath; getNodeTime(getNode(marker)); getNodeTime(getTwinNode(getNode(marker))); slowPath = getNextInSequence(marker); destroyPassageMarker(marker); } while (fastPath != NULL) { marker = fastPath; getNodeTime(getNode(marker)); getNodeTime(getTwinNode(getNode(marker))); fastPath = getNextInSequence(marker); destroyPassageMarker(marker); } }
void ResourceState::removeFromNextInSequence(uint64_t ID) { assert(NextInSequenceMask); assert(countPopulation(ID) == 1); if (ID > getNextInSequence()) RemovedFromNextInSequence |= ID; NextInSequenceMask = NextInSequenceMask & (~ID); if (!NextInSequenceMask) { NextInSequenceMask = ResourceSizeMask; assert(NextInSequenceMask != RemovedFromNextInSequence); NextInSequenceMask ^= RemovedFromNextInSequence; RemovedFromNextInSequence = 0; } }
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; } }
static void updateMembers(Node * bypass, Node * nextNode) { PassageMarkerI marker, next, tmp; Coordinate nextLength = getNodeLength(nextNode); // Update marker + arc info for (marker = getMarker(bypass); marker != NULL_IDX; marker = tmp) { tmp = getNextInNode(marker); if (!isTerminal(marker) && getNode(getNextInSequence(marker)) == nextNode) { // Marker steps right into target next = getNextInSequence(marker); disconnectNextPassageMarker(marker, graph); destroyPassageMarker(next); } else if (getUniqueness(nextNode) && goesToNode(marker, nextNode)) { // Marker goes indirectly to target while (getNode(getNextInSequence(marker)) != nextNode) { next = getNextInSequence(marker); disconnectNextPassageMarker(marker, graph); destroyPassageMarker(next); } next = getNextInSequence(marker); disconnectNextPassageMarker(marker, graph); destroyPassageMarker(next); } else if (!isTerminal(marker) && getFinishOffset(marker) == 0) { // Marker goes somewhere else than to target next = getNextInSequence(marker); incrementFinishOffset(marker, nextLength); } else { // Marker goes nowhere incrementFinishOffset(marker, nextLength); } } }
// 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; }
static boolean uniqueNodesConnect(Node * startingNode) { Node *destination = NULL; PassageMarkerI startMarker, currentMarker; RBConnection *newList; RBConnection *list = NULL; boolean multipleHits = false; if (arcCount(startingNode) == 0) return false; if (getMarker(startingNode) == NULL_IDX) return false; dbgCounter++; // Checking for multiple destinations for (startMarker = getMarker(startingNode); startMarker != NULL_IDX; startMarker = getNextInNode(startMarker)) { if (getFinishOffset(startMarker) > 2 * getWordLength(graph)) continue; for (currentMarker = getNextInSequence(startMarker); currentMarker != NULL_IDX; currentMarker = getNextInSequence(currentMarker)) { if (!getUniqueness(getNode(currentMarker))) { continue; } else if (getNodeStatus(getNode(currentMarker))) { if (getStartOffset(currentMarker) > 2 * getWordLength(graph)) break; for (newList = list; newList != NULL; newList = newList->next) { if (newList->node == getNode(currentMarker)) { newList->multiplicity++; break; } } if (newList == NULL) abort(); break; } else { if (getStartOffset(currentMarker) > 2 * getWordLength(graph)) break; setSingleNodeStatus(getNode(currentMarker), true); newList = allocateRBConnection(); newList->node = getNode(currentMarker); newList->multiplicity = 1; newList->marker = startMarker; newList->next = list; list = newList; break; } } } while (list != NULL) { newList = list; list = newList->next; setSingleNodeStatus(newList->node, false); if (newList->multiplicity >= MULTIPLICITY_CUTOFF) { if (destination == NULL) { destination = newList->node; path = newList->marker; } else if (destination != newList->node) multipleHits = true; } deallocateRBConnection(newList); } if (multipleHits) { multCounter++; setUniqueness(startingNode, false); return false; } if (destination == NULL || destination == startingNode || destination == getTwinNode(startingNode)) { nullCounter++; return false; } // Check for reciprocity for (startMarker = getMarker(getTwinNode(destination)); startMarker != NULL_IDX; startMarker = getNextInNode(startMarker)) { if (getFinishOffset(startMarker) > 2 * getWordLength(graph)) continue; for (currentMarker = getNextInSequence(startMarker); currentMarker != NULL_IDX; currentMarker = getNextInSequence(currentMarker)) { if (!getUniqueness(getNode(currentMarker))) { continue; } else if (getNodeStatus(getNode(currentMarker))) { if (getStartOffset(currentMarker) > 2 * getWordLength(graph)) break; for (newList = list; newList != NULL; newList = newList->next) { if (newList->node == getNode(currentMarker)) { newList->multiplicity++; break; } } if (newList == NULL) abort(); break; } else { if (getStartOffset(currentMarker) > 2 * getWordLength(graph)) break; setSingleNodeStatus(getNode(currentMarker), true); newList = allocateRBConnection(); newList->node = getNode(currentMarker); newList->multiplicity = 1; newList->next = list; list = newList; break; } } } while (list != NULL) { newList = list; list = newList->next; setSingleNodeStatus(newList->node, false); if (newList->multiplicity >= MULTIPLICITY_CUTOFF && newList->node != getTwinNode(startingNode)) multipleHits = true; deallocateRBConnection(newList); } if (multipleHits) { multCounter++; setUniqueness(destination, false); return false; } // Aligning long reads to each other: // TODO // Merge pairwise alignments and produce consensus // TODO return true; }