Ejemplo n.º 1
0
 /**
  * Add up overlap btw the blocks in this chain and the given interval.
  *
  * @return Length of overlap, offsets into first and last ContinuousBlocks, and indices of first
  *     and last ContinuousBlocks.
  */
 private static TargetIntersection targetIntersection(final Chain chain, final Interval interval) {
   int intersectionLength = 0;
   // Convert interval to 0-based, half-open
   int start = interval.getStart() - 1;
   int end = interval.getEnd();
   int firstBlockIndex = -1;
   int lastBlockIndex = -1;
   int startOffset = -1;
   int offsetFromEnd = -1;
   List<Chain.ContinuousBlock> blockList = chain.getBlocks();
   for (int i = 0; i < blockList.size(); ++i) {
     final Chain.ContinuousBlock block = blockList.get(i);
     if (block.fromStart >= end) {
       break;
     } else if (block.getFromEnd() <= start) {
       continue;
     }
     if (firstBlockIndex == -1) {
       firstBlockIndex = i;
       if (start > block.fromStart) {
         startOffset = start - block.fromStart;
       } else {
         startOffset = 0;
       }
     }
     lastBlockIndex = i;
     if (block.getFromEnd() > end) {
       offsetFromEnd = block.getFromEnd() - end;
     } else {
       offsetFromEnd = 0;
     }
     int thisIntersection = Math.min(end, block.getFromEnd()) - Math.max(start, block.fromStart);
     if (thisIntersection <= 0) {
       throw new PicardException("Should have been some intersection.");
     }
     intersectionLength += thisIntersection;
   }
   if (intersectionLength == 0) {
     return null;
   }
   return new TargetIntersection(
       chain, intersectionLength, startOffset, offsetFromEnd, firstBlockIndex, lastBlockIndex);
 }
Ejemplo n.º 2
0
 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(), targetIntersection);
       float percentLiftedOver = targetIntersection.intersectionLength / (float) interval.length();
       ret.add(
           new PartialLiftover(
               intersectingChain, toInterval, targetIntersection.chain.id, percentLiftedOver));
     }
   }
   return ret;
 }
Ejemplo n.º 3
0
 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;
 }
Ejemplo n.º 4
0
  /**
   * Lift over the given interval to the new genome build.
   *
   * @param interval Interval to be lifted over.
   * @param liftOverMinMatch Minimum fraction of bases that must remap.
   * @return Interval in the output build coordinates, or null if it cannot be lifted over.
   */
  public Interval liftOver(final Interval interval, final double liftOverMinMatch) {
    if (interval.length() == 0) {
      throw new IllegalArgumentException(
          "Zero-length interval cannot be lifted over.  Interval: " + interval.getName());
    }
    Chain chainHit = null;
    TargetIntersection targetIntersection = null;
    // Number of bases in interval that can be lifted over must be >= this.
    double minMatchSize = liftOverMinMatch * interval.length();

    // Find the appropriate Chain, and the part of the chain corresponding to the interval to be
    // lifted over.
    for (final Chain chain : chains.getOverlaps(interval)) {
      final TargetIntersection candidateIntersection = targetIntersection(chain, interval);
      if (candidateIntersection != null
          && candidateIntersection.intersectionLength >= minMatchSize) {
        if (chainHit != null) {
          // In basic liftOver, multiple hits are not allowed.
          return null;
        }
        chainHit = chain;
        targetIntersection = candidateIntersection;
      } else if (candidateIntersection != null) {
        LOG.info(
            "Interval "
                + interval.getName()
                + " failed to match chain "
                + chain.id
                + " because intersection length "
                + candidateIntersection.intersectionLength
                + " < minMatchSize "
                + minMatchSize
                + " ("
                + (candidateIntersection.intersectionLength / (float) interval.length())
                + " < "
                + liftOverMinMatch
                + ")");
      }
    }
    if (chainHit == null) {
      // Can't be lifted over.
      return null;
    }

    return createToInterval(interval.getName(), targetIntersection);
  }