示例#1
0
        /// <summary>
        /// Find the previous eligible sequence for alignment/extension
        /// </summary>
        /// <param name="alignments">List of alignment</param>
        /// <param name="currentAlignment">Current alignment</param>
        /// <returns>Reverse alignment</returns>
        private DeltaAlignment GetPreviousAlignment(
            IList <DeltaAlignment> alignments,
            DeltaAlignment currentAlignment)
        {
            DeltaAlignment deltaAlignment = null;
            int            alignmentFirstEnd, alignmentSecondEnd, gapHigh, gapLow;
            int            alignmentFirstStart  = currentAlignment.FirstSequenceStart;
            int            alignmentSecondStart = currentAlignment.SecondSequenceStart;
            int            distance             = (alignmentFirstStart < alignmentSecondStart)
                    ? alignmentFirstStart
                    : alignmentSecondStart;

            deltaAlignment = null;
            foreach (DeltaAlignment alignment in alignments)
            {
                if (currentAlignment.QueryDirection == alignment.QueryDirection)
                {
                    alignmentFirstEnd  = alignment.FirstSequenceEnd;
                    alignmentSecondEnd = alignment.SecondSequenceEnd;

                    if (alignmentFirstEnd <= alignmentFirstStart &&
                        alignmentSecondEnd <= alignmentSecondStart)
                    {
                        if ((alignmentFirstStart - alignmentFirstEnd)
                            > (alignmentSecondStart - alignmentSecondEnd))
                        {
                            gapHigh = alignmentFirstStart - alignmentFirstEnd;
                            gapLow  = alignmentSecondStart - alignmentSecondEnd;
                        }
                        else
                        {
                            gapLow  = alignmentFirstStart - alignmentFirstEnd;
                            gapHigh = alignmentSecondStart - alignmentSecondEnd;
                        }

                        if (gapHigh < BreakLength ||
                            ((gapLow * nucmerAligner.ValidScore)
                             + ((gapHigh - gapLow)
                                * nucmerAligner.SubstitutionScore)) >= 0)
                        {
                            deltaAlignment = alignment;
                            break;
                        }
                        else if ((gapHigh << 1) - gapLow < distance)
                        {
                            deltaAlignment = alignment;
                            distance       = (gapHigh << 1) - gapLow;
                        }
                    }
                }
            }

            return(deltaAlignment);
        }
示例#2
0
        /// <summary>
        /// Create a new delta alignment
        /// </summary>
        /// <param name="referenceSequence">Reference sequence</param>
        /// <param name="querySequence">Query sequence</param>
        /// <param name="cluster">Cluster object</param>
        /// <param name="match">Match object</param>
        /// <returns>Newly created DeltaAlignment object</returns>
        internal static DeltaAlignment NewAlignment(
            ISequence referenceSequence,
            ISequence querySequence,
            Cluster cluster,
            MaxUniqueMatchExtension match)
        {
            DeltaAlignment deltaAlignment = new DeltaAlignment(referenceSequence, querySequence);

            deltaAlignment.FirstSequenceStart  = match.FirstSequenceStart;
            deltaAlignment.SecondSequenceStart = match.SecondSequenceStart;
            deltaAlignment.FirstSequenceEnd    = match.FirstSequenceStart
                                                 + match.Length
                                                 - 1;
            deltaAlignment.SecondSequenceEnd = match.SecondSequenceStart
                                               + match.Length
                                               - 1;

            deltaAlignment.QueryDirection = cluster.QueryDirection;

            return(deltaAlignment);
        }
