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;
	}
}
Exemple #7
0
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;
}