Reinstated 'create tree from selected region only' with better indication that only...
[jalview.git] / src / jalview / analysis / NJTree.java
index fb0ec33..85749a1 100755 (executable)
@@ -46,71 +46,77 @@ public class NJTree {
   public NJTree(SequenceNode node) {\r
     top = node;\r
     maxheight = findHeight(top);\r
-\r
   }\r
-  // Private SequenceID class to do fuzzy .equals() method for Hashtable.\r
-\r
-  private class SeqIdname {\r
-    String id;\r
-\r
-    SeqIdname(String s) {\r
-      id = new String(s);\r
-    }\r
-    public int hashCode() {\r
-      return (id.substring(0,4).hashCode());\r
-    }\r
-    public boolean equals(Object s) {\r
-      if (s instanceof SeqIdname) {\r
-        return this.equals((SeqIdname) s);\r
-      } else {\r
-        if (s instanceof String) {\r
-          return this.equals((String) s);\r
-        }\r
-      }\r
-      return false;\r
-    }\r
 \r
-\r
-    public boolean equals(SeqIdname s) {\r
-      if (id.startsWith(s.id) || s.id.startsWith(id)) {\r
-        return true;\r
-      }\r
-      return false;\r
-    }\r
-\r
-    public boolean equals(String s) {\r
-      if (id.startsWith(s) || s.startsWith(id)) {\r
-        return true;\r
-      }\r
-      return false;\r
-    }\r
+  public String toString()\r
+  {\r
+    jalview.io.NewickFile fout = new jalview.io.NewickFile(getTopNode());\r
+    return fout.print(false,true); // distances only\r
   }\r
 \r
   public NJTree(SequenceI[] seqs, NewickFile treefile) {\r
     top = treefile.getTree();\r
     maxheight = findHeight(top);\r
-    Hashtable names = new Hashtable();\r
-    for (int i = 0; i < seqs.length; i++)\r
-    {\r
-      names.put(new SeqIdname(seqs[i].getDisplayId()), seqs[i]);\r
-    }\r
+    SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs);\r
+\r
     Vector leaves = new Vector();\r
     findLeaves(top, leaves);\r
+\r
     int i = 0;\r
     int namesleft = seqs.length;\r
+\r
     SequenceNode j;\r
-    SeqIdname nam;\r
+    SequenceI nam;\r
+    String realnam;\r
     while (i < leaves.size())\r
     {\r
       j = (SequenceNode) leaves.elementAt(i++);\r
-      nam = new SeqIdname(j.getName());\r
-      if ((namesleft>-1)\r
-          && names.containsKey(nam))\r
-      {\r
-        j.setElement(names.get(nam));\r
+      realnam = j.getName();\r
+      nam = null;\r
+      if (namesleft>-1)\r
+        nam = algnIds.findIdMatch(realnam);\r
+      if (nam != null) {\r
+        j.setElement(nam);\r
         namesleft--;\r
       } else {\r
-        j.setElement(new Sequence(nam.id, "THISISAPLACEHLDER"));\r
+        j.setElement(new Sequence(realnam, "THISISAPLACEHLDER"));\r
+        j.setPlaceholder(true);\r
+\r
+      }\r
+    }\r
+  }\r
+\r
+  /**\r
+   *\r
+   * used when the alignment associated to a tree has changed.\r
+   *\r
+   * @param alignment Vector\r
+   */\r
+  public void UpdatePlaceHolders(Vector alignment) {\r
+    Vector leaves = new Vector();\r
+    findLeaves(top, leaves);\r
+    int sz = leaves.size();\r
+    SequenceIdMatcher seqmatcher=null;\r
+    int i=0;\r
+    while (i<sz) {\r
+      SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);\r
+      if (alignment.contains(leaf.element()))\r
+        leaf.setPlaceholder(false);\r
+      else {\r
+        if (seqmatcher==null) {\r
+          // Only create this the first time we need it\r
+          SequenceI[] seqs = new SequenceI[alignment.size()];\r
+          for (int j=0; j<seqs.length; j++)\r
+            seqs[j] = (SequenceI) alignment.elementAt(j);\r
+          seqmatcher = new SequenceIdMatcher(seqs);\r
+        }\r
+        SequenceI nam = seqmatcher.findIdMatch(leaf.getName());\r
+        if (nam!=null) {\r
+          leaf.setPlaceholder(false);\r
+          leaf.setElement(nam);\r
+        } else {\r
+          leaf.setPlaceholder(true);\r
+        }\r
       }\r
     }\r
   }\r
@@ -406,7 +412,7 @@ public class NJTree {
           if (j==i) {\r
             distance[i][i] = 0;\r
           } else {\r
-            distance[i][j] = 100-Comparison.PID(sequence[i], sequence[j]);\r
+            distance[i][j] = 100-Comparison.PID(sequence[i], sequence[j], start, end);\r
             distance[j][i] = distance[i][j];\r
           }\r
         }\r
@@ -417,14 +423,14 @@ public class NJTree {
       for (int i = 0; i < noseqs-1; i++) {\r
         for (int j = i; j < noseqs; j++) {\r
           int score = 0;\r
-          for (int k=0; k < sequence[i].getLength(); k++) {\r
+          for (int k=start; k < end; k++) {\r
             try{\r
               score +=\r
                   ResidueProperties.getBLOSUM62(sequence[i].getSequence(k,\r
                   k + 1),\r
                                                 sequence[j].getSequence(k,\r
                   k + 1));\r
-            }catch(Exception ex){System.out.println("err creating BLOSUM62 tree");}\r
+            }catch(Exception ex){System.err.println("err creating BLOSUM62 tree");ex.printStackTrace();}\r
           }\r
           distance[i][j] = (float)score;\r
           if (score > maxscore) {\r
@@ -516,6 +522,11 @@ public class NJTree {
     return found;\r
   }\r
 \r
+  /**\r
+   * printNode is mainly for debugging purposes.\r
+   *\r
+   * @param node SequenceNode\r
+   */\r
   public void printNode(SequenceNode node) {\r
     if (node == null) {\r
       return;\r
@@ -538,8 +549,8 @@ public class NJTree {
 \r
       float dist = ((SequenceNode)node).dist;\r
       if (dist > maxDistValue) {\r
-         maxdist      = (SequenceNode)node;\r
-         maxDistValue = dist;\r
+          maxdist      = (SequenceNode)node;\r
+          maxDistValue = dist;\r
       }\r
     } else {\r
       findMaxDist((SequenceNode)node.left());\r
@@ -547,10 +558,10 @@ public class NJTree {
     }\r
   }\r
     public Vector getGroups() {\r
-       return groups;\r
+        return groups;\r
     }\r
     public float getMaxHeight() {\r
-       return maxheight;\r
+        return maxheight;\r
     }\r
   public void  groupNodes(SequenceNode node, float threshold) {\r
     if (node == null) {\r
@@ -639,8 +650,8 @@ public class NJTree {
   }\r
 \r
     public void reCount(SequenceNode node) {\r
-       ycount = 0;\r
-       _reCount(node);\r
+        ycount = 0;\r
+        _reCount(node);\r
     }\r
   public void _reCount(SequenceNode node) {\r
     if (node == null) {\r
@@ -664,13 +675,13 @@ public class NJTree {
 \r
   }\r
     public void swapNodes(SequenceNode node) {\r
-       if (node == null) {\r
-           return;\r
-       }\r
-       SequenceNode tmp = (SequenceNode)node.left();\r
+        if (node == null) {\r
+            return;\r
+        }\r
+        SequenceNode tmp = (SequenceNode)node.left();\r
 \r
-       node.setLeft(node.right());\r
-       node.setRight(tmp);\r
+        node.setLeft(node.right());\r
+        node.setRight(tmp);\r
     }\r
   public void changeDirection(SequenceNode node, SequenceNode dir) {\r
     if (node == null) {\r
@@ -710,13 +721,13 @@ public class NJTree {
     }\r
   }\r
     public void setMaxDist(SequenceNode node) {\r
-       this.maxdist = maxdist;\r
+        this.maxdist = maxdist;\r
     }\r
     public SequenceNode getMaxDist() {\r
-       return maxdist;\r
+        return maxdist;\r
     }\r
     public SequenceNode getTopNode() {\r
-       return top;\r
+        return top;\r
     }\r
 \r
 }\r