/// <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); }
/// <summary> /// Process the cluster /// 1. Re-map the reference sequence index to original index /// 2. Create synteny /// 3. Process synteny /// </summary> /// <param name="referenceSequenceList">List of reference sequences</param> /// <param name="clusters">List of clusters</param> /// <returns>List of delta alignments</returns> protected override IList <DeltaAlignment> ProcessCluster( IList <ISequence> referenceSequenceList, IList <Cluster> clusters) { ISequence currentReference = null; ISequence currentQuery = null; IList <Synteny> syntenies = new List <Synteny>(); IList <MaxUniqueMatchExtension> clusterMatches = null; Synteny currentSynteny = null; ISequence referenceSequence = null; ISequence querySequence = null; bool found = false; nucmerAligner.SimilarityMatrix = SimilarityMatrix; nucmerAligner.BreakLength = BreakLength; foreach (Cluster clusterIterator in clusters) { if (null != currentSynteny) { // Remove the empty clusters (if any) if ((null != currentSynteny) && (0 < currentSynteny.Clusters.Count) && (0 == currentSynteny.Clusters.Last().Matches.Count)) { currentSynteny.Clusters.Remove( currentSynteny.Clusters.Last()); } clusterMatches = new List <MaxUniqueMatchExtension>(); currentSynteny.Clusters.Add(new Cluster(clusterMatches)); } foreach (MaxUniqueMatchExtension matchIterator in clusterIterator.Matches) { currentQuery = matchIterator.Query; // Re-map the reference coordinate back to its original sequence foreach (ISequence sequence in referenceSequenceList) { if (matchIterator.FirstSequenceStart < sequence.Count) { currentReference = sequence; break; } else { matchIterator.FirstSequenceStart -= sequence.Count + 1; } } if ((null == referenceSequence) || (null == querySequence) || (string.Compare(referenceSequence.ID, currentReference.ID, StringComparison.OrdinalIgnoreCase) != 0) || string.Compare(querySequence.ID, currentQuery.ID, StringComparison.OrdinalIgnoreCase) != 0) { found = false; if ((null != querySequence) && (string.Compare(querySequence.ID, currentQuery.ID, StringComparison.OrdinalIgnoreCase) == 0)) { // Check if Synteny already exists // If found, mark the synteny and break foreach (Synteny syntenyIterator in syntenies) { if ((String.Compare( syntenyIterator.ReferenceSequence.ID, currentReference.ID, StringComparison.OrdinalIgnoreCase) == 0) && (String.Compare( syntenyIterator.QuerySequence.ID, currentQuery.ID, StringComparison.OrdinalIgnoreCase) == 0)) { currentSynteny = syntenyIterator; found = true; break; } } } else { ProcessSynteny(syntenies); } referenceSequence = currentReference; querySequence = currentQuery; // Remove the empty clusters (if any) if ((null != currentSynteny) && (0 < currentSynteny.Clusters.Count) && (0 == currentSynteny.Clusters.Last().Matches.Count)) { currentSynteny.Clusters.Remove( currentSynteny.Clusters.Last()); } if (!found) { // Create a Synteny currentSynteny = new Synteny( currentReference, currentQuery); // Add a cluster to Synteny syntenies.Add(currentSynteny); } clusterMatches = new List <MaxUniqueMatchExtension>(); currentSynteny.Clusters.Add(new Cluster(clusterMatches)); } if (1 < matchIterator.Length) { currentSynteny.Clusters.Last().Matches.Add(matchIterator); } } } return(ProcessSynteny(syntenies)); }