コード例 #1
0
        /// <summary>
        /// Trace simple path in specified direction.
        /// </summary>
        /// <param name="contigPath">List of graph nodes corresponding to contig path.</param>
        /// <param name="contigSequence">Sequence of contig being assembled.</param>
        /// <param name="isForwardDirection">Boolean indicating direction of path.</param>
        /// <param name="sameOrientation">Path orientation.</param>
        /// <param name="node">Next node on the path.</param>
        /// <param name="createContigSequences">Indicates whether the contig sequences are to be created or not.</param>
        private void TraceSimplePathLinks(
            List<DeBruijnNode> contigPath,
            List<byte> contigSequence,
            bool isForwardDirection,
            bool sameOrientation,
            DeBruijnNode node,
            bool createContigSequences)
        {
            bool endFound = false;
            while (!endFound)
            {
                node.IsVisited = true;
                // Get extensions going in same directions.
                Dictionary<DeBruijnNode, bool> sameDirectionExtensions = (isForwardDirection ^ sameOrientation) 
                    ? node.GetLeftExtensionNodesWithOrientation() 
                    : node.GetRightExtensionNodesWithOrientation();

                if (sameDirectionExtensions.Count == 0)
                {
                    // Found end of path. Add this and return
                    CheckAndAddNode(contigPath, contigSequence, node, isForwardDirection, sameOrientation, createContigSequences);
                    endFound = true;
                }
                else
                {
                    var sameDirectionExtension = sameDirectionExtensions.First();

                    // (sameDirectionExtensions == 1 && oppDirectionExtensions == 1)
                    // Continue traceback in the same direction. Add this node to list and continue.
                    if (!CheckAndAddNode(contigPath, contigSequence, node, isForwardDirection, sameOrientation, createContigSequences))
                    {
                        // Loop is found. Cannot extend simple path further 
                        //Assuming that any node with extensions >2 from either side have been trimmed, this should only be possible if the first
                        //node in list is last node as well, this means there is a circle in the graph of length >1, going to report it
                        if (contigPath != null && contigPath.Count > 0 && contigPath[0] == node)
                        {
                            endFound = true;
                        }
                    }
                    else
                    {
                        node = sameDirectionExtension.Key;
                        sameOrientation =
                            !(sameOrientation ^ sameDirectionExtension.Value);
                    }
                }
            }
        }
コード例 #2
0
ファイル: DanglingLinksPurger.cs プロジェクト: cpatmoore/bio
        /// <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)
        {
            for (; ;)
            {
                // Get extensions going in same and opposite directions.
                Dictionary<DeBruijnNode, bool> sameDirectionExtensions;
                int sameDirectionExtensionsCount, oppDirectionExtensionsCount;
                
                if (isForwardDirection ^ sameOrientation)
                {
                    sameDirectionExtensionsCount = node.LeftExtensionNodesCount;
                    oppDirectionExtensionsCount = node.RightExtensionNodesCount;
                    sameDirectionExtensions = node.GetLeftExtensionNodesWithOrientation();
                }
                else
                {
                    sameDirectionExtensionsCount = node.RightExtensionNodesCount;
                    oppDirectionExtensionsCount = node.LeftExtensionNodesCount;
                    sameDirectionExtensions = node.GetRightExtensionNodesWithOrientation();
                }

                bool reachedEndPoint;
                if (sameDirectionExtensionsCount == 0)
                {
                    // Found other end of dangling link
                    return CheckAndAddDanglingNode(link, node, out reachedEndPoint);
                }

                if (oppDirectionExtensionsCount > 1)
                {
                    // Have reached a point of ambiguity. Return list without updating it.
                    if (this.erodeThreshold != -1 && !node.IsMarkedForDelete)
                    {
                        lock (this.danglingLinkExtensionTasks)
                        {
                            // This task essentially just returns back to this method after other ones are removed
                            this.danglingLinkExtensionTasks.Add(new Task<int>(_ => 
                                ExtendDanglingLink(isForwardDirection, link, node, sameOrientation, false), TaskCreationOptions.None));
                        }
                        return null;
                    }
                    return link;
                }

                if (sameDirectionExtensionsCount > 1)
                {
                    // Have reached a point of ambiguity. Return list after updating it.
                    link = CheckAndAddDanglingNode(link, node, out reachedEndPoint);
                    if (this.erodeThreshold != -1 && reachedEndPoint != true && !node.IsMarkedForDelete)
                    {
                        lock (this.danglingLinkExtensionTasks)
                        {
                            this.danglingLinkExtensionTasks.Add(new Task<int>(_ => 
                                ExtendDanglingLink(isForwardDirection, link, node, sameOrientation, true), TaskCreationOptions.None));
                        }
                        return null;
                    }
                    return link;
                }

                // (sameDirectionExtensions == 1 && oppDirectionExtensions == 1)
                // Continue trace back. 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;
                }

                // Still in loop, so just add the extension and keeps going
                var item = sameDirectionExtensions.First();
                node = item.Key;
                sameOrientation = !(sameOrientation ^ item.Value);
            }
        }
コード例 #3
0
        /// <summary>
        /// Trace simple path starting from 'node' in specified direction.
        /// </summary>
        /// <param name="assembledContigs">List of assembled contigs.</param>
        /// <param name="node">Starting node of contig path.</param>
        /// <param name="isForwardDirection">Boolean indicating direction of path.</param>
        /// <param name="createContigSequences">Boolean indicating whether the contig sequences are to be created or not.</param>
        /// <param name="DuplicatesPossible">Boolean indicating if duplicates are possible, true if both the forward and reverse path could be generated</param>
        private void TraceSimplePath(List<ISequence> assembledContigs, DeBruijnNode node, bool isForwardDirection, bool createContigSequences,bool DuplicatesPossible)
        {
            ISequence nodeSequence = _graph.GetNodeSequence(node);
            List<byte> contigSequence = new List<byte>(nodeSequence);
            node.IsVisited = true;
            List<DeBruijnNode> contigPath = new List<DeBruijnNode> { node };
            KeyValuePair<DeBruijnNode, bool> nextNode =
                isForwardDirection ? node.GetRightExtensionNodesWithOrientation().First() : node.GetLeftExtensionNodesWithOrientation().First();
            
            TraceSimplePathLinks(contigPath, contigSequence, isForwardDirection, nextNode.Value, nextNode.Key, createContigSequences);

            // Check to remove duplicates
            if (!DuplicatesPossible || contigPath[0].NodeValue.CompareTo(contigPath.Last().NodeValue) >= 0)
            {
                // Check contig coverage.
                if (_coverageThreshold != -1)
                {
                    // Definition from Velvet Manual: http://helix.nih.gov/Applications/velvet_manual.pdf
                    // "k-mer coverage" is how many times a k-mer has been seen among the reads.
                    double coverage = contigPath.Average(n => n.KmerCount);
                    if (coverage < _coverageThreshold)
                    {
                        contigPath.ForEach(n => n.MarkNodeForDelete());
                    }
                }
                else
                {
                    if (createContigSequences)
                    {
                        lock (assembledContigs)
                        {
                            assembledContigs.Add(new Sequence(nodeSequence.Alphabet, contigSequence.ToArray()));
                        }
                    }
                }
            }
        }