*/
public static Feature nextFeature(FeatureSource source, String chr, int initStart, int initEnd, boolean forward) throws IOException {
Feature f = null;
int binSize = source.getFeatureWindowSize();
final Genome genome = GenomeManager.getInstance().getCurrentGenome();
if (forward) {
// Forward
int nextStart = initEnd;
String nextChr = chr;
while (nextChr != null) {
int chrLength = genome.getChromosome(nextChr).getLength();
while (nextStart < chrLength) {
int nextEnd = binSize > 0 ? nextStart + source.getFeatureWindowSize() : chrLength;
Iterator<Feature> iter = source.getFeatures(nextChr, nextStart, nextEnd);
if (iter != null) {
// The check on position should not be necessary, but not all implementations of getFeatures
// obey the contract to return features only in the interval.
while (iter.hasNext()) {
Feature feat = iter.next();
if (feat.getStart() > nextStart) {
return feat;
}
}
}
nextStart = nextEnd;
}
nextChr = genome.getNextChrName(nextChr);
nextStart = 0;
}
} else {
// Reverse
int nextEnd = initStart;
String nextChr = chr;
while (nextChr != null) {
while (nextEnd > 0) {
int nextStart = binSize > 0 ? Math.max(0, nextEnd - source.getFeatureWindowSize()) : 0;
Iterator<Feature> iter = source.getFeatures(nextChr, nextStart, nextEnd);
if (iter != null && iter.hasNext()) {
// The check on position should not be necessary, but not all implementations of getFeatures
// obey the contract to return features only in the interval.
Feature prevFeature = null;
while (iter.hasNext()) {
Feature feat = iter.next();
if (feat.getStart() < nextEnd) {
prevFeature = feat;
}
}
if (prevFeature != null) {
return prevFeature;
}
}
nextEnd = nextStart;
}
nextChr = genome.getPrevChrName(nextChr);
if (nextChr != null) {
nextEnd = genome.getChromosome(nextChr).getLength();
}
}
}
return f;