@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); } }