static boolean acceptorSiteAtJunction(Node * nodeA, Node * nodeB) { Node *twinNodeA = getTwinNode(nodeA); Node *twinNodeB = getTwinNode(nodeB); Nucleotide n1, n2; int i; n2 = getNucleotideInNode(twinNodeB, getNodeLength(twinNodeB) - SPLICE_FUZZINESS); for (i = SPLICE_FUZZINESS - 1; i > 0; i--) { n1 = n2; n2 = getNucleotideInNode(twinNodeB, getNodeLength(twinNodeB) - i); if (n1 == CYTOSINE && n2 == ADENINE) return true; } for (i = 0; i < SPLICE_FUZZINESS + 2; i++) { n1 = n2; n2 = getNucleotideInNode(twinNodeA, i); if (n1 == CYTOSINE && n2 == ADENINE) return true; } return false; }
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 boolean isLocalTwinDeadEnd(Node * node) { Arc *arc; for (arc = getArc(getTwinNode(node)); arc != NULL; arc = getNextArc(arc)) if (getNodeStatus(getTwinNode(getDestination(arc))) == 1) return false; return true; }
static void extendComponentFromNode(Node * node) { Connection *connect; //velvetLog("Extending from node %li\n", (long) getNodeID(node)); for (connect = getConnection(node); connect; connect = getNextConnection(connect)) extendComponentToNode(getTwinNode (getConnectionDestination(connect))); for (connect = getConnection(getTwinNode(node)); connect; connect = getNextConnection(connect)) extendComponentToNode(getConnectionDestination(connect)); }
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; } } } }
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)); }
void concatenateReadStarts(Node * target, Node * source, Graph * graph) { IDnum sourceLength, targetLength; ShortReadMarker *sourceArray, *targetArray, *marker; IDnum index; Coordinate position, nodeLength; if (!readStartsAreActivated(graph)) return; if (target == NULL || source == NULL) return; // Update Coordinates sourceArray = getNodeReads(source, graph); sourceLength = getNodeReadCount(source, graph); nodeLength = getNodeLength(target); for (index = 0; index < sourceLength; index++) { marker = getShortReadMarkerAtIndex(sourceArray, index); position = getShortReadMarkerPosition(marker); if (position != -1) { position += nodeLength; setShortReadMarkerPosition(marker, position); } } // Same but for symmetrical reads targetArray = getNodeReads(getTwinNode(target), graph); targetLength = getNodeReadCount(getTwinNode(target), graph); nodeLength = getNodeLength(source); for (index = 0; index < targetLength; index++) { marker = getShortReadMarkerAtIndex(targetArray, index); position = getShortReadMarkerPosition(marker); if (position != -1) { position += nodeLength; setShortReadMarkerPosition(marker, position); } } // Merging lists mergeNodeReads(target, source, graph); mergeNodeReads(getTwinNode(target), getTwinNode(source), graph); }
// Detects sequences that could be simplified through concatentation // Iterates till graph cannot be more simplified // Useless nodes are freed from memory and remaining ones are renumbered void concatenateGraph(Graph * graph) { IDnum nodeIndex; Node *node, *twin; velvetLog("Concatenation...\n"); for (nodeIndex = 1; nodeIndex < nodeCount(graph); nodeIndex++) { node = getNodeInGraph(graph, nodeIndex); if (node == NULL) continue; twin = getTwinNode(node); while (simpleArcCount(node) == 1 && simpleArcCount(getTwinNode (getDestination(getArc(node)))) == 1) { if (getDestination(getArc(node)) == twin || getDestination(getArc(node)) == node) break; concatenateStringOfNodes(node, graph); } while (simpleArcCount(twin) == 1 && simpleArcCount(getTwinNode (getDestination(getArc(twin)))) == 1) { if (getDestination(getArc(twin)) == node || getDestination(getArc(twin)) == twin) break; concatenateStringOfNodes(twin, graph); } } renumberNodes(graph); sortGapMarkers(graph); velvetLog("Concatenation over!\n"); }
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 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); } }
static void adjustShortReadsByLength(Node * target, Coordinate nodeLength) { ShortReadMarker *targetArray, *marker; IDnum targetLength, index; Coordinate position; if (!readStartsAreActivated(graph)) return; targetArray = getNodeReads(getTwinNode(target), graph); targetLength = getNodeReadCount(getTwinNode(target), graph); for (index = 0; index < targetLength; index++) { marker = getShortReadMarkerAtIndex(targetArray, index); position = getShortReadMarkerPosition(marker); if (position != -1) { position += nodeLength; setShortReadMarkerPosition(marker, position); } } }
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 void recenterNode(Node * node, Coordinate oldLength) { IDnum nodeID = getNodeID(node); Connection *connect, *next; Coordinate distance_shift = (getNodeLength(node) - oldLength) / 2; Coordinate min_distance = getNodeLength(node) / 2 - BACKTRACK_CUTOFF; MiniConnection *localConnect; //velvetLog("Recentering node\n"); for (connect = getConnection(node); connect != NULL; connect = next) { next = getNextConnection(connect); incrementConnectionDistance(connect, -distance_shift); if (getConnectionDistance(connect) < min_distance) { //velvetLog("Unrecording %li\n", // -getNodeID(getConnectionDestination(connect))); localConnect = &localScaffold[-getNodeID(getConnectionDestination(connect)) + nodeCount(graph)]; localConnect->frontReference = NULL; unmarkNode(getTwinNode(getConnectionDestination(connect)), localConnect); destroyConnection(connect, nodeID); } else if (getTwinConnection(connect) != NULL) incrementConnectionDistance(getTwinConnection(connect), -distance_shift); } for (connect = getConnection(getTwinNode(node)); connect != NULL; connect = next) { next = getNextConnection(connect); incrementConnectionDistance(connect, distance_shift); if (getTwinConnection(connect) != NULL) incrementConnectionDistance(getTwinConnection(connect), distance_shift); } }
///////////////////////////////////////// // Locus degree distribution ///////////////////////////////////////// static IDnum getDegree(Node * node) { Connection *connect; IDnum counter = 0; for (connect = getConnection(node); connect; connect = getNextConnection(connect)) if (getNodeStatus (getTwinNode(getConnectionDestination(connect)))) counter++; return counter; }
void readCoherentGraph(Graph * inGraph, boolean(*isUnique) (Node * node), double coverage, ReadSet * reads) { IDnum nodeIndex; Node *node; IDnum previousNodeCount = 0; graph = inGraph; listMemory = newRecycleBin(sizeof(PassageMarkerList), 100000); expected_coverage = coverage; sequences = reads->tSequences; velvetLog("Read coherency...\n"); resetNodeStatus(graph); identifyUniqueNodes(isUnique); trimLongReadTips(); previousNodeCount = 0; while (previousNodeCount != nodeCount(graph)) { previousNodeCount = nodeCount(graph); for (nodeIndex = 1; nodeIndex <= nodeCount(graph); nodeIndex++) { node = getNodeInGraph(graph, nodeIndex); if (node == NULL || !getUniqueness(node)) continue; while (uniqueNodesConnect(node)) node = bypass(); node = getTwinNode(node); while (uniqueNodesConnect(node)) node = bypass(); } renumberNodes(graph); } destroyRecycleBin(listMemory); destroyRecycleBin(nodeListMemory); velvetLog("Confronted to %li multiple hits and %li null over %li\n", (long) multCounter, (long) nullCounter, (long) dbgCounter); velvetLog("Read coherency over!\n"); }
static void projectFromSingleRead(Node * node, ReadOccurence * readOccurence, Coordinate position, Coordinate offset, Coordinate length) { Coordinate distance = 0; Node *target = getNodeInGraph(graph, -readOccurence->nodeID); double variance = 1; if (target == getTwinNode(node) || target == node) return; if (position < 0) { variance += getNodeLength(node) * getNodeLength(node) / 16; // distance += 0; } else { // variance += 0; distance += position - offset - getNodeLength(node) / 2; } if (readOccurence->position < 0) { variance += getNodeLength(target) * getNodeLength(target) / 16; //distance += 0; } else { // variance += 0; distance += -readOccurence->position + readOccurence->offset + getNodeLength(target) / 2; } if (position < 0 || readOccurence->position < 0) { if (offset < readOccurence->offset && distance - getNodeLength(node)/2 - getNodeLength(target)/2 < -10) return; if (offset > readOccurence->offset && distance - getNodeLength(node)/2 - getNodeLength(target)/2 > 10) return; variance += length * length / 16; createConnection(getNodeID(node), getNodeID(target), 1, 0, distance, variance); createConnection(-getNodeID(node), -getNodeID(target), 1, 0, -distance, variance); } else if (distance > 0) { createConnection(getNodeID(node), getNodeID(target), 1, 0, distance, variance); } else { createConnection(-getNodeID(node), -getNodeID(target), 1, 0, -distance, variance); } }
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)); }
static void updateDistribution(IDnum * distribution, Node * node) { IDnum degree = getDegree(node); if (degree < 4) distribution[degree]++; else distribution[3]++; degree = getReverseDegree(getTwinNode(node)); if (degree < 4) distribution[degree]++; else distribution[3]++; }
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 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 projectFromReadPair(Node * node, ReadOccurence * readOccurence, Coordinate position, Coordinate offset, Coordinate insertLength, double insertVariance) { Coordinate distance = insertLength; Coordinate variance = insertVariance; Node *target = getNodeInGraph(graph, readOccurence->nodeID); if (target == getTwinNode(node) || target == node) return; if (getUniqueness(target) && getNodeID(target) < getNodeID(node)) return; if (position < 0) { variance += getNodeLength(node) * getNodeLength(node) / 16; // distance += 0; } else { // variance += 0; distance += position - offset - getNodeLength(node) / 2; } if (readOccurence->position < 0) { variance += getNodeLength(target) * getNodeLength(target) / 16; //distance += 0; } else { // variance += 0; distance += readOccurence->position - readOccurence->offset - getNodeLength(target) / 2; } if (distance - getNodeLength(node)/2 - getNodeLength(target)/2 < -6 * sqrt(insertVariance)) return; else if (distance < getNodeLength(node)/2 + getNodeLength(target)/2) distance = getNodeLength(node)/2 + getNodeLength(target)/2; createConnection(getNodeID(node), getNodeID(target), 0, 1, distance, variance); }
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 expandLongNodes(boolean force_jumps) { IDnum nodeID; Node *node; boolean modified = false; for (nodeID = 1; nodeID <= nodeCount(graph); nodeID++) { node = getNodeInGraph(graph, nodeID); if (node != NULL && getUniqueness(node)) { modified = expandLongNode(node, force_jumps) || modified; modified = expandLongNode(getTwinNode(node), force_jumps) || modified; } } return modified; }
static void computeLocalNodeToNodeMappingsFromConnections(Connection * connect, Connection * connect2) { Node *node1 = getTwinNode(getConnectionDestination(connect)); Node *node2 = getTwinNode(getConnectionDestination(connect2)); IDnum nodeID1 = getNodeID(node1); IDnum nodeID2 = getNodeID(node2); Coordinate distance = getNodeLength(node1)/2 + getNodeLength(node2)/2; Arc *arc; if (getUniqueness(node1) || getUniqueness(node2)) return; if ((arc = getArcBetweenNodes(node1, node2, graph)) && !getConnectionBetweenNodes(node1, getTwinNode(node2))) { createConnection(nodeID1, -nodeID2, getMultiplicity(arc), 0, distance, 1 / (double) getMultiplicity(arc)); incrementConnectionWeight(getConnectionBetweenNodes (node1, getTwinNode(node2)), getMultiplicity(arc)); } if ((arc = getArcBetweenNodes(node2, node1, graph)) && !getConnectionBetweenNodes(node2, getTwinNode(node1))) { createConnection(nodeID2, -nodeID1, getMultiplicity(arc), 0, distance, 1 / (double) getMultiplicity(arc)); incrementConnectionWeight(getConnectionBetweenNodes (node2, getTwinNode(node1)), getMultiplicity(arc)); } }
static void projectFromReadPair(Node * node, ReadOccurence * readOccurence, Coordinate position, Coordinate offset, Coordinate insertLength, double insertVariance, boolean weight) { Coordinate distance = insertLength; Coordinate variance = insertVariance; Node *target = getNodeInGraph(graph, readOccurence->nodeID); Connection *connect; double score; // Filter for useless reads: if (readOccurence->position == -1 && readOccurence->offset == -1) return; if (target == getTwinNode(node) || target == node) return; if (getUniqueness(target) && getNodeID(target) < getNodeID(node)) return; if (weight) { if (position > 0 && readOccurence->position > 0 && (connect = getConnectionBetweenNodes(node, target))) { distance = getConnectionDistance(connect); distance -= position - offset - getNodeLength(node) / 2; distance -= readOccurence->position - readOccurence->offset - getNodeLength(target) / 2; score = K * exp((insertLength - distance) * (distance - insertLength) / (2 * insertVariance)); incrementConnectionWeight(connect, score); } return; } if (position < 0) { variance += getNodeLength(node) * getNodeLength(node) / 16; // distance += 0; } else { // variance += 0; distance += position - offset - getNodeLength(node) / 2; } if (readOccurence->position < 0) { variance += getNodeLength(target) * getNodeLength(target) / 16; //distance += 0; } else { // variance += 0; distance += readOccurence->position - readOccurence->offset - getNodeLength(target) / 2; } if (distance - getNodeLength(node) / 2 - getNodeLength(target) / 2 < -6 * sqrt(insertVariance)) return; createConnection(getNodeID(node), getNodeID(target), 0, 1, distance, variance); }
static void projectFromSingleRead(Node * node, ReadOccurence * readOccurence, Coordinate position, Coordinate offset, Coordinate length, boolean weight) { Coordinate distance = 0; Connection *connect; Node *target = getNodeInGraph(graph, -readOccurence->nodeID); double variance = 1; // Filter out troublemakers if (readOccurence->position == -1 && readOccurence->offset == -1) return; if (offset < 0 || readOccurence->offset < 0) return; if (target == getTwinNode(node) || target == node) return; if (weight) { if ((connect = getConnectionBetweenNodes(node, target))) { incrementConnectionWeight(connect, 1); } else if ((connect = getConnectionBetweenNodes(getTwinNode(node), getTwinNode(target)))) { incrementConnectionWeight(connect, 1); } return; } if (position < 0) { variance += getNodeLength(node) * getNodeLength(node) / 16; distance += getNodeLength(node) / 2; } else { // variance += 0; distance += position - offset - getNodeLength(node) / 2; } if (readOccurence->position < 0) { variance += getNodeLength(target) * getNodeLength(target) / 16; distance += getNodeLength(target) / 2; } else { // variance += 0; distance += -readOccurence->position + readOccurence->offset + getNodeLength(target) / 2; } if (offset < readOccurence->offset) { if (getNodeLength(node) % 2) distance--; createConnection(getNodeID(node), getNodeID(target), 1, 0, distance, variance); } else { if (getNodeLength(target) % 2) distance++; createConnection(-getNodeID(node), -getNodeID(target), 1, 0, -distance, variance); } }
static void extractNodeASEvents(Node * node, Locus * locus) { Node *nodeA, *nodeB, *nodeC; Event *event; // If linear or more than 2 outgoing arcs: ignore if (countActiveConnections(node) != 2) return; // Follow the two active arcs nodeA = getTwinNode(getConnectionDestination (getActiveConnection(node))); nodeB = getTwinNode(getConnectionDestination (getSecondActiveConnection(node))); // A should be the longer of the two if (getNodeLength(nodeA) < getNodeLength(nodeB)) { nodeC = nodeA; nodeA = nodeB; nodeB = nodeC; nodeC = NULL; } // If both very short, ignore: if (getNodeLength(nodeA) < 2 * getWordLength(graph) - 1) return; if (getNodeLength(nodeB) < 2 * getWordLength(graph) - 1) { if (countActiveConnections(nodeA) != 1 || countActiveConnections(nodeB) != 1 || getConnectionDestination(getActiveConnection(nodeA)) != getConnectionDestination(getActiveConnection(nodeB))) return; nodeC = getTwinNode(getConnectionDestination (getActiveConnection(nodeA))); // Intron retention if (donorSiteAtJunction(node, nodeA) && acceptorSiteAtJunction(nodeA, nodeC)) { event = allocateEvent(); event->type = intron_retention; event->nodes[0] = node; event->nodes[1] = nodeA; event->nodes[2] = nodeB; event->nodes[3] = nodeC; event->next = locus->event; locus->event = event; } // Alternative 5' splice site else if (donorSiteAtJunction(node, nodeA)) { event = allocateEvent(); event->type = alternative_5prime_splice; event->nodes[0] = node; event->nodes[1] = nodeA; event->nodes[2] = nodeB; event->nodes[3] = nodeC; event->next = locus->event; locus->event = event; } // Alternative 3' splice site else if (acceptorSiteAtJunction(nodeA, nodeC)) { event = allocateEvent(); event->type = alternative_3prime_splice; event->nodes[0] = node; event->nodes[1] = nodeA; event->nodes[2] = nodeB; event->nodes[3] = nodeC; event->next = locus->event; locus->event = event; } // Skipped exon else { event = allocateEvent(); event->type = skipped_exon; event->nodes[0] = node; event->nodes[1] = nodeA; event->nodes[2] = nodeB; event->nodes[3] = nodeC; event->next = locus->event; locus->event = event; } } else { // Alt. poly A: if (finishesWithPAS(node) && finishesWithPAS(nodeA)) { event = allocateEvent(); event->type = alternative_polyA; event->nodes[0] = node; event->nodes[1] = nodeA; event->nodes[2] = nodeB; event->nodes[3] = NULL; event->next = locus->event; locus->event = event; } // Mutually exclusive exons if (countActiveConnections(nodeA) == 1 && countActiveConnections(nodeB) == 1 && getConnectionDestination(getActiveConnection(nodeA)) == getConnectionDestination(getActiveConnection(nodeB))) { event = allocateEvent(); event->type = mutually_exclusive_exons; event->nodes[0] = node; event->nodes[1] = nodeA; event->nodes[2] = nodeB; event->nodes[3] = getTwinNode(getConnectionDestination (getActiveConnection(nodeA))); event->next = locus->event; locus->event = event; } } }
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; }
void produceTranscript(Locus * locus, IDnum nodesInList) { IDnum index = 0; Node *node; Transcript *transcript = newTranscript(nodesInList, ((double) nodesInList) / getContigCount(locus)); while ((node = popNodeRecord())) { transcript->contigs[index] = node; if (index > 0) { transcript->distances[index - 1] = getConnectionDistance((getConnectionBetweenNodes(transcript->contigs[index - 1], getTwinNode(node)))); transcript->distances[index - 1] -= getNodeLength(node)/2; transcript->distances[index - 1] -= getNodeLength(transcript->contigs[index - 1])/2; if (getNodeLength(node) % 2 > 0 || getNodeLength(transcript->contigs[index - 1]) % 2 > 0) transcript->distances[index - 1] -= 1; if (transcript->distances[index - 1] < 0) transcript->distances[index - 1] = 0; } index++; } transcript->contigCount = index; addTranscript(locus, transcript); }