public void TestJump() { var smallBam = Path.Combine(TestPaths.LocalTestDataDirectory, "bwaXC.bam"); using (var reader = new BamReader(smallBam)) { BamAlignment al = new BamAlignment(); Assert.True(reader.Jump(reader.GetReferenceIndex("chr1"), 20200)); Assert.True(reader.GetNextAlignment(ref al, true)); Assert.True(al.Position > 18000); Assert.True(reader.Jump(reader.GetReferenceIndex("chr1"), 200)); Assert.True(reader.GetNextAlignment(ref al, true)); Assert.True(al.Position < 250); // now, forward-only jumping Assert.True(reader.JumpForward(reader.GetReferenceIndex("chr1"), 20200)); Assert.True(reader.GetNextAlignment(ref al, true)); Assert.True(al.Position > 18000); // a good forward jump var position = reader.Tell(); Assert.True(reader.JumpForward(reader.GetReferenceIndex("chr1"), 200)); Assert.Equal(position, reader.Tell()); // we stayed put Assert.True(reader.GetNextAlignment(ref al, true)); Assert.True(al.Position > 18000); } }
private bool JumpIfNeeded(List <Region> chrIntervals, out Region currentRegion) { var completedIntervals = new List <Region>(); for (var i = 0; i < chrIntervals.Count; i++) { var interval = chrIntervals[i]; if ((_rawAlignment.Position + 1) > interval.EndPosition) // bam alignment is 0-based, interval is 1-based { completedIntervals.Add(interval); _shouldCheckJumpForCurrentInterval = true; } else { break; } } foreach (var completedInterval in completedIntervals) { chrIntervals.Remove(completedInterval); } // if done with intervals, jump to next chromosome if (!chrIntervals.Any()) { currentRegion = null; if (_rawAlignment.RefID == _references.Count - 1) { return(false); } if (_mateFinder == null || _mateFinder.NextMatePosition == null) { return(_bamReader.Jump(_rawAlignment.RefID + 1, 0)); } return(true); } currentRegion = chrIntervals[0]; // if far from next interval, jump forward. leave small buffer so we dont accidentally re-read already read alignments if there's not much gap inbetween if (_shouldCheckJumpForCurrentInterval) { var targetInterval = currentRegion; const int buffer = 100; var refMaxIndex = (int)(_references.First(r => r.Index == _rawAlignment.RefID).Length - 1); var jumpToThreshold = Math.Min(Math.Max(0, targetInterval.StartPosition - buffer), refMaxIndex); if (_mateFinder != null) { var nextMate = _mateFinder.NextMatePosition; if (nextMate != null && nextMate.Value < jumpToThreshold) { jumpToThreshold = nextMate.Value; } else { _shouldCheckJumpForCurrentInterval = false; } } else { _shouldCheckJumpForCurrentInterval = false; } if ((_rawAlignment.GetEndPosition() - _rawAlignment.CigarData.GetSuffixClip()) < jumpToThreshold) { return(_bamReader.JumpForward(_rawAlignment.RefID, Math.Min(Math.Max(0, targetInterval.StartPosition - 1), refMaxIndex))); } } return(true); }