Ejemplo n.º 1
0
        /// <summary>
        /// Classifies the node for purposes of creating a graph where links of singly joined nodes are combined
        /// </summary>
        /// <returns></returns>
        public static NODE_TYPE ClassifyNode(DeBruijnNode startNode)
        {
            var lefts  = startNode.GetLeftExtensionNodes().ToArray();
            var rights = startNode.GetRightExtensionNodes().ToArray();

            if (lefts.Any(x => rights.Contains(x)))
            {
                return(NODE_TYPE.END_LOOPS_ON_ITSELF);
            }
            //First to check if this guy can form an infinite circle with itself
            int validLeftExtensionsCount  = lefts.Length;
            int validRightExtensionsCount = rights.Length;

            if (validLeftExtensionsCount != 1 && validRightExtensionsCount == 1)
            {
                return(NODE_TYPE.GO_RIGHT);
            }
            else if (validLeftExtensionsCount == 1 && validRightExtensionsCount != 1)
            {
                return(NODE_TYPE.GO_LEFT);
            }
            else if (validRightExtensionsCount == 1 && validLeftExtensionsCount == 1)
            {
                return(NODE_TYPE.LINK_IN_CHAIN);
            }
            else if (validRightExtensionsCount > 1 && validLeftExtensionsCount > 1)
            {
                return(NODE_TYPE.NEXUS);
            }
            else if (validLeftExtensionsCount != 1 && validRightExtensionsCount != 1)
            {
                return(NODE_TYPE.ISLAND);
            }
            throw new Exception("Apparently you did not handle all cases...");
        }
Ejemplo n.º 2
0
 public IEnumerable <DeBruijnNode> GetNodesLeavingTop()
 {
     //if chain is longer than one, use previous node to get latest
     if (this.ConstituentNodes.Count > 1)
     {
         var          topNode     = ConstituentNodes[0];
         DeBruijnNode penUltimate = ConstituentNodes[1];
         bool         goingLeft   = penUltimate.GetLeftExtensionNodes().Contains(topNode);
         var          next        = goingLeft ? penUltimate.GetLeftExtensionNodesWithOrientation().Where(x => x.Key == topNode).First() :
                                    penUltimate.GetRightExtensionNodesWithOrientation().Where(x => x.Key == topNode).First();
         var nextSet = goingLeft ^ next.Value ? next.Key.GetRightExtensionNodes() :
                       next.Key.GetLeftExtensionNodes();
         foreach (var k in nextSet)
         {
             yield return(k);
         }
     }
     else
     {
         var baseNode = this.ConstituentNodes[0];
         Debug.Assert(KmerLength == Sequence.Length);
         var  ns = new Sequence(DnaAlphabet.Instance, baseNode.GetOriginalSymbols(MetaNode.KmerLength));
         bool orientationRight;    // = baseNode.GetOriginalSymbols(KmerLength).SequenceEqual(new DnaAlphabet(DnaAlphabet.Instance, Sequence));
         if (ns.ConvertToString().Equals(Sequence))
         {
             orientationRight = true;
         }
         else if ((new Sequence(ns.GetReverseComplementedSequence()).ConvertToString().Equals(Sequence)))
         {
             orientationRight = false;
         }
         else
         {
             throw new Exception("AAA");
         }
         var nextNodes = orientationRight ? baseNode.GetLeftExtensionNodes() : baseNode.GetRightExtensionNodes();
         foreach (var v in nextNodes)
         {
             yield return(v);
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Follow a node with one neighbor on either side and make sure it never reaches itself, which is problematic for making these things.
        /// Note that nodes can go to A->A->C if they refer to themselves but match the reverse compliment of themselves
        /// </summary>
        /// <param name="currentNode"></param>
        /// <param name="goRight"></param>
        /// <param name="graph"></param>
        /// <returns></returns>
        private bool VerifyNotCircular(DeBruijnNode currentNode)
        {
            List <DeBruijnNode> visitedNodes = new List <DeBruijnNode>();

            if (ClassifyNode(currentNode) != NODE_TYPE.LINK_IN_CHAIN)
            {
                throw new Exception("Node type doesn't match well!");
            }
            else
            {
                //go right, if we wind up where we started, circle.
                var  nextNode   = currentNode.GetRightExtensionNodesWithOrientation().First();
                bool goingRight = true;
                //we now either have the second or third node in path as next
                while (ClassifyNode(nextNode.Key) == NODE_TYPE.LINK_IN_CHAIN)
                {
                    visitedNodes.Add(nextNode.Key);
                    //determine if this is a kink or not, which will trigger issue at only first node.
                    if (nextNode.Key == currentNode)
                    {
                        //only one way to get back to the start, either we are in a circle, or the first node loops in to its reverse compliment and exits
                        //the other way, a "kink" so to speak, we know we have visited the right node since we started there, if we visited the left, problems
                        bool leftVisited = visitedNodes.Contains(currentNode.GetLeftExtensionNodes().First());
                        if (leftVisited)
                        {
                            return(false);
                        }
                        Debug.Assert(visitedNodes.Contains(currentNode.GetRightExtensionNodes().First()));
                    }

                    goingRight = !(goingRight ^ nextNode.Value);
                    var nextSet = goingRight ? nextNode.Key.GetRightExtensionNodesWithOrientation() : nextNode.Key.GetLeftExtensionNodesWithOrientation();
                    if (nextSet.Count != 1)
                    {
                        return(true);
                    }
                    nextNode = nextSet.First();
                }
                return(true);
            }
        }