예제 #1
0
        /// <summary>
        /// Checks if 'node' can be added to 'link' without
        /// violating any conditions pertaining to dangling links.
        /// Returns null if loop is found or length exceeds threshold.
        /// Otherwise, adds node to link and returns
        /// </summary>
        /// <param name="link">Dangling link</param>
        /// <param name="node">Node to be added</param>
        /// <param name="reachedErrorEndPoint">Indicates if we have reached end of dangling link</param>
        /// <returns>Updated dangling link</returns>
        private DeBruijnPath CheckAndAddDanglingNode(DeBruijnPath link, DeBruijnNode node, out bool reachedErrorEndPoint)
        {
            if (_erodeThreshold != -1 &&
                link.PathNodes.Count == 0 &&
                node.KmerCount < _erodeThreshold)
            {
                if (node.IsMarked())
                {
                    // There is a loop in this link. No need to update link.
                    // Set flag for end point reached as true and return.
                    reachedErrorEndPoint = true;
                    return(link);
                }
                else
                {
                    node.MarkNode();
                    reachedErrorEndPoint = false;
                    return(link);
                }
            }

            if (link.PathNodes.Contains(node))
            {
                // There is a loop in this link. No need to update link.
                // Set flag for end point reached as true and return.
                reachedErrorEndPoint = true;
                return(link);
            }

            if (link.PathNodes.Count >= _lengthThreshold)
            {
                // Length crosses threshold. Not a dangling link.
                // So set reached error end point as true and return null.
                reachedErrorEndPoint = true;
                return(null);
            }

            // No error conditions found. Add node to link.
            reachedErrorEndPoint = false;
            link.PathNodes.Add(node);
            return(link);
        }
예제 #2
0
        /// <summary>
        /// Starting from potential end of dangling link, trace back along
        /// extension edges in graph to find if it is a valid dangling link.
        /// Parallelization Note: No locks used in TraceDanglingLink.
        /// We only read graph structure here. No modifications are made.
        /// </summary>
        /// <param name="isForwardDirection">Boolean indicating direction of dangling link</param>
        /// <param name="link">Dangling Link</param>
        /// <param name="node">Node that is next on the link</param>
        /// <param name="sameOrientation">Orientation of link</param>
        /// <returns>List of nodes in dangling link</returns>
        private DeBruijnPath TraceDanglingExtensionLink(bool isForwardDirection, DeBruijnPath link, DeBruijnNode node, bool sameOrientation)
        {
            Dictionary <DeBruijnNode, DeBruijnEdge> sameDirectionExtensions, oppDirectionExtensions;

            bool reachedEndPoint = false;

            while (!reachedEndPoint)
            {
                // Get extensions going in same and opposite directions.
                if (isForwardDirection ^ sameOrientation)
                {
                    sameDirectionExtensions = node.LeftExtensionNodes;
                    oppDirectionExtensions  = node.RightExtensionNodes;
                }
                else
                {
                    sameDirectionExtensions = node.RightExtensionNodes;
                    oppDirectionExtensions  = node.LeftExtensionNodes;
                }

                if (sameDirectionExtensions.Count == 0)
                {
                    // Found other end of dangling link
                    // Add this and return
                    return(CheckAndAddDanglingNode(link, node, out reachedEndPoint));
                }
                else if (oppDirectionExtensions.Count > 1)
                {
                    // Have reached a point of ambiguity. Return list without updating it
                    if (_erodeThreshold != -1 && !node.IsMarked())
                    {
                        lock (_danglingLinkExtensionTasks)
                        {
                            _danglingLinkExtensionTasks.Add(new Task <int>((o) =>
                                                                           ExtendDanglingLink(isForwardDirection, link, node, sameOrientation, false),
                                                                           TaskCreationOptions.None));
                        }
                        return(null);
                    }

                    return(link);
                }
                else if (sameDirectionExtensions.Count > 1)
                {
                    // Have reached a point of ambiguity. Return list after updating it
                    link = CheckAndAddDanglingNode(link, node, out reachedEndPoint);
                    if (_erodeThreshold != -1 && reachedEndPoint != true && !node.IsMarked())
                    {
                        lock (_danglingLinkExtensionTasks)
                        {
                            _danglingLinkExtensionTasks.Add(new Task <int>((o) =>
                                                                           ExtendDanglingLink(isForwardDirection, link, node, sameOrientation, true),
                                                                           TaskCreationOptions.None));
                        }
                        return(null);
                    }

                    return(link);
                }
                else
                {
                    // (sameDirectionExtensions == 1 && oppDirectionExtensions == 1)
                    // Continue traceback. Add this node to that list and recurse.
                    link = CheckAndAddDanglingNode(link, node, out reachedEndPoint);
                    if (reachedEndPoint)
                    {
                        // Loop is found or threshold length has been exceeded.
                        return(link);
                    }
                    else
                    {
                        node            = sameDirectionExtensions.First().Key;
                        sameOrientation = !(sameOrientation ^ sameDirectionExtensions.First().Value.IsSameOrientation);
                    }
                }
            }

            return(null); // code will never reach here. Valid returns happen within the while loop.
        }