Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / gui / TreeCanvas.java
index 55ce44a..9180d52 100755 (executable)
@@ -53,6 +53,7 @@ import javax.swing.ToolTipManager;
 import jalview.analysis.Conservation;
 import jalview.analysis.TreeModel;
 import jalview.api.AlignViewportI;
+import jalview.bin.Console;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.BinaryNode;
@@ -66,6 +67,7 @@ import jalview.datamodel.SequenceNode;
 import jalview.gui.JalviewColourChooser.ColourChooserListener;
 import jalview.schemes.ColourSchemeI;
 import jalview.structure.SelectionSource;
+import jalview.util.ColorUtils;
 import jalview.util.Format;
 import jalview.util.MessageManager;
 import jalview.ws.datamodel.MappableContactMatrixI;
@@ -143,7 +145,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     scrollPane = scroller;
     addMouseListener(this);
     addMouseMotionListener(this);
-    
+
     ToolTipManager.sharedInstance().registerComponent(this);
   }
 
@@ -180,6 +182,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     PaintRefresher.Refresh(tp, av.getSequenceSetId());
     repaint();
   }
+
   /**
    * DOCUMENT ME!
    * 
@@ -221,6 +224,13 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     boolean has_placeholders = false;
     longestName = "";
 
+    AlignmentAnnotation aa = tp.getAssocAnnotation();
+    ContactMatrixI cm = (aa != null) ? av.getContactMatrix(aa) : null;
+    if (cm != null && cm.hasCutHeight())
+    {
+      threshold = (float) cm.getCutHeight();
+    }
+
     for (int i = 0; i < leaves.size(); i++)
     {
       BinaryNode lf = leaves.elementAt(i);
@@ -236,6 +246,18 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         longestName = TreeCanvas.PLACEHOLDER
                 + ((Sequence) lf.element()).getName();
       }
+      if (tp.isColumnWise() && cm != null)
+      {
+        // get color from group colours, if they are set for the matrix
+        try
+        {
+          Color col = cm.getGroupColorForPosition(parseColumnNode(lf));
+          setColor(lf, col.brighter());
+        } catch (NumberFormatException ex)
+        {
+        }
+        ;
+      }
     }
 
     setMarkPlaceholders(has_placeholders);
@@ -259,7 +281,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
    * @param offy
    *          DOCUMENT ME!
    */
-  public void drawNode(Graphics g, BinaryNode node, float chunk,
+  public void drawNode(Graphics g, BinaryNode node, double chunk,
           double wscale, int width, int offx, int offy)
   {
     if (node == null)
@@ -389,9 +411,9 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       }
 
       int ystart = (node.left() == null ? 0
-              : (int) (((BinaryNode) node.left()).ycount * chunk)) + offy;
+              : (int) (node.left().ycount * chunk)) + offy;
       int yend = (node.right() == null ? 0
-              : (int) (((BinaryNode) node.right()).ycount * chunk)) + offy;
+              : (int) (node.right().ycount * chunk)) + offy;
 
       Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
       nodeHash.put(node, pos);
@@ -774,8 +796,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
 
     if (top.count == 0)
     {
-      top.count = ((BinaryNode) top.left()).count
-              + ((BinaryNode) top.right()).count;
+      top.count = top.left().count + top.right().count;
     }
 
     float chunk = (float) (height - (offy)) / top.count;
@@ -864,7 +885,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       Vector<BinaryNode> leaves = tree.findLeaves(highlightNode);
       if (tp.isColumnWise())
       {
-        markColumnsFor(getAssociatedPanels(), leaves, Color.red,false);
+        markColumnsFor(getAssociatedPanels(), leaves, Color.red, false);
       }
       else
       {
@@ -1025,7 +1046,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
           threshold = 0f;
         }
       }
-
+      Console.log.debug("Tree cut threshold set at:" + threshold);
       PaintRefresher.Refresh(tp,
               getAssociatedPanel().av.getSequenceSetId());
       repaint();
@@ -1040,8 +1061,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     Map<BitSet, Color> colors = new HashMap();
     for (int i = 0; i < groups.size(); i++)
     {
-      Color col = new Color((int) (Math.random() * 255),
-              (int) (Math.random() * 255), (int) (Math.random() * 255));
+      Color col = ColorUtils.getARandomColor();
+
       setColor(groups.get(i), col.brighter());
 
       Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
@@ -1071,41 +1092,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
             cm.setColorForGroup(gp, colors.get(gp));
           }
         }
