--- /dev/null
+package jalview.datamodel;
+
+import jalview.ws.params.InvalidArgumentException;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ContactMatrix implements ContactMatrixI
+{
+ /**
+ * are contacts reflexive ?
+ */
+ boolean symmetric = true;
+
+ public ContactMatrix(boolean symmetric)
+ {
+ this.symmetric = symmetric;
+ }
+
+ List<List<Float>> contacts = null;
+
+ int width = 0, numcontacts = 0;
+
+ float min = 0f, max = 0f;
+
+ public void addContact(int left, int right, float strength)
+ {
+ if (left < 0 || right < 0)
+ {
+ throw new Error(new InvalidArgumentException(
+ "Cannot have negative indices for contact left=" + left
+ + " right=" + right + " strength=" + strength));
+ }
+ if (symmetric)
+ {
+ if (left > right)
+ {
+ // swap
+ int r = right;
+ right = left;
+ left = r;
+ }
+ }
+ if (contacts == null)
+ {
+ // TODO: use sparse list for efficiency ?
+ contacts = new ArrayList<List<Float>>();
+ }
+ List<Float> clist = contacts.get(left);
+ if (clist == null)
+ {
+ clist = new ArrayList<Float>();
+ contacts.set(left, clist);
+ }
+ Float last = clist.set(right, strength);
+ // TODO: if last is non null, may need to recompute range
+ checkBounds(strength);
+ if (last == null)
+ {
+ numcontacts++;
+ }
+ }
+
+ private void checkBounds(float strength)
+ {
+ if (min > strength)
+ {
+ min = strength;
+ }
+ if (max < strength)
+ {
+ max = strength;
+ }
+ }
+
+ Color minColor = Color.white, maxColor = Color.magenta;
+
+ Color shadeFor(float value)
+ {
+ return jalview.util.ColorUtils.getGraduatedColour(value, 0,
+ Color.white, max, Color.magenta);
+ }
+ @Override
+ public ContactListI getContactList(final int column)
+ {
+ if (column < 0 || column >= width)
+ {
+ return null;
+ }
+ return new ContactListI()
+ {
+ int p = column;
+
+ @Override
+ public Color getColorForScore(int column)
+ {
+
+ return shadeFor((float) getContactAt(column));
+ }
+
+ @Override
+ public Color getColorForRange(int i, int j)
+ {
+ double contc;
+ double v = 0;
+ for (int r=i;r<j;r++)
+ {
+ contc = getContactAt(r);
+ if (contc != contc)
+ {
+ v += contc;
+ }
+ }
+ // average for moment - probably more interested in maxIntProj though
+ return shadeFor(((float) v) / (j - i + 1));
+ }
+
+ @Override
+ public int getColumnWidth()
+ {
+ return 1;
+ }
+
+ @Override
+ public int getContactHeight()
+ {
+ return width;
+
+ }
+
+ @Override
+ public double getContactAt(int column)
+ {
+ List<Float> clist;
+ Float cl = null;
+ if (symmetric)
+ {
+ if (p < column)
+ {
+ clist = contacts.get(p);
+ cl = clist.get(column);
+ }
+ else
+ {
+ clist = contacts.get(column);
+ cl = clist.get(p);
+ }
+ }
+ else
+ {
+ clist = contacts.get(p);
+ cl = clist.get(column);
+ }
+ if (cl == null)
+ {
+ // return 0 not NaN ?
+ return Double.NaN;
+ }
+ return cl.doubleValue();
+ }
+ };
+ }
+
+}