示例#3
0
        /// <summary>
        /// Check if the cluster is shadowed (contained in alignment)
        /// </summary>
        /// <param name="alignments">List of alignment</param>
        /// <param name="currentCluster">current cluster</param>
        /// <param name="currentDeltaAlignment">Current delta alignment</param>
        /// <returns>Is cluster contained in alignment</returns>
        private static bool IsClusterShadowed(
            IList <DeltaAlignment> alignments,
            Cluster currentCluster,
            DeltaAlignment currentDeltaAlignment)
        {
            DeltaAlignment alignment = null;
            int            counter;

            int firstSequenceStart = currentCluster.Matches.First().FirstSequenceStart;
            int firstSequenceEnd   = currentCluster.Matches.Last().FirstSequenceStart
                                     + currentCluster.Matches.Last().Length - 1;
            int secondSequenceStart = currentCluster.Matches.First().SecondSequenceStart;
            int secondSequenceEnd   = currentCluster.Matches.Last().SecondSequenceStart
                                      + currentCluster.Matches.Last().Length - 1;

            if (0 < alignments.Count)
            {
                for (counter = alignments.IndexOf(currentDeltaAlignment); counter >= 0; counter--)
                {
                    alignment = alignments[counter];
                    if (alignment.QueryDirection == currentCluster.QueryDirection)
                    {
                        if ((alignment.FirstSequenceEnd >= firstSequenceEnd) &&
                            alignment.SecondSequenceEnd >= secondSequenceEnd &&
                            alignment.FirstSequenceStart <= firstSequenceStart &&
                            alignment.SecondSequenceStart <= secondSequenceStart)
                        {
                            break;
                        }
                    }
                }

                if (counter >= 0)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#4
0
        /// <summary>
        /// Extend the cluster forward
        /// </summary>
        /// <param name="referenceSequence">Reference sequence</param>
        /// <param name="querySequence">Query sequence</param>
        /// <param name="currentAlignment">current alignment object</param>
        /// <param name="targetReference">target position in reference sequence</param>
        /// <param name="targetQuery">target position in query sequence</param>
        /// <param name="methodName">Name of the method to be implemented</param>
        /// <returns>Was cluster extended forward</returns>
        private bool ExtendToNextSequence(
            ISequence referenceSequence,
            ISequence querySequence,
            DeltaAlignment currentAlignment,
            int targetReference,
            int targetQuery,
            int methodName)
        {
            int  referenceDistance;
            int  queryDistance;
            int  diagonal;
            bool isClusterExtended;
            bool isOverflow = false;
            bool isDouble   = false;

            diagonal = currentAlignment.Deltas.Count;

            referenceDistance = targetReference - currentAlignment.FirstSequenceEnd + 1;
            queryDistance     = targetQuery - currentAlignment.SecondSequenceEnd + 1;

            // If the length in first sequence exceeds maximum length then extend
            // till score is optimized irrespective of length.
            if (referenceDistance > NUCmerAligner.MaximumAlignmentLength)
            {
                targetReference = currentAlignment.FirstSequenceEnd + NUCmerAligner.MaximumAlignmentLength + 1;
                isOverflow      = true;
                methodName     |= NUCmerAligner.OptimalFlag;
            }

            // If the length in second sequence exceeds maximum length then extend
            // till score is optimized irrespective of length.
            if (queryDistance > NUCmerAligner.MaximumAlignmentLength)
            {
                targetQuery = currentAlignment.SecondSequenceEnd + NUCmerAligner.MaximumAlignmentLength + 1;
                if (isOverflow)
                {
                    isDouble = true;
                }
                else
                {
                    isOverflow = true;
                }

                methodName |= NUCmerAligner.OptimalFlag;
            }

            if (isDouble)
            {
                methodName &= ~NUCmerAligner.SeqendFlag;
            }

            // Extend the sequence to next sequence (aligned/extended sequence)
            isClusterExtended = nucmerAligner.ExtendSequence(
                referenceSequence,
                currentAlignment.FirstSequenceEnd,
                ref targetReference,
                querySequence,
                currentAlignment.SecondSequenceEnd,
                ref targetQuery,
                currentAlignment.Deltas,
                methodName);

            if (isClusterExtended && isOverflow)
            {
                isClusterExtended = false;
            }

            if (diagonal < currentAlignment.Deltas.Count)
            {
                referenceDistance =
                    (currentAlignment.FirstSequenceEnd - currentAlignment.FirstSequenceStart + 1)
                    - currentAlignment.DeltaReferencePosition - 1;
                currentAlignment.Deltas[diagonal] += (currentAlignment.Deltas[diagonal] > 0)
                    ? referenceDistance
                    : -referenceDistance;

                // Adjust the delta reference position
                foreach (int deltaPosition in currentAlignment.Deltas)
                {
                    currentAlignment.DeltaReferencePosition +=
                        (deltaPosition > 0)
                        ? deltaPosition
                        : Math.Abs(deltaPosition) - 1;
                }
            }

            currentAlignment.FirstSequenceEnd  = targetReference;
            currentAlignment.SecondSequenceEnd = targetQuery;

            return(isClusterExtended);
        }
示例#5
0
        /// <summary>
        /// Extend the cluster backward
        /// </summary>
        /// <param name="referenceSequence">Reference sequence</param>
        /// <param name="querySequence">Query sequence</param>
        /// <param name="alignments">List of alignments</param>
        /// <param name="currentAlignment">current alignment object</param>
        /// <param name="targetAlignment">target alignment object</param>
        /// <returns>Was clusted extended backward</returns>
        private bool ExtendToPreviousSequence(
            ISequence referenceSequence,
            ISequence querySequence,
            IList <DeltaAlignment> alignments,
            DeltaAlignment currentAlignment,
            DeltaAlignment targetAlignment)
        {
            bool isClusterExtended = false;
            bool isOverflow        = false;
            int  targetReference;
            int  targetQuery;
            int  startReference;
            int  startQuery;
            int  methodName = NUCmerAligner.BackwardAlignFlag;

            if (alignments.Contains(targetAlignment))
            {
                targetReference = targetAlignment.FirstSequenceEnd;
                targetQuery     = targetAlignment.SecondSequenceEnd;
            }
            else
            {
                // If the target alignment is not found then extend till the
                // start of sequence (0th Symbol)
                targetReference = 0;
                targetQuery     = 0;
                methodName     |= NUCmerAligner.OptimalFlag;
            }

            // If the length in first sequence exceeds maximum length then extend
            // till score is optimized irrespective of length.
            if ((currentAlignment.FirstSequenceStart - targetReference + 1) > NUCmerAligner.MaximumAlignmentLength)
            {
                targetReference = currentAlignment.FirstSequenceStart - NUCmerAligner.MaximumAlignmentLength + 1;
                isOverflow      = true;
                methodName     |= NUCmerAligner.OptimalFlag;
            }

            // If the length in second sequence exceeds maximum length then extend
            // till score is optimized irrespective of length.
            if ((currentAlignment.SecondSequenceStart - targetQuery + 1) > NUCmerAligner.MaximumAlignmentLength)
            {
                targetQuery = currentAlignment.SecondSequenceStart = NUCmerAligner.MaximumAlignmentLength + 1;
                if (!isOverflow)
                {
                    isOverflow = true;
                }

                methodName |= NUCmerAligner.OptimalFlag;
            }

            // Extend the sequence to previous sequence (aligned/extended sequence)
            isClusterExtended = nucmerAligner.ExtendSequence(
                referenceSequence,
                currentAlignment.FirstSequenceStart,
                ref targetReference,
                querySequence,
                currentAlignment.SecondSequenceStart,
                ref targetQuery,
                currentAlignment.Deltas,
                methodName);

            if (isOverflow || !alignments.Contains(targetAlignment))
            {
                isClusterExtended = false;
            }

            if (isClusterExtended)
            {
                // Extend the sequence to next sequence (aligned/extended sequence)
                ExtendToNextSequence(
                    referenceSequence,
                    querySequence,
                    targetAlignment,
                    currentAlignment.FirstSequenceStart,
                    currentAlignment.SecondSequenceStart,
                    NUCmerAligner.ForcedForwardAlignFlag);

                targetAlignment.FirstSequenceEnd  = currentAlignment.FirstSequenceEnd;
                targetAlignment.SecondSequenceEnd = currentAlignment.SecondSequenceEnd;
            }
            else
            {
                startReference = currentAlignment.FirstSequenceStart;
                startQuery     = currentAlignment.SecondSequenceStart;
                nucmerAligner.ExtendSequence(
                    referenceSequence,
                    targetReference,
                    ref startReference,
                    querySequence,
                    targetQuery,
                    ref startQuery,
                    currentAlignment.Deltas,
                    NUCmerAligner.ForcedForwardAlignFlag);

                currentAlignment.FirstSequenceStart  = targetReference;
                currentAlignment.SecondSequenceStart = targetQuery;

                // Adjust the delta reference position
                foreach (int deltaPosition in currentAlignment.Deltas)
                {
                    currentAlignment.DeltaReferencePosition +=
                        (deltaPosition > 0)
                        ? deltaPosition
                        : Math.Abs(deltaPosition) - 1;
                }
            }

            return(isClusterExtended);
        }
示例#6
0
        /// <summary>
        /// Extend the cluster in synteny
        /// </summary>
        /// <param name="synteny">Synteny in which cluster needs to be extened.</param>
        /// <returns>List of delta alignments</returns>
        private IList <DeltaAlignment> ExtendClusters(Synteny synteny)
        {
            bool isClusterExtended = false;
            IList <DeltaAlignment> deltaAlignments = new List <DeltaAlignment>();
            DeltaAlignment         deltaAlignment  = null;
            DeltaAlignment         targetAlignment = null;
            Cluster currentCluster = null;
            Cluster targetCluster  = synteny.Clusters.Last();
            int     targetReference;
            int     targetQuery;
            int     methodName = NUCmerAligner.ForwardAlignFlag;

            IList <Cluster> clusters = synteny.Clusters;

            // Sort the cluster by first sequence start
            clusters = SortCluster(clusters, FirstSequenceStart);

            IEnumerator <Cluster> previousCluster = clusters.GetEnumerator();

            previousCluster.MoveNext();
            IEnumerator <Cluster> cluster = clusters.GetEnumerator();

            while (cluster.MoveNext())
            {
                currentCluster = cluster.Current;

                if (!isClusterExtended &&
                    (currentCluster.IsFused ||
                     IsClusterShadowed(deltaAlignments, currentCluster, deltaAlignment)))
                {
                    currentCluster.IsFused = true;
                    previousCluster.MoveNext();
                    currentCluster = previousCluster.Current;
                    continue;
                }

                // Extend the match
                foreach (MaxUniqueMatchExtension match in currentCluster.Matches)
                {
                    if (isClusterExtended)
                    {
                        if (deltaAlignment.FirstSequenceEnd != match.FirstSequenceStart ||
                            deltaAlignment.SecondSequenceEnd != match.SecondSequenceStart)
                        {
                            continue;
                        }

                        deltaAlignment.FirstSequenceEnd  += match.Length - 1;
                        deltaAlignment.SecondSequenceEnd += match.Length - 1;
                    }
                    else
                    {
                        deltaAlignment = DeltaAlignment.NewAlignment(
                            synteny.ReferenceSequence,
                            synteny.QuerySequence,
                            currentCluster,
                            match);
                        deltaAlignments.Add(deltaAlignment);

                        // Find the MUM which is a good candidate for extension in reverse direction
                        targetAlignment = GetPreviousAlignment(deltaAlignments, deltaAlignment);

                        if (ExtendToPreviousSequence(
                                synteny.ReferenceSequence,
                                synteny.QuerySequence,
                                deltaAlignments,
                                deltaAlignment,
                                targetAlignment))
                        {
                            deltaAlignment = targetAlignment;
                        }
                    }

                    methodName = NUCmerAligner.ForwardAlignFlag;

                    if (currentCluster.Matches.IndexOf(match) < currentCluster.Matches.Count - 1)
                    {
                        // extend till the match in the current cluster
                        MaxUniqueMatchExtension nextMatch =
                            currentCluster.Matches[currentCluster.Matches.IndexOf(match) + 1];
                        targetReference = nextMatch.FirstSequenceStart;
                        targetQuery     = nextMatch.SecondSequenceStart;

                        isClusterExtended = ExtendToNextSequence(
                            synteny.ReferenceSequence,
                            synteny.QuerySequence,
                            deltaAlignment,
                            targetReference,
                            targetQuery,
                            methodName);
                    }
                    else
                    {
                        // extend till next cluster
                        targetReference = synteny.ReferenceSequence.Count - 1;
                        targetQuery     = synteny.QuerySequence.Count - 1;

                        targetCluster = GetNextCluster(
                            clusters,
                            currentCluster,
                            ref targetReference,
                            ref targetQuery);

                        if (!synteny.Clusters.Contains(targetCluster))
                        {
                            methodName |= NUCmerAligner.OptimalFlag;
                        }

                        isClusterExtended = ExtendToNextSequence(
                            synteny.ReferenceSequence,
                            synteny.QuerySequence,
                            deltaAlignment,
                            targetReference,
                            targetQuery,
                            methodName);
                    }
                }

                if (!synteny.Clusters.Contains(targetCluster))
                {
                    isClusterExtended = false;
                }

                currentCluster.IsFused = true;

                if (!isClusterExtended)
                {
                    previousCluster.MoveNext();
                    currentCluster = previousCluster.Current;
                }
                else
                {
                    currentCluster = targetCluster;
                }
            }

            return(deltaAlignments);
        }