Various sort methods added and bugs fixed (coping with associated trees and alignment...
authorjprocter <Jim Procter>
Fri, 20 May 2005 15:17:00 +0000 (15:17 +0000)
committerjprocter <Jim Procter>
Fri, 20 May 2005 15:17:00 +0000 (15:17 +0000)
src/jalview/analysis/AlignmentSorter.java

index 64682c1..48e771e 100755 (executable)
@@ -36,7 +36,12 @@ public class AlignmentSorter {
     //    align.setGroups(newg);\r
   }\r
 \r
-  /**    */\r
+  /**\r
+   * Sort by Percentage Identity\r
+   *\r
+   * @param align AlignmentI\r
+   * @param s SequenceI\r
+   */\r
   public static void sortByPID(AlignmentI align, SequenceI s) {\r
     int nSeq = align.getHeight();\r
 \r
@@ -72,16 +77,17 @@ public class AlignmentSorter {
   }\r
 \r
   private static void setOrder(AlignmentI align, Vector tmp) {\r
-    setOrder(align,vectorToArray(tmp));\r
+    setOrder(align,vectorSubsetToArray(tmp, align.getSequences()));\r
   }\r
 \r
   private static void setOrder(AlignmentI align, SequenceI [] seqs) {\r
-// NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work\r
-    for (int i = 0; i < seqs.length; i++) {\r
-      align.getSequences().setElementAt(seqs[i],i);\r
-    }\r
-  }\r
+      // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work\r
 \r
+      Vector algn = align.getSequences();\r
+\r
+      for (int i = 0, p = 0; i < seqs.length; i++)\r
+        algn.setElementAt(seqs[i], p++);\r
+  }\r
   /**    */\r
   static boolean sortIdAscending = true;\r
   public static void sortByID(AlignmentI align) {\r
@@ -144,27 +150,70 @@ public class AlignmentSorter {
     return seqs;\r
   }\r
 \r
+  private static SequenceI [] vectorSubsetToArray(Vector tmp, Vector mask) {\r
+    Vector seqs = new Vector();\r
+    int i,m, p;\r
+    boolean[] tmask = new boolean[m=mask.size()];\r
+    for (i=0; i<m; i++)\r
+      tmask[i] = true;\r
+    for (i=0; i < tmp.size(); i++) {\r
+      Object sq;\r
+      if (mask.contains(sq=tmp.elementAt(i))) {\r
+        tmask[mask.indexOf(sq)] = false;\r
+        seqs.addElement(sq);\r
+        m--;\r
+      }\r
+    }\r
+    for (i=0; i<tmask.length; i++)\r
+      if (tmask[i])\r
+        seqs.addElement(mask.elementAt(i));\r
+    return vectorToArray(seqs);\r
+  }\r
+\r
+\r
+  public static void sortBy(AlignmentI align, AlignmentOrder order) {\r
+    // Get an order vector that is a proper permutation of the positions in align\r
+    Vector tmp = order.getOrder();\r
+    if (tmp.size()<align.getHeight())\r
+      addStrays(align, tmp);\r
+    setOrder(align, tmp);\r
+  }\r
+\r
   static boolean sortTreeAscending = true;\r
-  public static void sortByTree(AlignmentI align, NJTree tree) {\r
-    int    nSeq = align.getHeight();\r
+\r
+  public static Vector getOrderByTree(AlignmentI align, NJTree tree) {\r
+    int nSeq = align.getHeight();\r
 \r
     Vector tmp = new Vector();\r
 \r
-    tmp = _sortByTree(tree.getTopNode(),tmp);\r
+    tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());\r
 \r
-    if (tmp.size() != nSeq) {\r
-      System.err.println("ERROR: tmp.size() != nseq in sortByTree");\r
-      if (tmp.size() < nSeq) {\r
-        addStrays(align,tmp);\r
+    if (tmp.size() != nSeq)\r
+    {\r
+      // TODO: JBPNote - decide if this is always an error\r
+      // (eg. not when a tree is associated to another alignment which has more\r
+      //  sequences)\r
+\r
+      if (tmp.size() < nSeq)\r
+      {\r
+        addStrays(align, tmp);\r
       }\r
+      if (tmp.size() != nSeq)\r
+        System.err.println("ERROR: tmp.size()="+tmp.size()+" != nseq="+nSeq+" in getOrderByTree");\r
+\r
     }\r
+    return tmp;\r
+  }\r
 \r
+  public static void sortByTree(AlignmentI align, NJTree tree) {\r
+    Vector tmp = getOrderByTree(align, tree);\r
+    // tmp should properly permute align with tree.\r
     if(sortTreeAscending)\r
       setOrder(align,tmp);\r
     else\r
-      setReverseOrder(align, vectorToArray(tmp));\r
+      setReverseOrder(align, vectorSubsetToArray(tmp, align.getSequences()));\r
 \r
-      sortTreeAscending = !sortTreeAscending;\r
+      sortTreeAscending = !sortTreeAscending; // JBPNote: this is totally random - have to keep last tree sort ref ...\r
   }\r
 \r
   private static void addStrays(AlignmentI align, Vector seqs) {\r
@@ -179,21 +228,38 @@ public class AlignmentSorter {
     }\r
   }\r
 \r
-  public static Vector _sortByTree(SequenceNode node, Vector tmp) {\r
+  public static Vector _sortByTree(SequenceNode node, Vector tmp, Vector seqset) {\r
     if (node == null) {return tmp;}\r
 \r
     SequenceNode left = (SequenceNode)node.left();\r
     SequenceNode right = (SequenceNode)node.right();\r
 \r
     if (left == null && right == null) {\r
-      if (node.element() instanceof SequenceI) {\r
-        tmp.addElement((SequenceI)node.element());\r
+      if (!node.isPlaceholder() && node.element()!=null)\r
+        if (node.element() instanceof SequenceI)\r
+          if (!tmp.contains(node.element()))\r
+              tmp.addElement((SequenceI)node.element());\r
         return tmp;\r
-      }\r
+\r
     } else {\r
-      _sortByTree(left,tmp);\r
-      _sortByTree(right,tmp);\r
+      _sortByTree(left,tmp, seqset);\r
+      _sortByTree(right,tmp, seqset);\r
     }\r
     return tmp;\r
   }\r
+  // Ordering Objects\r
+  // Alignment.sortBy(OrderObj) - sequence of sequence pointer refs in appropriate order\r
+  //\r
+\r
+  /**\r
+   * recover the order of sequences given by the safe numbering scheme introducd\r
+   * SeqsetUtils.uniquify.\r
+   */\r
+  public static void recoverOrder(SequenceI[] alignment) {\r
+    float[] ids = new float[alignment.length];\r
+    for (int i=0; i<alignment.length; i++)\r
+      ids[i] = (new Float(alignment[i].getName().substring(8))).floatValue();\r
+    jalview.util.QuickSort.sort(ids, alignment);\r
+  }\r
+\r
 }\r