@Ensures("result != null") public final String toString() { if (GenomeLoc.isUnmapped(this)) return "unmapped"; if (throughEndOfContigP() && atBeginningOfContigP()) return getContig(); else if (throughEndOfContigP() || getStart() == getStop()) return String.format("%s:%d", getContig(), getStart()); else return String.format("%s:%d-%d", getContig(), getStart(), getStop()); }
/** * Returns a new GenomeLoc that represents the region between the endpoints of this and that. * Requires that this and that GenomeLoc are both mapped. */ @Requires({"that != null", "isUnmapped(this) == isUnmapped(that)"}) @Ensures("result != null") public GenomeLoc endpointSpan(GenomeLoc that) throws ReviewedStingException { if (GenomeLoc.isUnmapped(this) || GenomeLoc.isUnmapped(that)) { throw new ReviewedStingException("Cannot get endpoint span for unmerged genome locs"); } if (!this.getContig().equals(that.getContig())) { throw new ReviewedStingException( "Cannot get endpoint span for genome locs on different contigs"); } return new GenomeLoc( getContig(), this.contigIndex, Math.min(getStart(), that.getStart()), Math.max(getStop(), that.getStop())); }
/** * Returns a new GenomeLoc that represents the entire span of this and that. Requires that this * and that GenomeLoc are contiguous and both mapped */ @Requires({"that != null", "isUnmapped(this) == isUnmapped(that)"}) @Ensures("result != null") public GenomeLoc merge(GenomeLoc that) throws ReviewedStingException { if (GenomeLoc.isUnmapped(this) || GenomeLoc.isUnmapped(that)) { if (!GenomeLoc.isUnmapped(this) || !GenomeLoc.isUnmapped(that)) throw new ReviewedStingException("Tried to merge a mapped and an unmapped genome loc"); return UNMAPPED; } if (!(this.contiguousP(that))) { throw new ReviewedStingException("The two genome loc's need to be contigous"); } return new GenomeLoc( getContig(), this.contigIndex, Math.min(getStart(), that.getStart()), Math.max(getStop(), that.getStop())); }
@Requires("that != null") @Ensures("result != null") public GenomeLoc intersect(GenomeLoc that) throws ReviewedStingException { if (GenomeLoc.isUnmapped(this) || GenomeLoc.isUnmapped(that)) { if (!GenomeLoc.isUnmapped(this) || !GenomeLoc.isUnmapped(that)) throw new ReviewedStingException("Tried to intersect a mapped and an unmapped genome loc"); return UNMAPPED; } if (!(this.overlapsP(that))) { throw new ReviewedStingException( "GenomeLoc::intersect(): The two genome loc's need to overlap"); } return new GenomeLoc( getContig(), this.contigIndex, Math.max(getStart(), that.getStart()), Math.min(getStop(), that.getStop())); }
@Requires("that != null") @Ensures("result == 0 || result == 1 || result == -1") public int compareTo(GenomeLoc that) { int result = 0; if (this == that) { result = 0; } else if (GenomeLoc.isUnmapped(this)) result = 1; else if (GenomeLoc.isUnmapped(that)) result = -1; else { final int cmpContig = compareContigs(that); if (cmpContig != 0) { result = cmpContig; } else { if (this.getStart() < that.getStart()) result = -1; if (this.getStart() > that.getStart()) result = 1; } } return result; }
@Requires("that != null") public final List<GenomeLoc> subtract(final GenomeLoc that) { if (GenomeLoc.isUnmapped(this) || GenomeLoc.isUnmapped(that)) { if (!GenomeLoc.isUnmapped(this) || !GenomeLoc.isUnmapped(that)) throw new ReviewedStingException("Tried to intersect a mapped and an unmapped genome loc"); return Arrays.asList(UNMAPPED); } if (!(this.overlapsP(that))) { throw new ReviewedStingException("GenomeLoc::minus(): The two genome loc's need to overlap"); } if (equals(that)) { return Collections.emptyList(); } else if (containsP(that)) { List<GenomeLoc> l = new ArrayList<GenomeLoc>(2); /** * we have to create two new region, one for the before part, one for the after The old * region: |----------------- old region (g) -------------| |----- to delete (e) ------| * * <p>product (two new regions): |------| + |--------| */ int afterStop = this.getStop(), afterStart = that.getStop() + 1; int beforeStop = that.getStart() - 1, beforeStart = this.getStart(); if (afterStop - afterStart >= 0) { GenomeLoc after = new GenomeLoc(this.getContig(), getContigIndex(), afterStart, afterStop); l.add(after); } if (beforeStop - beforeStart >= 0) { GenomeLoc before = new GenomeLoc(this.getContig(), getContigIndex(), beforeStart, beforeStop); l.add(before); } return l; } else if (that.containsP(this)) { /** * e completely contains g, delete g, but keep looking, there may be more regions i.e.: * |--------------------- e --------------------| |--- g ---| |---- others ----| */ return Collections.emptyList(); // don't need to do anything } else { /** * otherwise e overlaps some part of g * * <p>figure out which region occurs first on the genome. I.e., is it: |------------- g * ----------| |------------- e ----------| * * <p>or: |------------- g ----------| |------------ e -----------| */ GenomeLoc n; if (that.getStart() < this.getStart()) { n = new GenomeLoc(this.getContig(), getContigIndex(), that.getStop() + 1, this.getStop()); } else { n = new GenomeLoc(this.getContig(), getContigIndex(), this.getStart(), that.getStart() - 1); } // replace g with the new region return Arrays.asList(n); } }