JAL-1953 2.11.2 with Archeopteryx!
[jalview.git] / src / jalview / analysis / AlignmentSorter.java
index 9943a22..6005208 100755 (executable)
@@ -29,12 +29,15 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeNodeI;
 import jalview.util.QuickSort;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Routines for manipulating the order of a multiple sequence alignment TODO:
@@ -69,6 +72,8 @@ public class AlignmentSorter
 
   static TreeModel lastTree = null;
 
+  static TreeI lastExternalTree = null;
+
   static boolean sortTreeAscending = true;
 
   /*
@@ -108,8 +113,9 @@ public class AlignmentSorter
             true);
     for (int i = 0; i < nSeq; i++)
     {
-      scores[i] = (float) PIDModel.computePID(align.getSequenceAt(i)
-              .getSequenceAsString(), refSeq, pidParams);
+      scores[i] = (float) PIDModel.computePID(
+              align.getSequenceAt(i).getSequenceAsString(), refSeq,
+              pidParams);
       seqs[i] = align.getSequenceAt(i);
     }
 
@@ -142,8 +148,8 @@ public class AlignmentSorter
     }
 
     // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
-    List<SequenceI> asq;
-    synchronized (asq = align.getSequences())
+    List<SequenceI> asq = align.getSequences();
+    synchronized (asq)
     {
       for (int i = 0; i < len; i++)
       {
@@ -178,10 +184,10 @@ public class AlignmentSorter
   public static void setOrder(AlignmentI align, SequenceI[] seqs)
   {
     // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
-    List<SequenceI> algn;
-    synchronized (algn = align.getSequences())
+    List<SequenceI> algn = align.getSequences();
+    synchronized (algn)
     {
-      List<SequenceI> tmp = new ArrayList<SequenceI>();
+      List<SequenceI> tmp = new ArrayList<>();
 
       for (int i = 0; i < seqs.length; i++)
       {
@@ -278,7 +284,7 @@ public class AlignmentSorter
   {
     // MAINTAINS ORIGNAL SEQUENCE ORDER,
     // ORDERS BY GROUP SIZE
-    List<SequenceGroup> groups = new ArrayList<SequenceGroup>();
+    List<SequenceGroup> groups = new ArrayList<>();
 
     if (groups.hashCode() != lastGroupHash)
     {
@@ -314,7 +320,7 @@ public class AlignmentSorter
 
     // NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER
     // /////////////////////////////////////////////
-    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    List<SequenceI> seqs = new ArrayList<>();
 
     for (int i = 0; i < groups.size(); i++)
     {
@@ -356,7 +362,7 @@ public class AlignmentSorter
     // tmp2 = tmp.retainAll(mask);
     // return tmp2.addAll(mask.removeAll(tmp2))
 
-    ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
+    ArrayList<SequenceI> seqs = new ArrayList<>();
     int i, idx;
     boolean[] tmask = new boolean[mask.size()];
 
@@ -415,7 +421,8 @@ public class AlignmentSorter
     }
     else
     {
-      setReverseOrder(align, vectorSubsetToArray(tmp, align.getSequences()));
+      setReverseOrder(align,
+              vectorSubsetToArray(tmp, align.getSequences()));
     }
   }
 
@@ -434,9 +441,9 @@ public class AlignmentSorter
   {
     int nSeq = align.getHeight();
 
-    List<SequenceI> tmp = new ArrayList<SequenceI>();
+    List<SequenceI> tmp = new ArrayList<>();
 
-    tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());
+    tmp = _sortByTree(tree.getTopNode(), tmp);
 
     if (tmp.size() != nSeq)
     {
@@ -450,18 +457,36 @@ public class AlignmentSorter
 
       if (tmp.size() != nSeq)
       {
-        System.err
-                .println("WARNING: tmp.size()="
-                        + tmp.size()
-                        + " != nseq="
-                        + nSeq
-                        + " in getOrderByTree - tree contains sequences not in alignment");
+        System.err.println("WARNING: tmp.size()=" + tmp.size() + " != nseq="
+                + nSeq
+                + " in getOrderByTree - tree contains sequences not in alignment");
       }
     }
 
     return tmp;
   }
 
+
+
+  private static List<SequenceI> getOrderByTree(TreeI aptxTree,
+          Map<TreeNodeI, SequenceI> nodesWithBoundSeqs)
+  {
+    List<SequenceI> seqsByTreeOrder = new ArrayList<>();
+    if (!aptxTree.isEmpty())
+    {
+      for (final Iterator<TreeNodeI> iter = aptxTree
+              .iterateInPreOrder(); iter.hasNext();)
+      {
+        TreeNodeI treeNode = iter.next();
+        seqsByTreeOrder.add(nodesWithBoundSeqs.get(treeNode));
+      }
+
+    }
+    return seqsByTreeOrder;
+
+
+  }
+
   /**
    * Sorts the alignment by a given tree
    * 
@@ -491,7 +516,50 @@ public class AlignmentSorter
     }
     else
     {
-      setReverseOrder(align, vectorSubsetToArray(tmp, align.getSequences()));
+      setReverseOrder(align,
+              vectorSubsetToArray(tmp, align.getSequences()));
+    }
+  }
+
+  /**
+   * Sorts the alignment by a given tree from Archaeopteryx
+   * 
+   * @param align
+   *          alignment to order
+   * @param tree
+   *          tree which has
+   */
+  public static void sortByTree(AlignmentI align,
+          Map<TreeNodeI, SequenceI> nodesBoundToSequences,
+          TreeI treeI) throws IllegalArgumentException
+  {
+    List<SequenceI> tmp = getOrderByTree(treeI, nodesBoundToSequences);
+
+    if (!tmp.isEmpty())
+    {
+      if (lastExternalTree != treeI)
+      {
+        sortTreeAscending = true;
+        lastExternalTree = treeI;
+      }
+      else
+      {
+        sortTreeAscending = !sortTreeAscending;
+      }
+
+      if (sortTreeAscending)
+      {
+        setOrder(align, tmp);
+      }
+      else
+      {
+        setReverseOrder(align,
+                vectorSubsetToArray(tmp, align.getSequences()));
+      }
+    }
+    else
+    {
+      throw new IllegalArgumentException();
     }
   }
 
