Esempio n. 1
0
        private void MakeCircle(DeBruijnNode startNode, DeBruijnGraph graph)
        {
            CircularLoop = true;
            byte[] v = startNode.GetOriginalSymbols(graph.KmerLength);
            Console.WriteLine((new Sequence(DnaAlphabet.Instance, v)).ToString());
            ConstituentNodes.Add(startNode);
            startNode.IsVisited = true;
            Dictionary <DeBruijnNode, bool> nextNodes;
            bool goRight = true;

            nextNodes = startNode.GetRightExtensionNodesWithOrientation();
            var          nextSet = nextNodes.First();
            DeBruijnNode next    = nextSet.Key;

            while (next != startNode)
            {
                next.IsVisited = true;
                ConstituentNodes.Add(next);
                bool      sameOrientation = nextSet.Value;
                NODE_TYPE nextType        = ClassifyNode(next);
                //what direction do we get the node following the next one from? (Note path out determined by path in, so don't need to look at next node to get side of the one after).
                goRight = (!goRight) ^ sameOrientation;
                if (nextType == NODE_TYPE.LINK_IN_CHAIN)
                {
                    //NOTE: four possibilities condense in to 2 possible sides so written with ^ operator
                    nextNodes = goRight ? next.GetRightExtensionNodesWithOrientation() : next.GetLeftExtensionNodesWithOrientation();
                    //now how to determine what base to get? This only depends on relationship of current node to next node
                    //in all cases we either grab the RC of the first base or the last base, and which to grab is determined by incoming node
                    byte nextSymbol = GetNextSymbol(next, graph.KmerLength, !goRight);
                    contigSequence.Add(nextSymbol);
                }
                else
                {
                    throw new Exception("Non circular path being treated like one");
                }
                nextSet = nextNodes.First();
                next    = nextSet.Key;
            }
            Sequence = (new Sequence((IAlphabet)NoGapDnaAlphabet.Instance, contigSequence.ToArray())).ConvertToString(0, contigSequence.Count);
        }
Esempio n. 2
0
        /// <summary>
        /// This gets the next symbol from a node while forming chains.  This can be made a lot more efficient if it turns in to a bottleneck.
        /// all chains are extended from either the first or last base present in the node, and this base is either forward
        /// or reverse complimented, this method reflects this.
        /// </summary>
        /// <param name="node">Next node</param>
        /// <param name="graph">Graph to get symbol from</param>
        /// <param name="GetFirstNotLast">First or last base?</param>
        /// <param name="ReverseComplimentBase">Should the compliment of the base be returned</param>
        /// <returns></returns>
        public static byte GetNextSymbol(DeBruijnNode node, int kmerLength, bool GetRCofFirstBaseInsteadOfLastBase)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            byte[] symbols = node.GetOriginalSymbols(kmerLength);
            byte   value   = GetRCofFirstBaseInsteadOfLastBase ? symbols.First() : symbols.Last();

            if (GetRCofFirstBaseInsteadOfLastBase)
            {
                byte value2;
                bool rced = DnaAlphabet.Instance.TryGetComplementSymbol(value, out value2);
                //Should never happend
                if (!rced)
                {
                    throw new Exception("Could not revcomp base during graph construction");
                }
                value = value2;
            }
            return(value);
        }