use of tracks.IntervalFeature in project ASCIIGenome by dariober.
the class Utils method mergeIntervalFeatures.
/**
* Merge overlapping features. If screenCoords is true, merge is based on the screen coordinates. Otherwise use
* genomic coordinates.
* @throws InvalidColourException
*/
public static List<IntervalFeature> mergeIntervalFeatures(List<IntervalFeature> intervalList, boolean screenCoords) throws InvalidGenomicCoordsException, InvalidColourException {
List<IntervalFeature> mergedList = new ArrayList<IntervalFeature>();
if (intervalList.size() == 0) {
return mergedList;
}
String mergedChrom = null;
int mergedFrom = -1;
int mergedTo = -1;
int mergedScreenFrom = -1;
int mergedScreenTo = -1;
// Number of intervals in the merged one.
int numMrgIntv = 1;
// Put here all the different strands found in the merged features.
Set<Character> strand = new HashSet<Character>();
for (int i = 0; i < (intervalList.size() + 1); i++) {
// We do an additional loop to add to the mergedList the last interval.
// The last loop has interval == null so below you need to account for it
IntervalFeature interval = null;
if (i < intervalList.size()) {
interval = intervalList.get(i);
}
if (mergedFrom < 0) {
// Init interval
mergedChrom = interval.getChrom();
mergedFrom = interval.getFrom();
mergedTo = interval.getTo();
mergedScreenFrom = interval.getScreenFrom();
mergedScreenTo = interval.getScreenTo();
continue;
}
// Sanity check: The list to be merged is on the same chrom and sorted by start pos.
if (i < intervalList.size() && (!mergedChrom.equals(interval.getChrom()) || mergedFrom > interval.getFrom() || mergedFrom > mergedTo)) {
System.err.println(mergedChrom + " " + mergedFrom + " " + mergedTo);
throw new RuntimeException();
}
boolean overlap = false;
if (screenCoords && i < intervalList.size() && (mergedScreenFrom <= interval.getScreenTo() && mergedScreenTo >= (interval.getScreenFrom() - 1))) {
// Overlap: Extend <to> coordinate. See also http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
overlap = true;
} else if (i < intervalList.size() && (mergedFrom <= interval.getTo() && mergedTo >= (interval.getFrom() - 1))) {
// Overlap on genomic coordinates
overlap = true;
}
if (overlap) {
// Overlap found in screen or genomic coords.
mergedTo = Math.max(interval.getTo(), mergedTo);
mergedScreenTo = Math.max(interval.getScreenTo(), mergedScreenTo);
strand.add(interval.getStrand());
numMrgIntv++;
overlap = false;
} else {
// No overlap add merged interval to list and reset new merged interval
IntervalFeature x = new IntervalFeature(mergedChrom + "\t" + (mergedFrom - 1) + "\t" + mergedTo, TrackFormat.BED, null);
x.setScreenFrom(mergedScreenFrom);
x.setScreenTo(mergedScreenTo);
if (strand.size() == 1) {
x.setStrand(strand.iterator().next());
}
strand.clear();
if (x.equals(intervalList.get(i - 1)) && numMrgIntv == 1) {
mergedList.add(intervalList.get(i - 1));
} else {
mergedList.add(x);
}
if (i < intervalList.size()) {
// Do not reset from/to if you are in extra loop.
mergedFrom = interval.getFrom();
mergedTo = interval.getTo();
mergedScreenFrom = interval.getScreenFrom();
mergedScreenTo = interval.getScreenTo();
strand.add(interval.getStrand());
numMrgIntv = 1;
}
}
}
for (IntervalFeature x : mergedList) {
x.getIdeogram(true, true);
}
return mergedList;
}
Aggregations