@@ -535,7 +603,7 @@ public class AlignmentSorter
    * @return DOCUMENT ME!
    */
   private static List<SequenceI> _sortByTree(SequenceNode node,
-          List<SequenceI> tmp, List<SequenceI> seqset)
+          List<SequenceI> tmp)
   {
     if (node == null)
     {
@@ -564,13 +632,15 @@ public class AlignmentSorter
     }
     else
     {
-      _sortByTree(left, tmp, seqset);
-      _sortByTree(right, tmp, seqset);
+      _sortByTree(left, tmp);
+      _sortByTree(right, tmp);
     }
 
     return tmp;
   }
 
+
+
   // Ordering Objects
   // Alignment.sortBy(OrderObj) - sequence of sequence pointer refs in
   // appropriate order
@@ -586,7 +656,7 @@ public class AlignmentSorter
 
     for (int i = 0; i < alignment.length; i++)
     {
-      ids[i] = (new Float(alignment[i].getName().substring(8)))
+      ids[i] = (Float.valueOf(alignment[i].getName().substring(8)))
               .floatValue();
     }
 
@@ -681,27 +751,6 @@ public class AlignmentSorter
 
   public static String FEATURE_DENSITY = "density";
 
-  private static boolean containsIgnoreCase(final String lab,
-          final List<String> labs)
-  {
-    if (labs == null)
-    {
-      return true;
-    }
-    if (lab == null)
-    {
-      return false;
-    }
-    for (String label : labs)
-    {
-      if (lab.equalsIgnoreCase(label))
-      {
-        return true;
-      }
-    }
-    return false;
-  }
-
   /**
    * Sort sequences by feature score or density, optionally restricted by
    * feature types, feature groups, or alignment start/end positions.
@@ -729,14 +778,15 @@ public class AlignmentSorter
     if (method != FEATURE_SCORE && method != FEATURE_LABEL
             && method != FEATURE_DENSITY)
     {
-      String msg = String
-              .format("Implementation Error - sortByFeature method must be either '%s' or '%s'",
-                      FEATURE_SCORE, FEATURE_DENSITY);
+      String msg = String.format(
+              "Implementation Error - sortByFeature method must be either '%s' or '%s'",
+              FEATURE_SCORE, FEATURE_DENSITY);
       System.err.println(msg);
       return;
     }
 
-    flipFeatureSortIfUnchanged(method, featureTypes, groups, startCol, endCol);
+    flipFeatureSortIfUnchanged(method, featureTypes, groups, startCol,
+            endCol);
 
     SequenceI[] seqs = alignment.getSequencesArray();
 
@@ -755,8 +805,8 @@ public class AlignmentSorter
        * get sequence residues overlapping column region
        * and features for residue positions and specified types
        */
-      String[] types = featureTypes == null ? null : featureTypes
-              .toArray(new String[featureTypes.size()]);
+      String[] types = featureTypes == null ? null
+              : featureTypes.toArray(new String[featureTypes.size()]);
       List<SequenceFeature> sfs = seqs[i].findFeatures(startCol + 1,
               endCol + 1, types);