}
if (deleted > 0)
+ {
finalizeDeletion();
+ }
if (!isTainted)
{
offsets = null;
return false;
}
if (index < 0)
+ {
index = -1 - index;
+ }
else
+ {
index++;
+ }
}
}
{
return false;
}
-
+ isSorted = false;
}
if (index == intervalCount)
// System.out.println("stashed " + pt + " " + interval + " for "
// + index + " " + intervals[index]);
if (offsets == null)
+ {
offsets = new int[capacity];
+ }
offsets[pt] = offsets[index];
private IntervalI[] finalizeAddition(IntervalI[] dest)
{
if (dest == null)
+ {
dest = intervals;
+ }
if (added == 0)
{
if (intervalCount > 0 && dest != intervals)
{
int pt0 = pt;
while (--pt >= 0 && offsets[pt] == 0)
+ {
;
+ }
if (pt < 0)
+ {
pt = 0;
+ }
int nOK = pt0 - pt;
// shift upper intervals right
ptShift -= nOK;
if (nOK > 0)
+ {
System.arraycopy(intervals, pt, dest, ptShift, nOK);
+ }
if (added == 0)
+ {
break;
+ }
for (int offset = offsets[pt]; offset > 0; offset = offsets[offset])
{
dest[--ptShift] = intervals[offset];
int r1 = interval.getEnd();
int end = intervalCount - 1;
if (end < 0 || r0 < minStart)
+ {
return -1;
+ }
if (r0 > maxStart)
+ {
return -1 - intervalCount;
+ }
while (start <= end)
{
int mid = (start + end) >>> 1;
IntervalI iv = intervals[mid];
if ((bsIgnore == null || !bsIgnore.get(mid))
&& iv.equalsInterval(interval))
+ {
return mid;
// found one; just scan up and down now, first checking the range, but
// also checking other possible aspects of equivalence.
+ }
for (int i = mid; ++i <= end;)
{
if ((iv = intervals[i]).getBegin() != r0 || iv.getEnd() != r1)
+ {
break;
+ }
if ((bsIgnore == null || !bsIgnore.get(i))
&& iv.equalsInterval(interval))
+ {
return i;
+ }
}
for (int i = mid; --i >= start;)
{
if ((iv = intervals[i]).getBegin() != r0 || iv.getEnd() < r1)
+ {
return -1 - ++i;
+ }
if ((bsIgnore == null || !bsIgnore.get(i))
&& iv.equalsInterval(interval))
+ {
return i;
+ }
}
return -1 - start;
}
private int compareRange(IntervalI t, long from, long to)
{
if (t == null)
+ {
System.out.println("???");
+ }
int order = Long.signum(t.getBegin() - from);
return (order == 0
? Long.signum(bigendian ? to - t.getEnd() : t.getEnd() - to)
public boolean contains(Object entry)
{
if (entry == null || intervalCount == 0)
+ {
return false;
+ }
if (!isSorted || deleted > 0)
{
sort();
ensureFinalized();
int index = binaryIdentitySearch(inner, null);
if (index >= 0)
+ {
while ((index = index - Math.abs(offsets[index])) >= 0)
{
if (intervals[index] == outer)
return true;
}
}
+ }
return false;
}
private void ensureFinalized()
{
- if (isTainted && intervalCount + added > 1)
+ if (isTainted)
{
if (!isSorted || added > 0 || deleted > 0)
{
sort();
}
if (offsets == null || offsets.length < intervalCount)
+ {
offsets = new int[intervalCount];
+ }
linkFeatures();
isTainted = false;
}
ensureFinalized();
if (from > maxEnd || to < minStart)
+ {
return result;
+ }
int index = binaryLastIntervalSearch(from, to, ret);
int index1 = ret[0];
if (index1 < 0)
+ {
return result;
+ }
if (index1 > index + 1)
{
public IntervalI get(int i)
{
if (i < 0 || i >= intervalCount + added)
+ {
return null;
+ }
ensureFinalized();
return intervals[i];
}
@Override
public Iterator<T> iterator()
{
- finalizeAddition(null);
+ ensureFinalized();
return new Iterator<T>()
{
public T next()
{
if (next >= intervalCount)
+ {
throw new NoSuchElementException();
+ }
return (T) intervals[next++];
}
private void linkFeatures()
{
if (intervalCount == 0)
+ {
return;
+ }
maxEnd = intervals[0].getEnd();
offsets[0] = IntervalI.NOT_CONTAINED;
if (intervalCount == 1)
// if (addPt == intervalCount || offsets[pt] == 0)
// return pt;
if (pt >= 0 || added == 0 || pt == -1 - intervalCount)
+ {
return pt;
+ }
pt = -1 - pt;
int start = interval.getBegin();
int end = interval.getEnd();
break;
case 0:
if (iv.equalsInterval(interval))
+ {
return pt;
+ }
// fall through
case 1:
match = pt;
{
int i = intervalCount;
while (--i >= 0 && !intervals[i].equalsInterval(interval))
+ {
;
+ }
return i;
}
}
}
int i = binaryIdentitySearch(interval, bsDeleted);
if (i < 0)
+ {
return false;
+ }
if (deleted == 0)
{
if (bsDeleted == null)
+ {
bsDeleted = new BitSet(intervalCount);
+ }
else
+ {
bsDeleted.clear();
+ }
}
bsDeleted.set(i);
deleted++;
private void finalizeDeletion()
{
if (deleted == 0)
+ {
return;
+ }
// ......xxx.....xxxx.....xxxxx....
// ......^i,pt
i = bsDeleted.nextClearBit(i + 1);
int pt1 = bsDeleted.nextSetBit(i + 1);
if (pt1 < 0)
+ {
pt1 = intervalCount;
+ }
int n = pt1 - i;
System.arraycopy(intervals, i, intervals, pt, n);
pt += n;
if (pt1 == intervalCount)
{
for (i = pt1; --i >= pt;)
+ {
intervals[i] = null;
+ }
intervalCount -= deleted;
deleted = 0;
bsDeleted.clear();
return intervalCount + added - deleted;
}
+ @Override
+ public Object[] toArray()
+ {
+ ensureFinalized();
+ return super.toArray();
+ }
+
/**
* Sort intervals by start (lowest first) and end (highest first).
*/
{
if (start == end)
{
- getContactPoints(contactFeatureStarts, start, result, true);
- getContactPoints(contactFeatureEnds, start, result, false);
+ getContactPointStarts(contactFeatureStarts, start, result);
+ getContactPointEnds(contactFeatureEnds, end, result);
}
else
{
*
* @author Bob Hanson 2019.07.30
*/
- private void getContactPoints(List<SequenceFeature> l, long pos,
- List<SequenceFeature> result, boolean isStart)
+ private void getContactPointStarts(List<SequenceFeature> l, long pos,
+ List<SequenceFeature> result)
{
int low = 0;
int high = l.size() - 1;
{
int mid = (low + high) >>> 1;
SequenceFeature f = l.get(mid);
- switch (Long.signum((isStart ? f.begin : f.end) - pos))
+ switch (Long.signum(f.begin - pos))
{
case -1:
low = mid + 1;
int m = mid;
result.add(f);
// could be "5" in 12345556788 ?
- while (++mid <= high && (f = l.get(mid)) != null
- && (isStart ? f.begin : f.end) == pos)
+ while (++mid <= high && (f = l.get(mid)) != null && f.begin == pos)
{
result.add(f);
}
- while (--m >= low && (f = l.get(m)) != null
- && (isStart ? f.begin : f.end) == pos)
+ while (--m >= low && (f = l.get(m)) != null && f.begin == pos)
{
result.add(f);
}
}
}
+ private void getContactPointEnds(List<SequenceFeature> l, long pos,
+ List<SequenceFeature> result)
+ {
+ int low = 0;
+ int high = l.size() - 1;
+ while (low <= high)
+ {
+ int mid = (low + high) >>> 1;
+ SequenceFeature f = l.get(mid);
+ switch (Long.signum(f.end - pos))
+ {
+ case -1:
+ low = mid + 1;
+ continue;
+ case 1:
+ high = mid - 1;
+ continue;
+ case 0:
+ int m = mid;
+ if (f.begin != f.end)
+ {
+ result.add(f);
+ }
+ // could be "5" in 12345556788 ?
+ while (++mid <= high && (f = l.get(mid)) != null
+ && f.end == pos)
+ {
+ if (f.begin != f.end)
+ {
+ result.add(f);
+ }
+ }
+ while (--m >= low && (f = l.get(m)) != null
+ && f.end == pos)
+ {
+ if (f.begin != f.end)
+ {
+ result.add(f);
+ }
+ }
+ return;
+ }
+ }
+ }
+
/**
* Adds contact features whose start position lies in the from-to range to the
* result list
HIDDEN_COLOUR = hiddenCol;
}
+ @Override
+ /**
+ * for Test suite only.
+ */
+ public Color getBoxColour(ResidueShaderI shader, SequenceI seq, int i)
+ {
+ return new Color(getBoxColourInt(shader, seq, i));
+ }
+
public int getBoxColourInt(ResidueShaderI shader, SequenceI seq, int i)
{
char currentChar = seq.getCharAt(i);
: shader.findColourInt(currentChar, i, seq));
}
+ /**
+ * For test suite only.
+ */
+ @Override
+ public Color getResidueColour(boolean showBoxes, ResidueShaderI shader,
+ SequenceGroup[] allGroups, final SequenceI seq, int i,
+ FeatureColourFinder finder)
+ {
+ return new Color(getResidueColourInt(showBoxes, shader, allGroups, seq,
+ i, finder));
+ }
+
+
public int getResidueColourInt(boolean showBoxes, ResidueShaderI shader,
SequenceGroup[] allGroups, final SequenceI seq, int i,
FeatureColourFinder finder)
return c;
}
- int col = getResidueBoxColourInt(showBoxes, shader, allGroups, seq,
- i);
-
+ int col = getResidueBoxColourInt(showBoxes, shader, allGroups, seq, i);
// if there's a FeatureColourFinder we might override the residue colour
// here with feature colouring
return seq.setColor(i,
finder == null || finder.noFeaturesDisplayed() ? col
- : finder.findFeatureColourInt(col, seq, i));
+ : finder.findFeatureColourInt(col, seq, i));
}
-
+
+ /**
+ * For test suite only.
+ */
+ @Override
+ protected Color getResidueBoxColour(boolean showBoxes,
+ ResidueShaderI shader, SequenceGroup[] allGroups, SequenceI seq,
+ int i)
+ {
+ return new Color(
+ getResidueBoxColourInt(showBoxes, shader, allGroups, seq, i));
+ }
+
/**
* In the overview, the showBoxes setting is ignored, as the overview displays
* the colours regardless.
assertEquals(overlaps.get(1).getEnd(), 20);
overlaps = fs.findOverlappingFeatures(12, 16);
+
assertEquals(overlaps.size(), 3);
assertEquals(overlaps.get(0).getEnd(), 20);
assertEquals(overlaps.get(1).getEnd(), 20);
final AlignViewport av = new AlignViewport(al);
ResidueColourFinder rcf = new OverviewResColourFinder();
+ ResidueShaderI sh = av.getResidueShading();
+
// gaps are grey, residues white
- assertEquals(Color.white, rcf.getResidueColour(true,
- av.getResidueShading(),
- null, seq, 0, null));
- assertEquals(Color.lightGray, rcf
- .getResidueColour(true, av.getResidueShading(), null, seq, 2,
- null));
+ assertEquals(Color.white,
+ rcf.getResidueColour(true, sh, null, seq, 0, null));
+ System.out.println(rcf.getResidueColour(true, sh, null, seq, 2, null));
+ assertEquals(Color.lightGray, rcf.getResidueColour(true,
+ sh, null, seq, 2, null));
// unaffected by showBoxes setting
assertEquals(Color.white, rcf.getResidueColour(false,
- av.getResidueShading(), null, seq, 0, null));
+ sh, null, seq, 0, null));
assertEquals(Color.lightGray, rcf.getResidueColour(false,
- av.getResidueShading(), null, seq, 2, null));
+ sh, null, seq, 2, null));
}
@Test(groups = { "Functional" })
}
av.setGlobalColourScheme(new UserColourScheme(newColours));
+ seq.resetColors();
// gap colour not specified so gaps are lightGray
assertEquals(Color.lightGray, rcf
newColours[23] = Color.pink;
av.setGlobalColourScheme(new UserColourScheme(newColours));
+ seq.resetColors();
// gap colour specified as pink
assertEquals(Color.pink, rcf.getResidueColour(true,
// unaffected by showBoxes setting
// gap colour not specified so gaps are lightGray
newColours[23] = null;
+ seq.resetColors();
+
assertEquals(Color.lightGray, rcf.getResidueColour(false,
av.getResidueShading(), null, seq, 3, null));
newColours[23] = Color.pink;
av.setGlobalColourScheme(new UserColourScheme(newColours));
+ seq.resetColors();
// gap colour specified as pink
assertEquals(Color.pink, rcf.getResidueColour(false,
// use legacy colouring
rcf = new OverviewResColourFinder(true, Color.blue, Color.red);
+
+ seq.resetColors();
// G in group specified as magenta in Zappo
assertEquals(Color.magenta, rcf.getResidueColour(false,
// use new colouring
rcf = new OverviewResColourFinder(false, Color.blue, Color.red);
+ seq.resetColors();
+
// G in group specified as magenta in Zappo
assertEquals(Color.magenta, rcf.getResidueColour(false,
av.getResidueShading(), groups, seq, 7, null));
ResidueColourFinder rcf = new OverviewResColourFinder();
ResidueShaderI shader = new ResidueShader();
+ seq.resetColors();
+
// residues white
Color c = rcf.getBoxColour(shader, seq, 0);
assertEquals(Color.white, c);
rcf = new OverviewResColourFinder(true, Color.blue, Color.red);
shader = new ResidueShader();
+ seq.resetColors();
+
// residues light gray
c = rcf.getBoxColour(shader, seq, 0);
assertEquals(Color.lightGray, c);
rcf = new OverviewResColourFinder();
shader = new ResidueShader();
+ seq.resetColors();
+
// residues white
c = rcf.getBoxColour(shader, seq, 0);
assertEquals(Color.white, c);
rcf = new OverviewResColourFinder(false, Color.blue, Color.red);
shader = new ResidueShader(new ZappoColourScheme());
+ seq.resetColors();
+
// M residue pink
c = rcf.getBoxColour(shader, seq, 0);
assertEquals(Color.pink, c);
// legacy colouring with colour scheme
rcf = new OverviewResColourFinder(true, Color.blue, Color.red);
+ seq.resetColors();
+
// M residue pink
c = rcf.getBoxColour(shader, seq, 0);
assertEquals(Color.pink, c);