/** * Determine if the given loc overlaps any loc in the sorted set * * @param loc the location to test * @return */ public boolean overlaps(final GenomeLoc loc) { for (final GenomeLoc e : mArray) { if (e.overlapsP(loc)) { return true; } } return false; }
public GenomeLocSortedSet subtractRegions(GenomeLocSortedSet toRemoveSet) { LinkedList<GenomeLoc> good = new LinkedList<GenomeLoc>(); Stack<GenomeLoc> toProcess = new Stack<GenomeLoc>(); Stack<GenomeLoc> toExclude = new Stack<GenomeLoc>(); // initialize the stacks toProcess.addAll(mArray); Collections.reverse(toProcess); toExclude.addAll(toRemoveSet.mArray); Collections.reverse(toExclude); int i = 0; while (!toProcess.empty()) { // while there's still stuff to process if (toExclude.empty()) { good.addAll(toProcess); // no more excludes, all the processing stuff is good break; } GenomeLoc p = toProcess.peek(); GenomeLoc e = toExclude.peek(); if (p.overlapsP(e)) { toProcess.pop(); for (GenomeLoc newP : p.subtract(e)) toProcess.push(newP); } else if (p.compareContigs(e) < 0) { good.add(toProcess.pop()); // p is now good } else if (p.compareContigs(e) > 0) { toExclude.pop(); // e can't effect anything } else if (p.getStop() < e.getStart()) { good.add(toProcess.pop()); // p stops before e starts, p is good } else if (e.getStop() < p.getStart()) { toExclude.pop(); // p starts after e stops, e is done } else { throw new ReviewedStingException("BUG: unexpected condition: p=" + p + ", e=" + e); } if (i++ % 10000 == 0) logger.debug("removeRegions operation: i = " + i); } return createSetFromList(genomeLocParser, good); }
/** * Fully qualified constructor: instantiates a new GATKFeatureRecordList object with specified * GATKFeature track name, location on the reference, and list of associated GATKFeatures. This is * a knee-deep COPY constructor: passed name, loc, and data element objects will be referenced * from the created GATKFeatureRecordList (so that changing them from outside will affect data in * this object), however, the data elements will be copied into a newly allocated list, so that * the 'data' collection argument can be modified afterwards without affecting the state of this * record list. WARNING: this constructor is (semi-)validating: passed name and location are * allowed to be nulls (although it maybe unsafe, use caution), but if they are not nulls, then * passed non-null GATKFeature data elements must have same track name, and their locations must * overlap with the passed 'location' argument. Null data elements or null 'data' collection * argument are allowed as well. * * @param name the name of the track * @param data the collection of features at this location * @param loc the location */ public RODRecordListImpl(String name, Collection<GATKFeature> data, GenomeLoc loc) { this.records = new ArrayList<GATKFeature>(data == null ? 0 : data.size()); this.name = name; this.location = loc; if (data == null || data.size() == 0) return; // empty dataset, nothing to do for (GATKFeature r : data) { records.add(r); if (r == null) continue; if (!this.name.equals(r.getName())) { throw new ReviewedStingException( "Attempt to add GATKFeature with non-matching name " + r.getName() + " to the track " + name); } if (location != null && !location.overlapsP(r.getLocation())) { throw new ReviewedStingException( "Attempt to add GATKFeature that lies outside of specified interval " + location + "; offending GATKFeature:\n" + r.toString()); } } }