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); } }
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); }
static IDnum expectedNumberOfConnections(IDnum IDA, Connection * connect, IDnum ** counts, Category cat) { Node *A = getNodeInGraph(graph, IDA); Node *B = connect->destination; IDnum IDB = getNodeID(B); double left, middle, right; Coordinate longLength, shortLength, D; double M, N, O, P; Coordinate mu = getInsertLength(graph, cat); double sigma = sqrt(getInsertLength_var(graph, cat)); double result; double densityA, densityB, minDensity; if (mu <= 0) return 0; if (getNodeLength(A) == 0 || getNodeLength(B) == 0) return 0; if (getNodeLength(A) < getNodeLength(B)) { longLength = getNodeLength(B); shortLength = getNodeLength(A); } else { longLength = getNodeLength(A); shortLength = getNodeLength(B); } densityA = counts[cat][IDA + nodeCount(graph)] / (double) getNodeLength(A); densityB = counts[cat][IDB + nodeCount(graph)] / (double) getNodeLength(B); minDensity = densityA > densityB ? densityB : densityA; D = getConnectionDistance(connect) - (longLength + shortLength) / 2; M = (D - mu) / sigma; N = (D + shortLength - mu) / sigma; O = (D + longLength - mu) / sigma; P = (D + shortLength + longLength - mu) / sigma; left = ((norm(M) - norm(N)) - M * normInt(M, N)) * sigma; middle = shortLength * normInt(N, O); right = ((norm(O) - norm(P)) - P * normInt(O, P)) * (-sigma); result = (minDensity * (left + middle + right)); if (result > 0) return (IDnum) result; else return 0; }
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); } }
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 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); } }
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); }