public ReadToRealignDetails(Read read, int position, bool keepProbeSoftclips = false, bool keepBothSideSoftclips = false) { var freshCigarWithoutTerminalNsRaw = new CigarAlignment(); NPrefixLength = read.GetNPrefix(); NSuffixLength = read.GetNSuffix(); if (keepProbeSoftclips) { if (keepBothSideSoftclips || (!read.BamAlignment.IsReverseStrand() || !read.BamAlignment.IsPaired()) && NPrefixLength == 0) { NPrefixLength = (int)read.CigarData.GetPrefixClip(); } if (keepBothSideSoftclips || (read.BamAlignment.IsReverseStrand() || !read.BamAlignment.IsPaired()) && NSuffixLength == 0) { NSuffixLength = (int)read.CigarData.GetSuffixClip(); } } // Only build up the cigar for the non-N middle. Add the N prefix back on after the realignment attempts. freshCigarWithoutTerminalNsRaw.Add(new CigarOp('M', (uint)(read.Sequence.Length - NPrefixLength - NSuffixLength))); freshCigarWithoutTerminalNsRaw.Compress(); // start with fresh position map var positionMapWithoutTerminalNs = new PositionMap(read.ReadLength - NPrefixLength - NSuffixLength); Read.UpdatePositionMap(position, freshCigarWithoutTerminalNsRaw, positionMapWithoutTerminalNs); PrefixSoftclip = read.CigarData.GetPrefixClip(); SuffixSoftclip = read.CigarData.GetSuffixClip(); SequenceWithoutTerminalNs = read.Sequence.Substring(NPrefixLength, read.Sequence.Length - NPrefixLength - NSuffixLength); PositionMapWithoutTerminalNs = positionMapWithoutTerminalNs; PositionMapLength = positionMapWithoutTerminalNs.Length; FreshCigarWithoutTerminalNs = freshCigarWithoutTerminalNsRaw; Position = position; }
public void FindValidPositionsAndAddBuildings(List <Entity> entities) { PositionMap positionMap = new PositionMap(); for (int i = 0; i < entities.Count; i++) { Entity entity = entities[i]; BuildingComponent buildingComponent = entity.Get <BuildingComponent>(); Building buildingTO = buildingComponent.BuildingTO; if (this.FindValidPositionAndUpdate(entity, buildingTO)) { positionMap.AddPosition(buildingTO.Key, new Position { X = buildingTO.X, Z = buildingTO.Z }); } } Service.Get <ServerAPI>().Enqueue(new BuildingMultiMoveCommand(new BuildingMultiMoveRequest { PositionMap = positionMap })); }
private void LayoutThreadlines(long currentTick) { PositionMap.Clear(); ThreadlineNodes.Clear(); // go through each thread object and position nodes float xOffset = 0; float nodeHeight = 18; float nodeWidth = 18; foreach (var timeline in Threadlines.Values.OrderBy(t => t.ThreadID)) { // do depth correction so we dont have empty columns int fixedDepth = 0; timeline.FixedDepths = new int[timeline.Deepest + 1]; foreach (var depth in timeline.DepthSet) { timeline.FixedDepths[depth] = fixedDepth; fixedDepth++; } timeline.NodeDepths = new ThreadlineNode[timeline.Deepest + 2]; // an extra level to prevent outside bounds exc when checking lower level float yPos = ScreenSize.Height - nodeHeight - 16; float colWidth = timeline.Deepest * nodeWidth + 100; string label = "#" + timeline.ThreadID.ToString() + ": " + timeline.Name; float x = ScreenOffset.X + xOffset + 2; float y = ScreenOffset.Y + yPos + nodeHeight + 2; Renderer.DrawString(label, TextFont, timeline.IsAlive ? Color.Black : Color.Gray, x, y, colWidth, 18); foreach (var item in timeline.Sequence) { var node = NodeModels[item.NodeID]; PositionMap[node.ID] = node; int depth = timeline.FixedDepths[item.Depth]; float xPos = xOffset + nodeWidth * depth; var area = new RectangleF(ScreenOffset.X + xPos, ScreenOffset.Y + yPos, nodeHeight, nodeWidth); // only light up the latest node if (!AddedNodes.Contains(node.ID)) { node.RoomForLabel = true; node.SetArea(area); } // extend this node down to the previous nodes (future node) depth bool foundPrev = false; for (int i = depth + 1; i < timeline.NodeDepths.Length; i++) { if (!foundPrev && timeline.NodeDepths[i] != null) { area.Height = timeline.NodeDepths[i].Area.Bottom - area.Top; foundPrev = true; } timeline.NodeDepths[i] = null; } bool showHit = false; if (item.EndTick == 0 || Utilities.TicksToSeconds(currentTick - item.StartTick) < 1.0) // of started in last second { showHit = true; } float labelX = ScreenOffset.X + xPos + nodeWidth + 3; float labelWidth = colWidth - nodeWidth * (depth + 1) - 3; var labelArea = new RectangleF(labelX, ScreenOffset.Y + yPos + 1, labelWidth, nodeHeight); var entry = new ThreadlineNode() { Node = node, Area = area, LabelArea = labelArea, ShowHit = showHit }; if (timeline.NodeDepths[depth] == null) { timeline.NodeDepths[depth] = entry; } ThreadlineNodes.Add(entry); yPos -= nodeHeight; } xOffset += colWidth; } }
public void DrawCallGraph() { if (DoRevalue || XRay.CallChange || (ShowLayout != ShowNodes.All && XRay.CoverChange) || (ShowLayout == ShowNodes.Instances && XRay.InstanceChange)) { RecalcCover(InternalRoot); RecalcCover(ExternalRoot); PositionMap.Clear(); CenterMap.Clear(); var root = CurrentRoot; //causes method graph with ShowExternal on to show nothing //if (root == InternalRoot && ShowExternal) // root = TopRoot; TopGraph = new GraphSet(this, root); // combine position and center maps for graph tree Utilities.RecurseTree( TopGraph, s => { foreach (var kvp in s.PositionMap) { PositionMap[kvp.Key] = kvp.Value; } foreach (var id in s.CenterMap) { CenterMap.Add(id); } }, s => s.Subsets.Values ); XRay.CallChange = false; XRay.CoverChange = false; XRay.InstanceChange = false; DoRevalue = false; RevalueCount++; DoResize = true; } // graph created in relative coords so it doesnt need to be re-computed each resize, only on recalc if (DoResize) { Utilities.RecurseTree( TopGraph, s => { foreach (var graph in s.Graphs) { if (s.GraphContainer == null) { ScaleGraph(graph, new RectangleF(ScreenOffset, ScreenSize)); } else if (s.GraphContainer.XNode.External) { // this is assuming the external node is a triangle var area = s.GraphContainer.AreaF; var inside = new RectangleF(area.X + area.Width / 4f, area.Y + area.Height / 2f, area.Width / 2f, area.Height / 2f); ScaleGraph(graph, inside); } else { ScaleGraph(graph, s.GraphContainer.AreaF); } } }, s => s.Subsets.Values ); DoResize = false; ResizeCount++; } }
public static int GetSumOfMismatchQualities(byte[] quals, string readSequence, PositionMap positionMap, string refSequence, int startIndexInRefSequence = 0) { var matchMap = GetMismatchMap(readSequence, positionMap, refSequence, startIndexInRefSequence); return(GetSumOfMismatchQualities(matchMap, quals)); }
internal static extern double ecore_animator_pos_map_n(double pos, PositionMap map, int v_size, double[] v);
private static PositionMap _ParseChildren(ElementNode parentNode, PositionValue parentPosition) { // Traverse every node. Nodes with the position property will affect the childrens' // positions. PositionMap childValues = new PositionMap(); PositionModule positionProperty = parentNode.Properties.Get(PositionDescriptor._typeId) as PositionModule; foreach (ElementNode childNode in parentNode.Children) { PositionValue childPosition = positionProperty.GetPositionValues(childNode.Id); if (childPosition != null) { // Parent has a modifying position for the child. childPosition = _Multiply(parentPosition, childPosition); } else { // Child inherits parent's position. childPosition = new PositionValue(parentPosition); } childValues[childNode.Id] = childPosition; childValues.AddRange(_ParseChildren(childNode, childPosition)); } return childValues; }
public static void SearchMeposPositions(ILogger <Worker> logger) { // Configue all the meepos positions (How can we calculate the first position of the meepo bar? ) PositionMap.RecalculateMeepos(logger); }
internal static extern double ecore_animator_pos_map(double pos, PositionMap map, double v1, double v2);
public void MoveMap(Location location) { PositionMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(location.Latitude, location.Longitude), Distance.FromKilometers(Settings.SearchRadius)), true); }
private RealignmentResult AddIndelAndGetResult(string readSequence, CandidateIndel priorIndel, string refSequence, bool anchorLeft, PositionMap positionMap) { var foundIndel = false; var insertionPostionInReadStart = -1; var insertionPositionInReadEnd = -1; if (anchorLeft) { // move along position map to see if we can insert indel for (var i = 0; i < positionMap.Length; i++) { if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition && i != positionMap.Length - 1) // make sure we dont end right before indel { foundIndel = true; if (priorIndel.Type == AlleleCategory.Insertion) { insertionPostionInReadStart = i + 1; // stick in -1 for insertion length, then adjust positions after for (var j = i + 1; j < positionMap.Length; j++) { if (j - i <= priorIndel.Length) { positionMap.UpdatePositionAtIndex(j, -1, true); if (j - i == priorIndel.Length || j == positionMap.Length - 1) { insertionPositionInReadEnd = j; } } else { if (positionMap.GetPositionAtIndex(j) != -1) // preserve existing insertions { positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) - priorIndel.Length); } } } break; } if (priorIndel.Type == AlleleCategory.Deletion) { // offset positions after deletion for (var j = i + 1; j < positionMap.Length; j++) { if (positionMap.GetPositionAtIndex(j) != -1) // preserve existing insertions { positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) + priorIndel.Length); } } break; } } } } else { // walk backwards along position map to see if we can insert indel if (priorIndel.Type == AlleleCategory.Insertion) { for (var i = positionMap.Length - 1; i >= 0; i--) { if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition + 1 && i != 0) { foundIndel = true; insertionPositionInReadEnd = i - 1; } else if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition && i != positionMap.Length - 1) { foundIndel = true; insertionPositionInReadEnd = i; } if (foundIndel) { // stick in -1 for insertion length, then adjust positions for (var j = insertionPositionInReadEnd; j >= 0; j--) { if (insertionPositionInReadEnd - j + 1 <= priorIndel.Length) { positionMap.UpdatePositionAtIndex(j, -1, true); if (insertionPositionInReadEnd - j + 1 == priorIndel.Length || j == 0) { insertionPostionInReadStart = j; } } else { if (positionMap.GetPositionAtIndex(j) != -1) // Don't update position map for things that were already -1 { positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) + priorIndel.Length); } } } break; } } } else if (priorIndel.Type == AlleleCategory.Deletion) { for (var i = positionMap.Length - 1; i >= 1; i--) { if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition + priorIndel.Length + 1) //deletions must be fully anchored to be observed { foundIndel = true; // offset positions after deletion for (var j = i - 1; j >= 0; j--) { if (positionMap.GetPositionAtIndex(j) != -1) // preserve existing insertions { positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) - priorIndel.Length); } } break; } } } } if (!foundIndel || !Helper.IsValidMap(positionMap.Map, refSequence)) { return(null); } // verify insertion matches if (priorIndel.Type == AlleleCategory.Insertion) { if (insertionPostionInReadStart == -1 || insertionPositionInReadEnd == -1) { return(null); // weird, this shouldnt ever happen } var readInsertedSequence = readSequence.Substring(insertionPostionInReadStart, insertionPositionInReadEnd - insertionPostionInReadStart + 1); var indelSequence = priorIndel.AlternateAllele.Substring(1); var clippedPriorSequence = anchorLeft ? indelSequence.Substring(0, readInsertedSequence.Length) : indelSequence.Substring(indelSequence.Length - readInsertedSequence.Length); var mismatches = Helper.GetNumMismatches(readInsertedSequence, clippedPriorSequence); if (mismatches == null || mismatches > 0) { return(null); // inserted sequence doesn't match read } } var newCigar = Helper.ConstructCigar(positionMap.Map); var newSummary = Extensions.GetAlignmentSummary(positionMap.FirstMappableBase() - 1, newCigar, refSequence, readSequence); if (newSummary == null) { return(null); } var readHasPosition = positionMap.HasAnyMappableBases(); if (!readHasPosition) { throw new InvalidDataException(string.Format("Trying to generate result and read does not have any alignable bases. ({0}, {1})", newCigar, string.Join(",", positionMap))); } return(new RealignmentResult() { Cigar = newCigar, NumIndels = newCigar.NumIndels(), Position = positionMap.FirstMappableBase(), NumMismatches = newSummary.NumMismatches, NumNonNMismatches = newSummary.NumNonNMismatches, NumMismatchesIncludeSoftclip = newSummary.NumMismatchesIncludeSoftclip, NumSoftclips = newSummary.NumSoftclips, NumNonNSoftclips = newSummary.NumNonNSoftclips, NumIndelBases = newSummary.NumIndelBases }); }
private RealignmentResult AddIndelAndGetResult(string readSequence, HashableIndel priorIndel, string refSequence, bool anchorLeft, PositionMap positionMap, int refSequenceStartIndex, bool pairSpecific) { var foundIndel = false; var insertionPostionInReadStart = -1; var insertionPositionInReadEnd = -1; var deletionPositionInRead = -1; bool anyPositionsAfterDeletionMapped = false; // TODO PERF can we bail out early if it's not possible that the indel could be inserted in the read, based on position? if (anchorLeft) { // move along position map to see if we can insert indel for (var i = 0; i < positionMap.Length; i++) { if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition && i != positionMap.Length - 1) // make sure we dont end right before indel { foundIndel = true; if (priorIndel.Type == AlleleCategory.Insertion) { insertionPostionInReadStart = i + 1; // stick in -1 for insertion length, then adjust positions after for (var j = i + 1; j < positionMap.Length; j++) { if (j - i <= priorIndel.Length) { positionMap.UpdatePositionAtIndex(j, -1, true); if (j - i == priorIndel.Length || j == positionMap.Length - 1) { insertionPositionInReadEnd = j; } } else { if (positionMap.GetPositionAtIndex(j) != -1) // preserve existing insertions { positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) - priorIndel.Length); } } } break; } if (priorIndel.Type == AlleleCategory.Deletion) { deletionPositionInRead = i; // offset positions after deletion for (var j = i + 1; j < positionMap.Length; j++) { if (positionMap.GetPositionAtIndex(j) != -1) // preserve existing insertions { anyPositionsAfterDeletionMapped = true; positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) + priorIndel.Length); } } break; } } } } else { // walk backwards along position map to see if we can insert indel if (priorIndel.Type == AlleleCategory.Insertion) { for (var i = positionMap.Length - 1; i >= 0; i--) { if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition + 1 && i != 0) { foundIndel = true; insertionPositionInReadEnd = i - 1; } else if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition && i != positionMap.Length - 1) { foundIndel = true; insertionPositionInReadEnd = i; } if (foundIndel) { // stick in -1 for insertion length, then adjust positions for (var j = insertionPositionInReadEnd; j >= 0; j--) { if (insertionPositionInReadEnd - j + 1 <= priorIndel.Length) { positionMap.UpdatePositionAtIndex(j, -1, true); if (insertionPositionInReadEnd - j + 1 == priorIndel.Length || j == 0) { insertionPostionInReadStart = j; } } else { if (positionMap.GetPositionAtIndex(j) != -1) // Don't update position map for things that were already -1 { positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) + priorIndel.Length); } } } break; } } } else if (priorIndel.Type == AlleleCategory.Deletion) { for (var i = positionMap.Length - 1; i >= 1; i--) { if (positionMap.GetPositionAtIndex(i) == priorIndel.ReferencePosition + priorIndel.Length + 1) //deletions must be fully anchored to be observed { foundIndel = true; deletionPositionInRead = i - 1; // offset positions after deletion for (var j = i - 1; j >= 0; j--) { if (positionMap.GetPositionAtIndex(j) != -1) // preserve existing insertions { anyPositionsAfterDeletionMapped = true; positionMap.UpdatePositionAtIndex(j, positionMap.GetPositionAtIndex(j) - priorIndel.Length); } } break; } } } } //if (!foundIndel || !Helper.IsValidMap(positionMap, refSequence)) //TODO changed this just for tailor if (!foundIndel || (priorIndel.Type == AlleleCategory.Deletion && !anyPositionsAfterDeletionMapped) || !Helper.IsValidMap(positionMap.Map)) { return(null); } var isSketchy = false; if (priorIndel.IsRepeat) { //if (priorIndel.Type == AlleleCategory.Deletion) //{ // if (Helper.RepeatDeletionFlankedByRepeats(readSequence, priorIndel, deletionPositionInRead)) // { // return null; // } //} //// TODO in the case of using sketchy anchor test: //// Ideally, we'd check the anchor length against how many repeats are in the reference vs the variant, //// ... Or maybe just always check the whole anchor if it's a repeat. var anchorLength = priorIndel.Type == AlleleCategory.Insertion ? Math.Min(insertionPostionInReadStart, readSequence.Length - insertionPositionInReadEnd) : Math.Min(deletionPositionInRead, readSequence.Length - deletionPositionInRead); if (anchorLength >= readSequence.Length) { throw new Exception("Anchor should never be longer than read length."); // TODO remove after dev. } if (anchorLength < Math.Max(10, priorIndel.Length)) { if (priorIndel.Type == AlleleCategory.Deletion) { if (Helper.DeletionHasSketchyAnchor(readSequence, priorIndel, deletionPositionInRead)) { if (pairSpecific) { isSketchy = true; } else { return(null); } } } else { if (priorIndel.NumBasesInReferenceSuffixBeforeUnique >= anchorLength) { if (pairSpecific) { isSketchy = true; } else { return(null); } } } } } // TODO do we need to be more nuanced about this and only do it in duplication areas? if (priorIndel.Type == AlleleCategory.Deletion) { var anchorStart = deletionPositionInRead + 1; var rightAnchorLength = readSequence.Length - anchorStart; if (rightAnchorLength < priorIndel.Length) { if (anchorStart < readSequence.Length) { if (readSequence.Substring(anchorStart) == priorIndel.ReferenceAllele.Substring(1, rightAnchorLength)) { return(null); } } } } if (priorIndel.IsDuplication && priorIndel.Type == AlleleCategory.Insertion) { // TODO return to this - I think the thought was to prevent FP dups, but the implementation may have been wrong // No partial duplications? //if (readSequence.Length - insertionPositionInReadEnd <= priorIndel.Length) if (readSequence.Length - insertionPositionInReadEnd <= 3) { // Assumes priors are left-aligned return(null); } } //verify insertion matches var newReadSequence = readSequence; var nifiedAt = new List <int>(); if (priorIndel.Type == AlleleCategory.Insertion) { if (insertionPostionInReadStart == -1 || insertionPositionInReadEnd == -1) { return(null); // weird, this shouldnt ever happen } var readInsertedSequence = readSequence.Substring(insertionPostionInReadStart, insertionPositionInReadEnd - insertionPostionInReadStart + 1); var indelSequence = priorIndel.AlternateAllele.Substring(1); if (anchorLeft && readInsertedSequence.Length < indelSequence.Length && priorIndel.NumApproxDupsRight > 0) { // Don't allow partial realignment to dups return(null); } if (!anchorLeft && readInsertedSequence.Length < indelSequence.Length && priorIndel.NumApproxDupsLeft > 0) { // Don't allow partial realignment to dups return(null); } var clippedPriorSequence = anchorLeft ? indelSequence.Substring(0, readInsertedSequence.Length) : indelSequence.Substring(indelSequence.Length - readInsertedSequence.Length); var isMismatch = readInsertedSequence != clippedPriorSequence; if (isMismatch) { int?mismatches = null; var mismatchesToDq = 0d; if (priorIndel.Length >= _minInsertionSizeToAllowMismatchingBases && !(priorIndel.NumApproxDupsLeft + priorIndel.NumApproxDupsRight > 0)) { mismatches = Helper.GetHammingNumMismatches(readInsertedSequence, clippedPriorSequence); mismatchesToDq = priorIndel.Length * _maxProportionInsertSequenceMismatch; if (mismatches > mismatchesToDq) { //Console.WriteLine( // $"Too many mismatches between insertions: {mismatches} > {maxAllowedMismatches} ({clippedPriorSequence} vs {readInsertedSequence})"); } else { //Console.WriteLine( // $"Able to Nify mismatches between insertions: {mismatches} <= {maxAllowedMismatches} ({clippedPriorSequence} vs {readInsertedSequence})"); var newSequence = Helper.NifyMismatches(clippedPriorSequence, readInsertedSequence, nifiedAt); // TODO PERF is this actually necessary now that we're not actually Nifying? We can just keep the bases that we're Nifying at. newReadSequence = readSequence.Substring(0, insertionPostionInReadStart) + newSequence.ToLower() + readSequence.Substring(insertionPositionInReadEnd + 1); nifiedAt = nifiedAt.Select(x => x + insertionPostionInReadStart).ToList(); } } if (mismatches == null || (mismatches > mismatchesToDq)) { return(null); // inserted sequence doesn't match read } } } // TODO update to use PositionMap class var newCigar = Helper.ConstructCigar(positionMap.Map); // TODO moved this, and probably should in original Hygea too? // Also, can cut down the calls to positionmap.First() in the original //var readHasPosition = positionMap.Any(p => p > 0); // Position map is one-based, so should be >, not >= 0. if (!positionMap.HasAnyMappableBases()) { throw new InvalidDataException(string.Format("Trying to generate result and read does not have any alignable bases. ({0}, {1})", newCigar, string.Join(",", positionMap))); } var startIndexInReference = positionMap.FirstMappableBase() - 1; // Position map is one-based, so should be >, not >= 0. var startIndexInRefSequenceSnippet = startIndexInReference - refSequenceStartIndex; var newSummary = Extensions.GetAlignmentSummary(startIndexInRefSequenceSnippet, newCigar, refSequence, newReadSequence, _trackActualMismatches, _checkSoftclipsForMismatches); if (newSummary == null) { return(null); } return(new RealignmentResult() { Cigar = newCigar, NumIndels = newCigar.NumIndels(), Position = startIndexInReference + 1, NumMismatches = newSummary.NumMismatches, NumNonNMismatches = newSummary.NumNonNMismatches, NumSoftclips = newSummary.NumSoftclips, NumNonNSoftclips = newSummary.NumNonNSoftclips, NumDeletedBases = newSummary.NumDeletedBases, NumInsertedBases = newSummary.NumInsertedBases, NumMatches = newSummary.NumMatches, NumIndelBases = newSummary.NumIndelBases, NumMismatchesIncludeSoftclip = newSummary.NumMismatchesIncludeSoftclip, MismatchesIncludeSoftclip = newSummary.MismatchesIncludeSoftclip, Indels = StringifyIndel(priorIndel), NifiedAt = nifiedAt, IndelsAddedAt = new List <int> { priorIndel.Type == AlleleCategory.Insertion ? insertionPostionInReadStart : deletionPositionInRead }, IsSketchy = isSketchy }); }
private RealignmentResult RealignForAnchor(HashableIndel[] indels, Dictionary <HashableIndel, GenomeSnippet> indelContexts, Read read, bool anchorOnLeft, ReadToRealignDetails details, bool pairSpecific, int[] indexes) { try { var freshCigarWithoutTerminalNs = new CigarAlignment(details.FreshCigarWithoutTerminalNs); var freshPositionMap = new PositionMap(details.PositionMapLength); for (int i = 0; i < details.PositionMapLength; i++) { freshPositionMap.UpdatePositionAtIndex(i, details.PositionMapWithoutTerminalNs.GetPositionAtIndex(i)); } var result = new RealignmentResult(); // layer on indels one by one, indels already sorted by ascending position if (LayerOnIndels(indels, indelContexts, anchorOnLeft, details.SequenceWithoutTerminalNs, freshPositionMap, ref result, pairSpecific)) { return(null); } var context = indelContexts[indels[0]]; // Softclip partial insertions at read ends if (_maskPartialInsertion || _minimumUnanchoredInsertionLength > 0) { MaskPartialInsertion(indels, read, context.Sequence, result, context.StartPosition); } _softclipReapplier.ReapplySoftclips(read, details.NPrefixLength, details.NSuffixLength, freshPositionMap, result, context, details.PrefixSoftclip, details.SuffixSoftclip, freshCigarWithoutTerminalNs); result.AcceptedIndels = new List <int>(); result.AcceptedHashableIndels = new List <HashableIndel>(); for (int i = 0; i < result.AcceptedIndelsInSubList.Count; i++) { // TODO do we need to be more nuanced about this and only do it in duplication areas? var currentSubIndex = result.AcceptedIndelsInSubList[i]; result.AcceptedIndels.Add(indexes[currentSubIndex]); var currentIndel = indels[currentSubIndex]; result.AcceptedHashableIndels.Add(currentIndel); if (currentIndel.Type == AlleleCategory.Deletion) { var addedAt = result.IndelsAddedAt[i]; var anchorStart = addedAt + 1; var lastOp = result.Cigar[result.Cigar.Count - 1]; var rightSoftclipLength = lastOp.Type == 'S' ? (int)lastOp.Length : 0; var rightAnchorLength = read.Sequence.Length - anchorStart - rightSoftclipLength; if (rightAnchorLength < currentIndel.Length && anchorStart < read.Sequence.Length) { if (read.Sequence.Substring(anchorStart, rightAnchorLength) == currentIndel.ReferenceAllele.Substring(1, rightAnchorLength)) { return(null); } } } } if (result.SumOfMismatchingQualities == null) { result.SumOfMismatchingQualities = Helper.GetSumOfMismatchQualities(read.Qualities, read.Sequence, freshPositionMap, context.Sequence, context.StartPosition); } result.Indels = string.Join("|", indels.Select(x => StringifyIndel(x))); return(result); } catch (Exception e) { if (_debug) { Logger.WriteExceptionToLog(new Exception($"Realign for anchor failed: read '{read.Name}' with indels {(string.Join("|", indels.Select(x => StringifyIndel(x))))}, anchoring on {(anchorOnLeft ? "left" : "right")}.", e)); } return(null); } }
public PositionData() { ChildrenPositions = new PositionMap(); }
/* internal void setUserState (object obj) { userState = obj; }*/ //caller should not change input after it is passed in. internal ParseContext(int at, string module, PositionMap pmap) { //this.userState = us; this.step = 0; this.at = at; this.module = module; this.pmap = pmap; }
//caller should not change input after it is passed in. internal ParserState(Tok[] input, int at, string module, PositionMap pmap, int end_index, string eof_str, ShowToken show) : base(at, module, pmap) { this.input = input; this.sys_unexpected = new ParsecError[input.Length]; this.show = show; this.end_index = end_index; this.eof_unexpected = ParsecError.raiseSysUnexpected( end_index, eof_str); }
internal ScannerState(string src, int a, string module, PositionMap pmap, int l) : base(a, module, pmap) { this.src = src; this.len = l; }
public void Render() { // clear and pre-process marked depencies RecalcDependencies(); // figure out if we need to do a search if (SearchString != LastSearch) { DoSearch(); } // draw layout ScreenSize.Width = Renderer.ViewWidth * ZoomFactor; ScreenSize.Height = Renderer.ViewHeight * ZoomFactor; ScreenOffset.X = PanOffset.X * ScreenSize.Width; // +(Width * CenterFactor.X - ModelSize.Width * CenterFactor.X); ScreenOffset.Y = PanOffset.Y * ScreenSize.Height; // +(Height * CenterFactor.Y - ModelSize.Height * CenterFactor.Y); if (ViewLayout == LayoutType.TreeMap) { DrawTreeMap(Renderer); if (ShowingOutside) { Renderer.DrawTextBackground(XColors.BorderColor, InternalRoot.AreaF.Width, 0, PanelBorderWidth, InternalRoot.AreaF.Height); DrawNode(InternalRoot, 0, true); } if (ShowingExternal) { Renderer.DrawTextBackground(XColors.BorderColor, ExternalRoot.AreaF.X - PanelBorderWidth, 0, PanelBorderWidth, ExternalRoot.AreaF.Height); DrawNode(ExternalRoot, 0, true); } DrawNode(CurrentRoot, 0, true); } else if (ViewLayout == LayoutType.CallGraph) { DrawCallGraph(); // id 0 nodes are intermediates foreach (var node in PositionMap.Values) { //foreach (var node in Graphs.SelectMany(g => g.Nodes()).Where(n => n.ID != 0)) DrawNode(node, 0, false); } } else if (ViewLayout == LayoutType.Timeline) { DrawTheadline(); foreach (var node in ThreadlineNodes) { DrawNode(node.Node, node.Area, node.LabelArea, 0, false, node.ShowHit); } } // draw ignored over nodes ignored may contain /*foreach (var ignored in IgnoredNodes.Values) * if (PositionMap.ContainsKey(ignored.ID)) * { * Renderer.DrawLine(XColors.IgnoredColor, 1, ignored.AreaF.UpperLeftCorner(), ignored.AreaF.LowerRightCorner(), false); * Renderer.DrawLine(XColors.IgnoredColor, 1, ignored.AreaF.UpperRightCorner(), ignored.AreaF.LowerLeftCorner(), false); * }*/ // draw dividers for call graph /*if (ViewLayout == LayoutType.CallGraph) * { * if (ShowRightOutsideArea) * buffer.DrawLine(CallDividerPen, RightDivider, 0, RightDivider, Height); * * if (ShowLeftOutsideArea) * buffer.DrawLine(CallDividerPen, LeftDivider, 0, LeftDivider, Height); * }*/ // draw dependency graph if (ViewLayout == LayoutType.CallGraph && (GraphMode == CallGraphMode.Dependencies || GraphMode == CallGraphMode.Init || GraphMode == CallGraphMode.Intermediates)) { foreach (var source in PositionMap.Values) { if (source.EdgesOut == null) { continue; } foreach (var to in source.EdgesOut) { if (!PositionMap.ContainsKey(to)) { continue; } var destination = PositionMap[to]; int penWidth = (source.Focused || destination.Focused) ? 2 : 1; if ((!DrawCallGraphVertically && source.AreaF.X < destination.AreaF.X) || (DrawCallGraphVertically && source.AreaF.Y < destination.AreaF.Y)) { DrawGraphEdge(penWidth, XColors.CallOutColor, source, destination); } else { DrawGraphEdge(penWidth, XColors.CallInColor, source, destination); } } } } // draw call graph if (XRay.FlowTracking && ViewLayout != LayoutType.Timeline) { foreach (var source in PositionMap.Values) { if (source.XNode.CallsOut == null) { continue; } if (ViewLayout == LayoutType.TreeMap && source.ObjType == XObjType.Class && ShowMethods) { continue; } if (ViewLayout == LayoutType.CallGraph && GraphMode != CallGraphMode.Init && source.ObjType == XObjType.Class && ShowMethods) { continue; } foreach (var call in source.XNode.CallsOut) { if (!PositionMap.ContainsKey(call.Destination)) { continue; } if (ShowThreads != null && !call.ThreadIDs.Any(id => ShowThreads.Contains(id))) { continue; } var destination = PositionMap[call.Destination]; // if there are items we're filtering on then only show calls to those nodes if (FilteredNodes.Count > 0 && !IsNodeFiltered(true, source) && !IsNodeFiltered(true, destination)) { continue; } // do after select filter so we can have ignored nodes inside selected, but not the otherway around if (IgnoredNodes.Count > 0 && IsNodeFiltered(false, source) || IsNodeFiltered(false, destination)) { continue; } int lineWidth = (source.Focused || destination.Focused) ? 2 : 1; if (call.StillInside > 0 && ShowCalls) { if (ViewLayout == LayoutType.TreeMap) { Renderer.DrawCallLine(XColors.HoldingCallColor, lineWidth, source.CenterF, destination.CenterF, false, source, destination); } else if (ViewLayout == LayoutType.CallGraph) { DrawGraphEdge(lineWidth, XColors.HoldingCallColor, source, destination); } } else if (ShowAllCalls && GraphMode != CallGraphMode.Intermediates && GraphMode != CallGraphMode.Init) { if (ViewLayout == LayoutType.TreeMap) { var callSource = PositionMap[call.Source]; var callDest = PositionMap[call.Destination]; PointF start = callSource.CenterF; PointF end = callDest.CenterF; PointF mid = new PointF(start.X + (end.X - start.X) / 2, start.Y + (end.Y - start.Y) / 2); Renderer.DrawCallLine(XColors.CallOutColor, lineWidth, start, mid, false, callSource, callDest); Renderer.DrawCallLine(XColors.CallInColor, lineWidth, mid, end, false, callSource, callDest); } else if (ViewLayout == LayoutType.CallGraph) { if ((!DrawCallGraphVertically && source.AreaF.X < destination.AreaF.X) || (DrawCallGraphVertically && source.AreaF.Y < destination.AreaF.Y)) { DrawGraphEdge(lineWidth, XColors.CallOutColor, source, destination); } else { DrawGraphEdge(lineWidth, XColors.CallInColor, source, destination); } } } if (call.Hit > 0 && ShowCalls) { var color = XColors.CallPenColors[call.Hit]; if (ViewLayout == LayoutType.TreeMap) { Renderer.DrawCallLine(color, lineWidth, source.CenterF, destination.CenterF, true, source, destination); } else if (ViewLayout == LayoutType.CallGraph) { DrawGraphEdge(lineWidth, color, source, destination, true); } } } } } XRay.DashOffset = (XRay.DashOffset == 0) ? 2 : XRay.DashOffset - 1; // draw mouse over label if (ViewLayout != LayoutType.Timeline) { DrawFooterLabel(); } DrawToolTip(); }
public void ReapplySoftclips(Read read, int nPrefixLength, int nSuffixLength, PositionMap positionMapWithoutTerminalNs, RealignmentResult result, GenomeSnippet context, uint prefixSoftclip, uint suffixSoftclip, CigarAlignment freshCigarWithoutTerminalNs) { // Re-append the N-prefix var nPrefixPositionMap = Enumerable.Repeat(-1, nPrefixLength); var nSuffixPositionMap = Enumerable.Repeat(-1, nSuffixLength); // TODO maybe have a function for combining pos maps instead var finalPositionMap = new PositionMap(nPrefixPositionMap.Concat(positionMapWithoutTerminalNs.Map).Concat(nSuffixPositionMap).ToArray()); var finalCigar = new CigarAlignment { new CigarOp('S', (uint)nPrefixLength) }; foreach (CigarOp op in result.Cigar) { finalCigar.Add(op); } finalCigar.Add(new CigarOp('S', (uint)nSuffixLength)); finalCigar.Compress(); result.Cigar = finalCigar; // In case realignment introduced a bunch of mismatch-Ms where there was previously softclipping, optionally re-mask them. if (result != null && _remaskSoftclips) { var mismatchMap = Helper.GetMismatchMap(read.Sequence, finalPositionMap, context.Sequence, context.StartPosition); var softclipAdjustedCigar = Helper.SoftclipCigar(result.Cigar, mismatchMap, prefixSoftclip, suffixSoftclip, maskNsOnly: _maskNsOnly, prefixNs: Helper.GetCharacterBookendLength(read.Sequence, 'N', false), suffixNs: Helper.GetCharacterBookendLength(read.Sequence, 'N', true), softclipEvenIfMatch: _keepProbeSoftclips || _keepBothSideSoftclips, softclipRepresentsMess: (!(_keepBothSideSoftclips || _keepProbeSoftclips))); // Update position map to account for any softclipping added var adjustedPrefixClip = softclipAdjustedCigar.GetPrefixClip(); for (var i = 0; i < adjustedPrefixClip; i++) { finalPositionMap.UpdatePositionAtIndex(i, -2, true); } var adjustedSuffixClip = softclipAdjustedCigar.GetSuffixClip(); for (var i = 0; i < adjustedSuffixClip; i++) { finalPositionMap.UpdatePositionAtIndex(finalPositionMap.Length - 1 - i, -2, true); } var editDistance = Helper.GetNumMismatches(read.Sequence, finalPositionMap, context.Sequence, context.StartPosition); if (editDistance == null) { // This shouldn't happen at this point - we already have a successful result throw new InvalidDataException("Edit distance is null for :" + read.Name + " with position map " + string.Join(",", finalPositionMap) + " and CIGAR " + softclipAdjustedCigar); } // TODO PERF - See how much this really helps analytically. I'm thinking maybe kill this altogether and remove from eval var sumOfMismatching = Helper.GetSumOfMismatchQualities(mismatchMap, read.Qualities); var readHasPosition = finalPositionMap.HasAnyMappableBases(); if (!readHasPosition) { throw new InvalidDataException(string.Format( "Read does not have any alignable bases. ({2} --> {0} --> {3}, {1})", freshCigarWithoutTerminalNs, string.Join(",", finalPositionMap), read.CigarData, softclipAdjustedCigar)); } result.Position = finalPositionMap.FirstMappableBase(); // TODO this used to be >= 0 but changed to > 0. Confirm correct. result.Cigar = softclipAdjustedCigar; result.NumMismatches = editDistance.Value; var addedAtFinal = new List <int>(); foreach (var i in result.IndelsAddedAt) { addedAtFinal.Add(i + nPrefixLength); } result.IndelsAddedAt = addedAtFinal; var nifiedAtFinal = new List <int>(); foreach (var i in result.NifiedAt) { nifiedAtFinal.Add(i + nPrefixLength); } result.NifiedAt = nifiedAtFinal; var newSummary = Extensions.GetAlignmentSummary(result.Position - 1 - context.StartPosition, result.Cigar, context.Sequence, read.Sequence, _trackActualMismatches, _checkSoftclipsForMismatches); result.NumNonNMismatches = newSummary.NumNonNMismatches; result.NumNonNSoftclips = newSummary.NumNonNSoftclips; result.NumSoftclips = newSummary.NumSoftclips; result.NumInsertedBases = newSummary.NumInsertedBases; result.NumMismatchesIncludeSoftclip = newSummary.NumMismatchesIncludeSoftclip; //result.MismatchesIncludeSoftclip = newSummary.MismatchesIncludeSoftclip; result.SumOfMismatchingQualities = sumOfMismatching; result.AnchorLength = newSummary.AnchorLength; } }
private RealignmentResult RealignForAnchor(CandidateIndel[] indels, Read read, string refSequence, bool anchorOnLeft) { var position = read.GetAdjustedPosition(anchorOnLeft); var freshCigarWithoutTerminalNs = new CigarAlignment(); var nPrefixLength = read.GetNPrefix(); var nSuffixLength = read.GetNSuffix(); // Only build up the cigar for the non-N middle. Add the N prefix back on after the realignment attempts. freshCigarWithoutTerminalNs.Add(new CigarOp('M', (uint)(read.Sequence.Length - nPrefixLength - nSuffixLength))); freshCigarWithoutTerminalNs.Compress(); // start with fresh position map //var positionMapWithoutTerminalNsArray = new int[read.ReadLength - nPrefixLength - nSuffixLength]; var positionMapWithoutTerminalNs = new PositionMap(read.ReadLength - nPrefixLength - nSuffixLength); Read.UpdatePositionMap(position, freshCigarWithoutTerminalNs, positionMapWithoutTerminalNs); var prefixSoftclip = read.CigarData.GetPrefixClip(); var suffixSoftclip = read.CigarData.GetSuffixClip(); RealignmentResult result = null; var sequenceWithoutTerminalNs = read.Sequence.Substring(nPrefixLength, read.Sequence.Length - nPrefixLength - nSuffixLength); // layer on indels one by one, indels already sorted by ascending position if (anchorOnLeft) { for (var i = 0; i < indels.Length; i++) { result = AddIndelAndGetResult(sequenceWithoutTerminalNs, indels[i], refSequence, true, positionMapWithoutTerminalNs); if (result == null) { return(null); } } } else { for (var i = indels.Length - 1; i >= 0; i--) { result = AddIndelAndGetResult(sequenceWithoutTerminalNs, indels[i], refSequence, false, positionMapWithoutTerminalNs); if (result == null) { return(null); } } } // Softclip partial insertions at read ends // Assumption: there should be no softclips in the cigar by this time // Assumption: there should be exactly as many/the same indels in "indels" as are represented in the cigar in "result.Cigar". var firstIndel = indels[0]; var lastIndel = indels[indels.Length - 1]; bool hasInsertion = (firstIndel.Type == AlleleCategory.Insertion || lastIndel.Type == AlleleCategory.Insertion); if (hasInsertion) { if (_minimumUnanchoredInsertionLength > 0 || _maskPartialInsertion) { var newCigar = new CigarAlignment { }; for (int i = 0; i < result.Cigar.Count; i++) { if (result.Cigar[i].Type == 'S') { throw new InvalidDataException( string.Format( "Found an unexpected cigar type [{0}] in CIGAR string {1} before re-softclipping", result.Cigar[i].Type, result.Cigar)); } else if (i == 0 && Helper.EvaluateInsertionAtReadEnds(result.Cigar[i], firstIndel, _minimumUnanchoredInsertionLength, _maskPartialInsertion)) { newCigar.Add(new CigarOp('S', result.Cigar[i].Length)); } else if (i == result.Cigar.Count - 1 && Helper.EvaluateInsertionAtReadEnds(result.Cigar[i], lastIndel, _minimumUnanchoredInsertionLength, _maskPartialInsertion)) { newCigar.Add(new CigarOp('S', result.Cigar[i].Length)); } else { newCigar.Add(result.Cigar[i]); } } newCigar.Compress(); result.Cigar = newCigar; } } // Re-append the N-prefix var nPrefixPositionMap = Enumerable.Repeat(-1, nPrefixLength); var nSuffixPositionMap = Enumerable.Repeat(-1, nSuffixLength); var finalPositionMap = new PositionMap(nPrefixPositionMap.Concat(positionMapWithoutTerminalNs.Map).Concat(nSuffixPositionMap).ToArray()); var finalCigar = new CigarAlignment { new CigarOp('S', (uint)nPrefixLength) }; foreach (CigarOp op in result.Cigar) { finalCigar.Add(op); } finalCigar.Add(new CigarOp('S', (uint)nSuffixLength)); finalCigar.Compress(); result.Cigar = finalCigar; var UpdatedSummary = Extensions.GetAlignmentSummary(result.Position - 1, result.Cigar, refSequence, read.Sequence); result.NumIndels = UpdatedSummary.NumIndels; result.NumNonNMismatches = UpdatedSummary.NumNonNMismatches; result.NumMismatchesIncludeSoftclip = UpdatedSummary.NumMismatchesIncludeSoftclip; result.NumNonNSoftclips = UpdatedSummary.NumNonNSoftclips; result.NumSoftclips = UpdatedSummary.NumSoftclips; result.NumIndelBases = UpdatedSummary.NumIndelBases; result.MismatchesIncludeSoftclip = UpdatedSummary.MismatchesIncludeSoftclip; result.HasHighFrequencyIndel = indels.Any(t => t.Frequency > HighFrequencyIndelCutoff); // In case realignment introduced a bunch of mismatch-Ms where there was previously softclipping, optionally re-mask them. if (result != null && _remaskSoftclips) { var mismatchMap = Helper.GetMismatchMap(read.Sequence, finalPositionMap.Map, refSequence); var softclipAdjustedCigar = Helper.SoftclipCigar(result.Cigar, mismatchMap, prefixSoftclip, suffixSoftclip, maskNsOnly: true, prefixNs: Helper.GetCharacterBookendLength(read.Sequence, 'N', false), suffixNs: Helper.GetCharacterBookendLength(read.Sequence, 'N', true)); // Update position map to account for any softclipping added var adjustedPrefixClip = softclipAdjustedCigar.GetPrefixClip(); for (var i = 0; i < adjustedPrefixClip; i++) { finalPositionMap.UpdatePositionAtIndex(i, -2, true); } var adjustedSuffixClip = softclipAdjustedCigar.GetSuffixClip(); for (var i = 0; i < adjustedSuffixClip; i++) { finalPositionMap.UpdatePositionAtIndex(finalPositionMap.Length - 1 - i, -2, true); } var editDistance = Helper.GetEditDistance(read.Sequence, finalPositionMap.Map, refSequence); if (editDistance == null) { // This shouldn't happen at this point - we already have a successful result throw new InvalidDataException("Edit distance is null for :" + read.Name + " with position map " + string.Join(",", finalPositionMap) + " and CIGAR " + softclipAdjustedCigar); } var readHasPosition = finalPositionMap.HasAnyMappableBases(); if (!readHasPosition) { throw new InvalidDataException(string.Format("Read does not have any alignable bases. ({2} --> {0} --> {3}, {1})", freshCigarWithoutTerminalNs, string.Join(",", finalPositionMap), read.CigarData, softclipAdjustedCigar)); } result.Position = finalPositionMap.FirstMappableBase(); result.Cigar = softclipAdjustedCigar; result.NumMismatches = editDistance.Value; var newSummary = Extensions.GetAlignmentSummary(result.Position - 1, result.Cigar, refSequence, read.Sequence); result.NumNonNMismatches = newSummary.NumNonNMismatches; result.NumMismatchesIncludeSoftclip = newSummary.NumMismatchesIncludeSoftclip; result.NumNonNSoftclips = newSummary.NumNonNSoftclips; result.NumSoftclips = newSummary.NumSoftclips; result.NumIndelBases = newSummary.NumIndelBases; result.MismatchesIncludeSoftclip = newSummary.MismatchesIncludeSoftclip; result.HasHighFrequencyIndel = indels.Any(t => t.Frequency > HighFrequencyIndelCutoff); result.NumIndelBases = UpdatedSummary.NumIndelBases; } return(result); }