/** Merges a sorted collection of intervals and optionally concatenates unique names or takes the first name. */ static Interval merge(final SortedSet<Interval> intervals, final boolean concatenateNames) { final String chrom = intervals.first().getSequence(); int start = intervals.first().getStart(); int end = intervals.last().getEnd(); final boolean neg = intervals.first().isNegativeStrand(); final LinkedHashSet<String> names = new LinkedHashSet<String>(); final String name; for (final Interval i : intervals) { if (i.getName() != null) names.add(i.getName()); start = Math.min(start, i.getStart()); end = Math.max(end, i.getEnd()); } if (concatenateNames) { name = StringUtil.join("|", names); } else { name = names.iterator().next(); } return new Interval(chrom, start, end, neg, name); }
/** * Merges a sorted collection of intervals and optionally concatenates unique names or takes the first name. */ static Interval merge(final SortedSet<Interval> intervals, final boolean concatenateNames) { final String chrom = intervals.first().getContig(); int start = intervals.first().getStart(); int end = intervals.last().getEnd(); final boolean neg = intervals.first().isNegativeStrand(); final LinkedHashSet<String> names = new LinkedHashSet<>(); final String name; for (final Interval i : intervals) { if (i.getName() != null) { names.add(i.getName()); } start = Math.min(start, i.getStart()); end = Math.max(end, i.getEnd()); } if (names.isEmpty()) { name = null; } else if (concatenateNames) { name = StringUtil.join("|", names); } else { name = names.iterator().next(); } return new Interval(chrom, start, end, neg, name); }
public String toString() { if (toInterval == null) { // Matched a chain, but entirely within a gap. return fromInterval.toString() + " (len " + fromInterval.length() + ")=>null using chain " + chainId; } final String strand = toInterval.isNegativeStrand()? "-": "+"; return fromInterval.toString() + " (len " + fromInterval.length() + ")=>" + toInterval + "(" + strand + ") using chain " + chainId + " ; pct matched " + percentLiftedOver; } }
public String toString() { if (toInterval == null) { // Matched a chain, but entirely within a gap. return fromInterval.toString() + " (len " + fromInterval.length() + ")=>null using chain " + chainId; } final String strand = toInterval.isNegativeStrand()? "-": "+"; return fromInterval.toString() + " (len " + fromInterval.length() + ")=>" + toInterval + "(" + strand + ") using chain " + chainId + " ; pct matched " + percentLiftedOver; } }
public String toString() { if (toInterval == null) { // Matched a chain, but entirely within a gap. return fromInterval.toString() + " (len " + fromInterval.length() + ")=>null using chain " + chainId; } final String strand = toInterval.isNegativeStrand()? "-": "+"; return fromInterval.toString() + " (len " + fromInterval.length() + ")=>" + toInterval + "(" + strand + ") using chain " + chainId + " ; pct matched " + percentLiftedOver; } }
@Override protected int doWork() { IOUtil.assertFileIsReadable(INPUT); IOUtil.assertFileIsWritable(OUTPUT); IntervalList intervals = IntervalList.fromFile(INPUT); if (SORT) intervals = intervals.sorted(); try { final BufferedWriter out = IOUtil.openFileForBufferedWriting(OUTPUT); for (final Interval i : intervals) { final String strand = i.isNegativeStrand() ? "-" : "+"; final List<?> fields = CollectionUtil.makeList(i.getContig(), i.getStart()-1, i.getEnd(), i.getName(), SCORE, strand); out.append(fields.stream().map(String::valueOf).collect(Collectors.joining("\t"))); out.newLine(); } out.close(); } catch (IOException ioe) { throw new RuntimeIOException(ioe); } return 0; } }
@Override protected int doWork() { IOUtil.assertFileIsReadable(INPUT); IOUtil.assertFileIsWritable(OUTPUT); IntervalList intervals = IntervalList.fromFile(INPUT); if (SORT) intervals = intervals.sorted(); try { final BufferedWriter out = IOUtil.openFileForBufferedWriting(OUTPUT); for (final Interval i : intervals) { final String strand = i.isNegativeStrand() ? "-" : "+"; final List<?> fields = CollectionUtil.makeList(i.getContig(), i.getStart()-1, i.getEnd(), i.getName(), SCORE, strand); out.append(fields.stream().map(String::valueOf).collect(Collectors.joining("\t"))); out.newLine(); } out.close(); } catch (IOException ioe) { throw new RuntimeIOException(ioe); } return 0; } }
@Override List<Bait> design(final BaitDesigner designer, final Interval target, final ReferenceSequence reference) { final List<Bait> baits = new LinkedList<Bait>(); final int baitSize = designer.BAIT_SIZE; final int baitOffset = designer.BAIT_OFFSET; final int lastPossibleBaitStart = Math.min(target.getEnd(), reference.length() - baitSize); final int baitCount = 1 + (int) Math.floor((lastPossibleBaitStart - target.getStart()) / (double) baitOffset); int i = 0; for (int start = target.getStart(); start < lastPossibleBaitStart; start += baitOffset) { final Bait bait = new Bait(target.getContig(), start, CoordMath.getEnd(start, baitSize), target.isNegativeStrand(), designer.makeBaitName(target.getName(), ++i, baitCount)); bait.addBases(reference, designer.DESIGN_ON_TARGET_STRAND); baits.add(bait); } return baits; } };
public List<PartialLiftover> diagnosticLiftover(final Interval interval) { final List<PartialLiftover> ret = new ArrayList<PartialLiftover>(); if (interval.length() == 0) { throw new IllegalArgumentException("Zero-length interval cannot be lifted over. Interval: " + interval.getName()); } for (final Chain chain : chains.getOverlaps(interval)) { Interval intersectingChain = interval.intersect(chain.interval); final TargetIntersection targetIntersection = targetIntersection(chain, intersectingChain); if (targetIntersection == null) { ret.add(new PartialLiftover(intersectingChain, chain.id)); } else { Interval toInterval = createToInterval(interval.getName(), interval.isNegativeStrand(), targetIntersection); float percentLiftedOver = targetIntersection.intersectionLength/(float)interval.length(); ret.add(new PartialLiftover(intersectingChain, toInterval, targetIntersection.chain.id, percentLiftedOver)); } } return ret; }
public List<PartialLiftover> diagnosticLiftover(final Interval interval) { final List<PartialLiftover> ret = new ArrayList<PartialLiftover>(); if (interval.length() == 0) { throw new IllegalArgumentException("Zero-length interval cannot be lifted over. Interval: " + interval.getName()); } for (final Chain chain : chains.getOverlaps(interval)) { Interval intersectingChain = interval.intersect(chain.interval); final TargetIntersection targetIntersection = targetIntersection(chain, intersectingChain); if (targetIntersection == null) { ret.add(new PartialLiftover(intersectingChain, chain.id)); } else { Interval toInterval = createToInterval(interval.getName(), interval.isNegativeStrand(), targetIntersection); float percentLiftedOver = targetIntersection.intersectionLength/(float)interval.length(); ret.add(new PartialLiftover(intersectingChain, toInterval, targetIntersection.chain.id, percentLiftedOver)); } } return ret; }
@Override List<Bait> design(final BaitDesigner designer, final Interval target, final ReferenceSequence reference) { final List<Bait> baits = new LinkedList<Bait>(); final int baitSize = designer.BAIT_SIZE; final int baitOffset = designer.BAIT_OFFSET; final int lastPossibleBaitStart = Math.min(target.getEnd(), reference.length() - baitSize); final int baitCount = 1 + (int) Math.floor((lastPossibleBaitStart - target.getStart()) / (double) baitOffset); int i = 0; for (int start = target.getStart(); start < lastPossibleBaitStart; start += baitOffset) { final Bait bait = new Bait(target.getContig(), start, CoordMath.getEnd(start, baitSize), target.isNegativeStrand(), designer.makeBaitName(target.getName(), ++i, baitCount)); bait.addBases(reference, designer.DESIGN_ON_TARGET_STRAND); baits.add(bait); } return baits; } };
/** * Returns a new IntervalList where each interval is padded by the specified amount of bases. */ public IntervalList padded(final int before, final int after) { if (before < 0 || after < 0) { throw new IllegalArgumentException("Padding values must be >= 0."); } final IntervalList padded = new IntervalList(this.getHeader().clone()); final SAMSequenceDictionary dict = padded.getHeader().getSequenceDictionary(); for (final Interval i : this) { final SAMSequenceRecord seq = dict.getSequence(i.getContig()); final int start = Math.max(1, i.getStart() - before); final int end = Math.min(seq.getSequenceLength(), i.getEnd() + after); padded.add(new Interval(i.getContig(), start, end, i.isNegativeStrand(), i.getName())); } return padded; }
/** * Returns a new IntervalList where each interval is padded by the specified amount of bases. */ public IntervalList padded(final int before, final int after) { if (before < 0 || after < 0) { throw new IllegalArgumentException("Padding values must be >= 0."); } final IntervalList padded = new IntervalList(this.getHeader().clone()); final SAMSequenceDictionary dict = padded.getHeader().getSequenceDictionary(); for (final Interval i : this) { final SAMSequenceRecord seq = dict.getSequence(i.getContig()); final int start = Math.max(1, i.getStart() - before); final int end = Math.min(seq.getSequenceLength(), i.getEnd() + after); padded.add(new Interval(i.getContig(), start, end, i.isNegativeStrand(), i.getName())); } return padded; }
public int compare(final Interval lhs, final Interval rhs) { final int lhsIndex = this.header.getSequenceIndex(lhs.getSequence()); final int rhsIndex = this.header.getSequenceIndex(rhs.getSequence()); int retval = lhsIndex - rhsIndex; if (retval == 0) retval = lhs.getStart() - rhs.getStart(); if (retval == 0) retval = lhs.getEnd() - rhs.getEnd(); if (retval == 0) { if (lhs.isPositiveStrand() && rhs.isNegativeStrand()) retval = -1; else if (lhs.isNegativeStrand() && rhs.isPositiveStrand()) retval = 1; } if (retval == 0) { if (lhs.getName() == null) { if (rhs.getName() == null) return 0; else return -1; } else if (rhs.getName() == null) { return 1; } else { return lhs.getName().compareTo(rhs.getName()); } } return retval; } }
@Test(dataProvider = "indelFlipDataWithOriginalAllele") public void testFlipIndelWithOriginalAlleles(final VariantContext source, final ReferenceSequence reference, final VariantContext result) { final LiftOver liftOver = new LiftOver(CHAIN_FILE); final Interval originalLocus = new Interval(source.getContig(), source.getStart(), source.getEnd()); final Interval target = liftOver.liftOver(originalLocus); if (target != null && !target.isNegativeStrand()) { throw new RuntimeException("not reversed"); } final VariantContext flipped = LiftoverUtils.liftVariant(source, target, reference, false, true); VcfTestUtils.assertEquals(flipped, result); }
@Test(dataProvider = "noCallAndSymbolicData") public void testLiftOverNoCallAndSymbolic(final LiftOver liftOver, final VariantContext source, final VariantContext result, final boolean expectReversed) { final Interval target = liftOver.liftOver(new Interval(source.getContig(), source.getStart(), source.getEnd()), .95); Assert.assertEquals(target.isNegativeStrand(), expectReversed); VariantContext vc = LiftoverUtils.liftVariant(source, target, REFERENCE, true, true); VcfTestUtils.assertEquals(vc, result); Assert.assertEquals(vc.getAttribute(LiftoverVcf.ORIGINAL_CONTIG), source.getContig()); Assert.assertEquals(vc.getAttribute(LiftoverVcf.ORIGINAL_START), source.getStart()); Assert.assertTrue(source.getAlleles().equals(result.getAlleles()) != result.hasAttribute(LiftoverVcf.ORIGINAL_ALLELES)); if (!source.getAlleles().equals(result.getAlleles())) { List<String> resultAlleles = new ArrayList<>(); source.getAlleles().forEach(a -> resultAlleles.add(a.getDisplayString())); Assert.assertEquals(resultAlleles, result.getAttributeAsStringList(LiftoverVcf.ORIGINAL_ALLELES, null)); } }
@Test(dataProvider = "indelFlipData") public void testFlipIndel(final VariantContext source, final ReferenceSequence reference, final VariantContext result) { final LiftOver liftOver = new LiftOver(CHAIN_FILE); final Interval originalLocus = new Interval(source.getContig(), source.getStart(), source.getEnd()); final Interval target = liftOver.liftOver(originalLocus); if (target != null && !target.isNegativeStrand()) { throw new RuntimeException("not reversed"); } final VariantContext flipped = LiftoverUtils.liftVariant(source, target, reference, false, false); VcfTestUtils.assertEquals(flipped, result); }
@Override public List<Interval> takeSome(final Interval interval, final long idealSplitWeight, final long currentSize, final double projectSizeOfRemaining) { final long amount = idealSplitWeight - currentSize; if (amount >= interval.length()) { return CollectionUtil.makeList(interval, null); } if (amount == 0) { return CollectionUtil.makeList(null, interval); } final Interval left = new Interval( interval.getContig(), interval.getStart(), interval.getStart() + (int) amount - 1, interval.isNegativeStrand(), interval.getName() ); final Interval right = new Interval( interval.getContig(), interval.getStart() + (int) amount, interval.getEnd(), interval.isNegativeStrand(), interval.getName() ); return CollectionUtil.makeList(left, right); } }
@Override public List<Interval> takeSome(final Interval interval, final long idealSplitWeight, final long currentSize, final double projectSizeOfRemaining) { final long amount = idealSplitWeight - currentSize; if (amount >= interval.length()) { return CollectionUtil.makeList(interval, null); } if (amount == 0) { return CollectionUtil.makeList(null, interval); } final Interval left = new Interval( interval.getContig(), interval.getStart(), interval.getStart() + (int) amount - 1, interval.isNegativeStrand(), interval.getName() ); final Interval right = new Interval( interval.getContig(), interval.getStart() + (int) amount, interval.getEnd(), interval.isNegativeStrand(), interval.getName() ); return CollectionUtil.makeList(left, right); } }
private static IntervalList composeIntervalList(final IntervalList source, final String chromosome, final int... segmentsByPair) { final IntervalList intervals = new IntervalList(source.getHeader()); for (int i = 0; i < segmentsByPair.length; i += 2) { final Interval parentInterval = lookupIntervalContainingLocus(source, chromosome, segmentsByPair[i]); intervals.add(new Interval(chromosome, segmentsByPair[i], segmentsByPair[i + 1], parentInterval.isNegativeStrand(), parentInterval.getName())); } return intervals; }