JAL-2349 JAL-2382 contact matrix datamodel object
authorJim Procter <jprocter@issues.jalview.org>
Mon, 16 Jan 2017 12:27:32 +0000 (12:27 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Mon, 16 Jan 2017 12:27:32 +0000 (12:27 +0000)
src/jalview/datamodel/ContactMatrix.java [new file with mode: 0644]

diff --git a/src/jalview/datamodel/ContactMatrix.java b/src/jalview/datamodel/ContactMatrix.java
new file mode 100644 (file)
index 0000000..fac1dee
--- /dev/null
@@ -0,0 +1,165 @@
+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();
+      }
+    };
+  }
+
+}