-        // stash colors in linked annotation row.
-        // doesn't work yet. TESTS!
-        int sstart = aa.sequenceRef != null ? aa.sequenceRef.getStart() - 1
-                : 0;
-        Annotation ae;
-        Color gpcol = null;
-        int[] seqpos = null;
-        for (BitSet gp : colors.keySet())
-        {
-          gpcol = colors.get(gp);
-          for (int p = gp.nextSetBit(0); p >= 0
-                  && p < Integer.MAX_VALUE; p = gp.nextSetBit(p + 1))
-          {
-            if (cm instanceof MappableContactMatrixI)
-            {
-              MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
-              seqpos = mcm.getMappedPositionsFor(aa.sequenceRef, p);
-              if (seqpos == null)
-              {
-                // no mapping for this column.
-                continue;
-              }
-              // TODO: handle ranges...
-              ae = aa.getAnnotationForPosition(seqpos[0]);
-            }
-            else
-            {
-              ae = aa.getAnnotationForPosition(p + sstart);
-            }
-            if (ae != null)
-            {
-              ae.colour = gpcol.brighter().darker();
-            }
-          }
-        }
+        cm.transferGroupColorsTo(aa);
       }
     }
 
@@ -1124,14 +1111,19 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     }
   }
 
+  private int parseColumnNode(BinaryNode bn) throws NumberFormatException
+  {
+    return Integer.parseInt(
+            bn.getName().substring(bn.getName().indexOf("c") + 1));
+  }
+
   private boolean isColumnForNodeSelected(BinaryNode bn)
   {
     SequenceI rseq = tp.assocAnnotation.sequenceRef;
     int colm = -1;
     try
     {
-      colm = Integer.parseInt(
-              bn.getName().substring(bn.getName().indexOf("c") + 1));
+      colm = parseColumnNode(bn);
     } catch (Exception e)
     {
       return false;
@@ -1144,16 +1136,17 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     ColumnSelection cs = av.getColumnSelection();
     HiddenColumns hc = av.getAlignment().getHiddenColumns();
     AlignmentAnnotation aa = tp.getAssocAnnotation();
-    int offp=-1;
+    int offp = -1;
     if (aa != null)
     {
       ContactMatrixI cm = av.getContactMatrix(aa);
-      // generally, we assume cm has 1:1 mapping to annotation row - probably wrong
+      // generally, we assume cm has 1:1 mapping to annotation row - probably
+      // wrong
       // but.. if
       if (cm instanceof MappableContactMatrixI)
       {
         int[] pos;
-          // use the mappable's mapping - always the case for PAE Matrices so good
+        // use the mappable's mapping - always the case for PAE Matrices so good
         // for 2.11.3
         MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
         pos = mcm.getMappedPositionsFor(rseq, colm + 1);
@@ -1162,16 +1155,18 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         {
           offp = rseq.findIndex(pos[0]);
         }
-      } else {
+      }
+      else
+      {
         offp = colm;
       }
     }
-    if (offp<=0)
+    if (offp <= 0)
     {
       return false;
     }
 
-    offp-=2;
+    offp -= 2;
     if (!av.hasHiddenColumns())
     {
       return cs.contains(offp);
@@ -1183,6 +1178,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     }
     return false;
   }
+
   private BitSet createColumnGroupFor(Vector<BinaryNode> l, Color col)
   {
     BitSet gp = new BitSet();
@@ -1198,8 +1194,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         // parse out from nodename
         try
         {
-          colm = Integer.parseInt(
-                  bn.getName().substring(bn.getName().indexOf("c") + 1));
+          colm = parseColumnNode(bn);
         } catch (Exception e)
         {
           continue;
@@ -1241,17 +1236,16 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       {
         continue;
       }
-      if (mcm!=null)
+      if (mcm != null)
       {
-        int[] seqpos = mcm.getMappedPositionsFor(
-                tp.assocAnnotation.sequenceRef, colm);
+        int[] seqpos = mcm.getMappedPositionsFor(rseq, colm);
         if (seqpos == null)
         {
           // no mapping for this column.
           continue;
         }
         // TODO: handle ranges...
-        offp = seqpos[0]-1;
+        offp = rseq.findIndex(seqpos[0]) - 1;
       }
       else
       {