static void markInterestingNodes(Node * node) { Connection *connect; Node *destination; MiniConnection *localConnect; Coordinate min_distance = getNodeLength(node) / 2 - BACKTRACK_CUTOFF; // Mark own node setEmptyMiniConnection(node); // Loop thru primary scaffold for (connect = getConnection(node); connect != NULL; connect = getNextConnection(connect)) { destination = getTwinNode(getConnectionDestination(connect)); localConnect = &localScaffold[getNodeID(destination) + nodeCount(graph)]; if (getNodeStatus(destination)) { readjustMiniConnection(destination, localConnect, getConnectionDistance(connect), min_distance, getConnectionVariance(connect), connect, NULL); localConnect->backReference = NULL; } else { resetMiniConnection(destination, localConnect, getConnectionDistance(connect), getConnectionVariance(connect), connect, NULL, true); } integrateDerivativeDistances(connect, min_distance, true); } // Loop thru twin's primary scaffold for (connect = getConnection(getTwinNode(node)); connect != NULL; connect = getNextConnection(connect)) { destination = getConnectionDestination(connect); localConnect = &localScaffold[getNodeID(destination) + nodeCount(graph)]; if (getNodeStatus(destination)) readjustMiniConnection(destination, localConnect, -getConnectionDistance(connect), min_distance, getConnectionVariance(connect), NULL, connect); else resetMiniConnection(destination, localConnect, -getConnectionDistance(connect), getConnectionVariance(connect), NULL, connect, -1); integrateDerivativeDistances(connect, min_distance, false); } }
static void recenterLocalScaffold(Node * node, Coordinate oldLength) { MiniConnection *localConnect; Coordinate distance_shift = (getNodeLength(node) - oldLength) / 2; Coordinate min_distance = getNodeLength(node) / 2 - BACKTRACK_CUTOFF; NodeList *nodeList, *next; IDnum node2ID; Node *node2; for (nodeList = markedNodes; nodeList != NULL; nodeList = next) { next = nodeList->next; node2 = nodeList->node; if (node2 == node) { setSingleNodeStatus(node2, 1); continue; } node2ID = getNodeID(node2); localConnect = &localScaffold[node2ID + nodeCount(graph)]; localConnect->distance -= distance_shift; if (localConnect->distance < min_distance && localConnect->backReference == NULL && localConnect->frontReference == NULL) unmarkNode(node2, localConnect); else if (getNodeStatus(node2) > 0) setSingleNodeStatus(node2, 1); else if (getNodeStatus(node2) < 0) setSingleNodeStatus(node2, -1); } }
static void clipTipsVeryHardLocally() { NodeList *nodeList, *next; Node *current, *twin; boolean modified = true; //velvetLog("Clipping short tips off graph HARD\n"); while (modified) { modified = false; for (nodeList = getMarkedNodeList(); nodeList != NULL; nodeList = next) { next = nodeList->next; current = nodeList->node; if (current == NULL || getNodeStatus(current) != 1) continue; if (getUniqueness(current)) continue; //velvetLog("Checking node HARD %li %i\n", (long)getNodeID(current), simpleArcCount(current)); twin = getTwinNode(current); if( isLocalDeadEnd(current) || isLocalTwinDeadEnd(current) ){ //velvetLog("Found tip at node %li\n", (long)getNodeID(current)); handicapNode(current); modified = true; } } } }
void renumberLocusNodes(Locus * locus) { IDnum index; Node * node; IDnum counter = 0; Node ** newArray; for (index = 0; index < locus->contigCount; index++) { node = locus->contigs[index]; if (!getNodeStatus(node)) { locus->contigs[index] = NULL; counter++; if (getUniqueness(node)) locus->longContigCount--; } } if (counter == 0) return; newArray = callocOrExit(locus->contigCount - counter, Node *); counter = 0; for (index = 0; index < locus->contigCount; index++) { node = locus->contigs[index]; if (node == NULL) counter++; else newArray[index - counter] = node; } free(locus->contigs); locus->contigs = newArray; locus->contigCount -= counter; }
void handicapNode(Node * node) { if (getNodeStatus(node) > 0) setSingleNodeStatus(node, 10); else setSingleNodeStatus(node, -10); }
static void extendComponentToNode(Node * node) { if (getNodeStatus(node)) return; setSingleNodeStatus(node, true); recordNode(node); }
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 setNodeConnectionStatus(Node * node, boolean status) { Connection *connect; for (connect = getConnection(node); connect; connect = getNextConnection(connect)) if (getNodeStatus (getTwinNode(getConnectionDestination(connect)))) setConnectionStatus(connect, status); }
Connection *getReverseActiveConnection(Node * node) { Connection *connect; for (connect = getConnection(getTwinNode(node)); connect; connect = getNextConnection(connect)) if (getNodeStatus(getConnectionDestination(connect))) return connect; return NULL; }
static boolean hasNoActiveConnections(Node * node) { Connection *connect; for (connect = getConnection(node); connect; connect = getNextConnection(connect)) if (getNodeStatus (getTwinNode(getConnectionDestination(connect)))) return false; return true; }
static IDnum getReverseDegree(Node * node) { Connection *connect; IDnum counter = 0; for (connect = getConnection(node); connect; connect = getNextConnection(connect)) if (getNodeStatus(getConnectionDestination(connect))) counter++; return counter; }
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 inline boolean isNodeMemorized(Node * node, SmallNodeList * nodePile) { #ifdef OPENMP /* SF TODO There must be a faster way to do this: bit mask, hash table, tree, ... ? */ SmallNodeList * list; for (list = nodePile; list; list = list->next) if (list->node == node) return true; return false; #else return getNodeStatus(node); #endif }
void redraw(const uavcan::TimerEvent&) { std::cout << "\x1b\x5b\x48" << "\x1b\x5b\x32\x4a" << " NID | Status | Uptime\n" << "-----+---------------+--------\n"; for (unsigned i = 1; i <= uavcan::NodeID::Max; i++) { const auto s = getNodeStatus(i); if (s.known) { printStatusLine(i, s); } } std::cout << std::flush; }
static void propagateComponent(Node * node) { Connection *connect; if (getNodeStatus(node) || !getUniqueness(node)) return; setNodeStatus(node, true); for (connect = getConnection(node); connect != NULL; connect = getNextConnection(connect)) propagateComponent(getConnectionDestination(connect)); for (connect = getConnection(getTwinNode(node)); connect != NULL; connect = getNextConnection(connect)) propagateComponent(getConnectionDestination(connect)); }
void unmarkNode(Node * node, MiniConnection * localConnect) { if (localConnect->frontReference != NULL || localConnect->backReference != NULL) { if (getNodeStatus(node) > 0) setSingleNodeStatus(node, 10); else setSingleNodeStatus(node, -10); } else { setSingleNodeStatus(node, false); destroyNodeList(localConnect->nodeList); localConnect->frontReference = NULL; localConnect->backReference = NULL; localConnect->nodeList = NULL; } }
static void fillUpComponent(Node * node) { Connection *connect; if (getNodeStatus(node) || !getUniqueness(node)) return; setSingleNodeStatus(node, true); recordNode(node); for (connect = getConnection(node); connect != NULL; connect = getNextConnection(connect)) fillUpComponent(getTwinNode (getConnectionDestination(connect))); for (connect = getConnection(getTwinNode(node)); connect != NULL; connect = getNextConnection(connect)) fillUpComponent(getConnectionDestination(connect)); }
static Connection *getSecondReverseActiveConnection(Node * node) { Connection *connect; boolean firstFound = false; for (connect = getConnection(getTwinNode(node)); connect; connect = getNextConnection(connect)) { if (getNodeStatus(getConnectionDestination(connect))) { if (firstFound) return connect; else firstFound = true; } } return false; }
static IDnum countConnectedComponents(Graph * graph) { IDnum index; IDnum count = 0; Node *node; resetNodeStatus(graph); for (index = 1; index <= nodeCount(graph); index++) { node = getNodeInGraph(graph, index); if (!getNodeStatus(node) && getUniqueness(node)) { count++; propagateComponent(node); } } return count; }
static Locus *extractConnectedComponents(IDnum locusCount) { Locus *loci = allocateLocusArray(locusCount); Locus *locus; IDnum index; IDnum locusIndex = 0; IDnum nodeIndex; Node *node; resetNodeStatus(graph); for (index = 1; index <= nodeCount(graph); index++) { node = getNodeInGraph(graph, index); if (!getNodeStatus(node) && getUniqueness(node)) { locus = getLocus(loci, locusIndex++); clearLocus(locus); // Long contigs fillUpComponent(node); setLongContigCount(locus, countMarkedNodes()); while (existsMarkedNode()) addContig(locus, popNodeRecord()); // Secondary contigs extendComponent(locus); setContigCount(locus, getLongContigCount(locus) + countMarkedNodes()); while (existsMarkedNode()) addContig(locus, popNodeRecord()); // Mark primary nodes so that their twins are not reused for (nodeIndex = 0; nodeIndex < getLongContigCount(locus); nodeIndex++) setNodeStatus(getContig(locus, nodeIndex), true); // Unmark secondary nodes so that they are available to other loci for (nodeIndex = getLongContigCount(locus); nodeIndex < getContigCount(locus); nodeIndex++) setNodeStatus(getContig(locus, nodeIndex), false); } } return loci; }
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; }
static void ghostThreadSequenceThroughGraph(TightString * tString, KmerOccurenceTable * kmerOccurences, Graph * graph, IDnum seqID, Category category, boolean readTracking, boolean double_strand) { Kmer word; Kmer antiWord; Coordinate readNucleotideIndex; KmerOccurence *kmerOccurence; int wordLength = getWordLength(graph); Nucleotide nucleotide; Node *node; Node *previousNode = NULL; clearKmer(&word); clearKmer(&antiWord); // Neglect any read which will not be short paired if ((!readTracking && category % 2 == 0) || category / 2 >= CATEGORIES) return; // Neglect any string shorter than WORDLENGTH : if (getLength(tString) < wordLength) return; // Verify that all short reads are reasonnably short if (getLength(tString) > USHRT_MAX) { printf("Short read of length %lli, longer than limit %i\n", (long long) getLength(tString), SHRT_MAX); puts("You should better declare this sequence as long, because it genuinely is!"); exit(1); } // Allocate memory for the read pairs if (!readStartsAreActivated(graph)) activateReadStarts(graph); // Fill in the initial word : for (readNucleotideIndex = 0; readNucleotideIndex < wordLength - 1; readNucleotideIndex++) { nucleotide = getNucleotide(readNucleotideIndex, tString); pushNucleotide(&word, nucleotide); if (double_strand) { #ifdef COLOR reversePushNucleotide(&antiWord, nucleotide); #else reversePushNucleotide(&antiWord, 3 - nucleotide); #endif } } // Go through sequence while (readNucleotideIndex < getLength(tString)) { // Shift word: nucleotide = getNucleotide(readNucleotideIndex++, tString); pushNucleotide(&word, nucleotide); if (double_strand) { #ifdef COLOR reversePushNucleotide(&antiWord, nucleotide); #else reversePushNucleotide(&antiWord, 3 - nucleotide); #endif } // Search in table if ((!double_strand || compareKmers(&word, &antiWord) <= 0) && (kmerOccurence = findKmerOccurenceInSortedTable(&word, kmerOccurences))) { node = getNodeInGraph(graph, kmerOccurence->nodeID); } else if ((double_strand && compareKmers(&word, &antiWord) > 0) && (kmerOccurence = findKmerOccurenceInSortedTable(&antiWord, kmerOccurences))) { node = getNodeInGraph(graph, -kmerOccurence->nodeID); } else { node = NULL; if (previousNode) break; } previousNode = node; // Fill in graph if (node && !getNodeStatus(node)) { incrementReadStartCount(node, graph); setSingleNodeStatus(node, true); memorizeNode(node); } } unlockMemorizedNodes(); }
static void threadSequenceThroughGraph(TightString * tString, KmerOccurenceTable * kmerOccurences, Graph * graph, IDnum seqID, Category category, boolean readTracking, boolean double_strand) { Kmer word; Kmer antiWord; Coordinate readNucleotideIndex; Coordinate kmerIndex; KmerOccurence *kmerOccurence; int wordLength = getWordLength(graph); PassageMarker *marker = NULL; PassageMarker *previousMarker = NULL; Node *node; Node *previousNode = NULL; Coordinate coord; Coordinate previousCoord = 0; Nucleotide nucleotide; clearKmer(&word); clearKmer(&antiWord); // Neglect any string shorter than WORDLENGTH : if (getLength(tString) < wordLength) return; // Fill in the initial word : for (readNucleotideIndex = 0; readNucleotideIndex < wordLength - 1; readNucleotideIndex++) { nucleotide = getNucleotide(readNucleotideIndex, tString); pushNucleotide(&word, nucleotide); if (double_strand) { #ifdef COLOR reversePushNucleotide(&antiWord, nucleotide); #else reversePushNucleotide(&antiWord, 3 - nucleotide); #endif } } // Go through sequence while (readNucleotideIndex < getLength(tString)) { nucleotide = getNucleotide(readNucleotideIndex++, tString); pushNucleotide(&word, nucleotide); if (double_strand) { #ifdef COLOR reversePushNucleotide(&antiWord, nucleotide); #else reversePushNucleotide(&antiWord, 3 - nucleotide); #endif } // Search in table if ((!double_strand || compareKmers(&word, &antiWord) <= 0) && (kmerOccurence = findKmerOccurenceInSortedTable(&word, kmerOccurences))) { node = getNodeInGraph(graph, kmerOccurence->nodeID); coord = kmerOccurence->position; } else if ((double_strand && compareKmers(&word, &antiWord) > 0) && (kmerOccurence = findKmerOccurenceInSortedTable(&antiWord, kmerOccurences))) { node = getNodeInGraph(graph, -kmerOccurence->nodeID); coord = getNodeLength(node) - kmerOccurence->position - 1; } else { node = NULL; if (previousNode) { break; } } // Fill in graph if (node) { kmerIndex = readNucleotideIndex - wordLength; if (previousNode == node && previousCoord == coord - 1) { if (category / 2 >= CATEGORIES) { setPassageMarkerFinish(marker, kmerIndex + 1); setFinishOffset(marker, getNodeLength(node) - coord - 1); } else { incrementVirtualCoverage(node, category / 2, 1); incrementOriginalVirtualCoverage (node, category / 2, 1); } } else { if (category / 2 >= CATEGORIES) { marker = newPassageMarker(seqID, kmerIndex, kmerIndex + 1, coord, getNodeLength (node) - coord - 1); transposePassageMarker(marker, node); connectPassageMarkers (previousMarker, marker, graph); previousMarker = marker; } else { if (readTracking) { if (!getNodeStatus(node)) { addReadStart(node, seqID, coord, graph, kmerIndex); setSingleNodeStatus (node, true); memorizeNode(node); } else { blurLastShortReadMarker (node, graph); } } incrementVirtualCoverage(node, category / 2, 1); incrementOriginalVirtualCoverage (node, category / 2, 1); } createArc(previousNode, node, graph); } previousNode = node; previousCoord = coord; } } unlockMemorizedNodes(); }
bool ZDvidTarget::readOnly() const { return m_readOnly || getNodeStatus() == ZDvid::NODE_LOCKED; }
static boolean pushNeighbours(Node * node, Node * oppositeNode, Coordinate distance, boolean force_jumps) { Node *candidate; Coordinate oldLength = getNodeLength(node); MiniConnection *localConnect; NodeList *path, *tmp; if ((path = pathIsClear(node, oppositeNode, distance))) { while (path) { candidate = path->node; tmp = path->next; deallocateNodeList(path); path = tmp; /////////////////////////////////////// // Stepping forward to destination // /////////////////////////////////////// if (getUniqueness(candidate)) { concatenateReadStarts(node, candidate, graph); concatenateLongReads(node, candidate, graph); absorbExtension(node, candidate); // Scaffold changes recenterNode(node, oldLength); recenterLocalScaffold(node, oldLength); absorbExtensionInScaffold(node, candidate); // Read coverage #ifndef SINGLE_COV_CAT Category cat; for (cat = 0; cat < CATEGORIES; cat++) { incrementVirtualCoverage(node, cat, getVirtualCoverage(candidate, cat)); incrementOriginalVirtualCoverage(node, cat, getOriginalVirtualCoverage(candidate, cat)); } #else incrementVirtualCoverage(node, getVirtualCoverage(candidate)); #endif if (getNodeStatus(candidate)) { localConnect = &localScaffold[getNodeID (candidate) + nodeCount (graph)]; if (localConnect->frontReference) { destroyConnection (localConnect-> frontReference, getNodeID(node)); localConnect-> frontReference = NULL; } if (localConnect->backReference) { destroyConnection (localConnect-> backReference, -getNodeID(node)); localConnect-> backReference = NULL; } unmarkNode(candidate, localConnect); } if (getNodeStatus(getTwinNode(candidate))) { localConnect = &localScaffold[-getNodeID (candidate) + nodeCount (graph)]; if (localConnect->frontReference) { destroyConnection (localConnect-> frontReference, getNodeID(node)); localConnect-> frontReference = NULL; } if (localConnect->backReference) { destroyConnection (localConnect-> backReference, -getNodeID(node)); localConnect-> backReference = NULL; } unmarkNode(getTwinNode(candidate), localConnect); } destroyNode(candidate, graph); return true; } else { adjustShortReads(node, candidate); adjustLongReads(node, getNodeLength(candidate)); absorbExtension(node, candidate); } } } if (force_jumps && oppositeNode && abs_ID(getNodeID(oppositeNode)) < abs_ID(getNodeID(node))) { distance -= getNodeLength(node) / 2; distance -= getNodeLength(oppositeNode) / 2; if (distance > 10) { adjustShortReadsByLength(node, distance); adjustLongReads(node, distance); appendGap(node, distance, graph); } else { adjustShortReadsByLength(node, 10); adjustLongReads(node, 10); appendGap(node, 10, graph); } concatenateReadStarts(node, oppositeNode, graph); concatenateLongReads(node, oppositeNode, graph); absorbExtension(node, oppositeNode); // Scaffold changes recenterNode(node, oldLength); recenterLocalScaffold(node, oldLength); absorbExtensionInScaffold(node, oppositeNode); // Read coverage #ifndef SINGLE_COV_CAT Category cat; for (cat = 0; cat < CATEGORIES; cat++) incrementVirtualCoverage(node, cat, getVirtualCoverage(oppositeNode, cat)); #else incrementVirtualCoverage(node, getVirtualCoverage(oppositeNode)); #endif if (getNodeStatus(oppositeNode)) { localConnect = &localScaffold[getNodeID(oppositeNode) + nodeCount(graph)]; if (localConnect->frontReference) { destroyConnection(localConnect-> frontReference, getNodeID(node)); localConnect->frontReference = NULL; } if (localConnect->backReference) { destroyConnection(localConnect-> backReference, -getNodeID(node)); localConnect->backReference = NULL; } unmarkNode(oppositeNode, localConnect); } if (getNodeStatus(getTwinNode(oppositeNode))) { localConnect = &localScaffold[-getNodeID(oppositeNode) + nodeCount(graph)]; if (localConnect->frontReference) { destroyConnection(localConnect-> frontReference, getNodeID(node)); localConnect->frontReference = NULL; } if (localConnect->backReference) { destroyConnection(localConnect-> backReference, -getNodeID(node)); localConnect->backReference = NULL; } unmarkNode(getTwinNode(oppositeNode), localConnect); } destroyNode(oppositeNode, graph); } return false; }
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; } }
static void integrateDerivativeDistances(Connection * connect, Coordinate min_distance, boolean direction) { Node *reference = getConnectionDestination(connect); Node *destination; IDnum destinationID; Coordinate distance, baseDistance; double variance, baseVariance; Connection *connect2; MiniConnection *localConnect; // debug IDnum counter = 0; if (!getUniqueness(reference)) return; //velvetLog("Opposite node %li length %li at %li ± %f\n", getNodeID(reference), getNodeLength(reference), getConnectionDistance(connect), getConnectionVariance(connect)); baseDistance = getConnectionDistance(connect); baseVariance = getConnectionVariance(connect); for (connect2 = getConnection(reference); connect2 != NULL; connect2 = getNextConnection(connect2)) { // Avoid null derivative if (connect2 == getTwinConnection(connect)) continue; destination = getConnectionDestination(connect2); // Beware of directionality if (!direction) destination = getTwinNode(destination); // Derivate values destinationID = getNodeID(destination); // Beware of directionality (bis) if (direction) distance = baseDistance - getConnectionDistance(connect2); else distance = getConnectionDistance(connect2) - baseDistance; variance = getConnectionVariance(connect2) + baseVariance; localConnect = &localScaffold[destinationID + nodeCount(graph)]; // Avoid over-projection if (distance < min_distance) { //velvetLog("Node %li not at distance %li± %f (min %li)\n", destinationID, distance, variance, min_distance); continue; } counter++; if (getNodeStatus(destination)) { readjustMiniConnection(destination, localConnect, distance, min_distance, variance, NULL, NULL); } else resetMiniConnection(destination, localConnect, distance, variance, NULL, NULL, true); //velvetLog("Node %li now at distance %li\n", destinationID, localConnect->distance); } //velvetLog("%li secondary distances added\n", counter); }
static void absorbExtensionInScaffold(Node * node, Node * source) { IDnum nodeID = getNodeID(node); IDnum sourceID = getNodeID(source); IDnum sourceIndex = sourceID + nodeCount(graph); Node *twinSource = getTwinNode(source); IDnum twinSourceIndex = getNodeID(twinSource) + nodeCount(graph); Connection *connect, *original; Node *destination; IDnum destinationID; Coordinate distance_shift = (getNodeLength(node) - getNodeLength(source)) / 2; Coordinate min_distance = getNodeLength(node) / 2 - BACKTRACK_CUTOFF; MiniConnection *localConnect; Coordinate distance; double variance; IDnum direct_count; IDnum paired_count; while ((connect = getConnection(source))) { destination = getTwinNode(getConnectionDestination(connect)); if (destination == getTwinNode(node)) { localConnect = &localScaffold[twinSourceIndex]; localConnect->frontReference = NULL; unmarkNode(twinSource, localConnect); destroyConnection(connect, sourceID); continue; } if (destination == node) { localConnect = &localScaffold[sourceIndex]; localConnect->backReference = NULL; unmarkNode(source, localConnect); destroyConnection(connect, sourceID); continue; } destinationID = getNodeID(destination); localConnect = &localScaffold[destinationID + nodeCount(graph)]; incrementConnectionDistance(connect, distance_shift); distance = getConnectionDistance(connect); variance = getConnectionVariance(connect); direct_count = getConnectionDirectCount(connect); paired_count = getConnectionPairedCount(connect); if (getNodeStatus(destination)) { readjustMiniConnection(destination, localConnect, distance, min_distance, variance, NULL, NULL); if ((original = localConnect->frontReference)) readjustConnection(original, distance, variance, direct_count, paired_count); else localConnect->frontReference = createNewConnection(nodeID, -destinationID, direct_count, paired_count, distance, variance); } else resetMiniConnection(destination, localConnect, distance, variance, createNewConnection(nodeID, -destinationID, direct_count, paired_count, distance, variance), NULL, true); integrateDerivativeDistances(connect, min_distance, true); destroyConnection(connect, sourceID); } // Loop thru twin's primary scaffold while ((connect = getConnection(getTwinNode(source)))) { destination = getConnectionDestination(connect); if (destination == node) { localConnect = &localScaffold[sourceIndex]; localConnect->frontReference = NULL; unmarkNode(source, localConnect); destroyConnection(connect, -sourceID); continue; } if (destination == getTwinNode(node)) { localConnect = &localScaffold[twinSourceIndex]; localConnect->backReference = NULL; unmarkNode(twinSource, localConnect); destroyConnection(connect, -sourceID); continue; } destinationID = getNodeID(destination); localConnect = &localScaffold[destinationID + nodeCount(graph)]; incrementConnectionDistance(connect, -distance_shift); distance = getConnectionDistance(connect); variance = getConnectionVariance(connect); direct_count = getConnectionDirectCount(connect); paired_count = getConnectionPairedCount(connect); if (distance > min_distance && getNodeStatus(destination) < 0) { readjustMiniConnection(destination, localConnect, -distance, min_distance, variance, NULL, NULL); if ((original = localConnect->backReference)) readjustConnection(original, distance, variance, direct_count, paired_count); } else if (getNodeStatus(destination) < 0) { if ((original = localConnect->backReference)) { destroyConnection(original, -nodeID); localConnect->backReference = NULL; } unmarkNode(destination, localConnect); } else if (getNodeStatus(destination) > 0) { if ((original = localConnect->frontReference)) { destroyConnection(original, nodeID); localConnect->frontReference = NULL; } unmarkNode(destination, localConnect); } else if (distance > min_distance) { resetMiniConnection(destination, localConnect, -distance, variance, NULL, createNewConnection(-nodeID, destinationID, direct_count, paired_count, distance, variance), -1); integrateDerivativeDistances(connect, min_distance, true); } destroyConnection(connect, -sourceID); } }