JAL-3759 exclude hidden columns when processing column selection
[jalview.git] / src / jalview / analysis / Grouping.java
index 7b6dda1..88d3525 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -21,6 +21,7 @@
 package jalview.analysis;
 
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 
@@ -102,6 +103,107 @@ public class Grouping
   }
 
   /**
+   * Divide the given sequences based on the equivalence of characters at
+   * selected columns If exgroups is provided, existing groups will be
+   * subdivided.
+   * 
+   * @param sequences
+   * @param columnSelection
+   * @param list
+   * @param hiddenColumns
+   * @return
+   */
+  public static SequenceGroup[] makeGroupsFromCols(SequenceI[] sequences,
+          ColumnSelection cs, List<SequenceGroup> list,
+          HiddenColumns hiddenColumns)
+  {
+    // TODO: determine how to get/recover input data for group generation
+    Map<String, List<SequenceI>> gps = new HashMap<String, List<SequenceI>>();
+    Map<String, SequenceGroup> pgroup = new HashMap<String, SequenceGroup>();
+    if (list != null)
+    {
+      for (SequenceGroup sg : list)
+      {
+        for (SequenceI sq : sg.getSequences(null))
+        {
+          pgroup.put(sq.toString(), sg);
+        }
+      }
+    }
+
+    /*
+     * get selected columns (in the order they were selected);
+     * note this could include right-to-left ranges
+     */
+    int[] spos = new int[cs.getSelected().size()];
+    int width = -1;
+    int i = 0;
+    for (Integer pos : cs.getSelected())
+    {
+      if (hiddenColumns == null || hiddenColumns.isVisible(pos.intValue()))
+      {
+        spos[i++] = pos.intValue();
+      }
+    }
+    if (i < spos.length)
+    {
+      // mark end of visible column position
+      spos[i] = -1;
+    }
+    // actual number of visible columns
+    for (i = 0; i < sequences.length; i++)
+    {
+      int slen = sequences[i].getLength();
+      if (width < slen)
+      {
+        width = slen;
+      }
+
+      SequenceGroup pgp = pgroup.get(((Object) sequences[i]).toString());
+      StringBuilder schar = new StringBuilder();
+      if (pgp != null)
+      {
+        schar.append(pgp.getName() + ":");
+      }
+      for (int p : spos)
+      {
+        if (p < 0)
+        {
+          break;
+        }
+        if (p >= slen)
+        {
+          schar.append("~");
+        }
+        else
+        {
+          schar.append(sequences[i].getCharAt(p));
+        }
+      }
+      List<SequenceI> svec = gps.get(schar.toString());
+      if (svec == null)
+      {
+        svec = new ArrayList<SequenceI>();
+        gps.put(schar.toString(), svec);
+      }
+      svec.add(sequences[i]);
+    }
+    // make some groups
+    SequenceGroup[] groups = new SequenceGroup[gps.size()];
+    i = 0;
+    for (String key : gps.keySet())
+    {
+      SequenceGroup group = new SequenceGroup(gps.get(key),
+              "Subseq: " + key, null, true, true, false, 0, width - 1);
+
+      groups[i++] = group;
+    }
+    gps.clear();
+    pgroup.clear();
+    return groups;
+  }
+
+  /**
    * subdivide the given sequences based on the distribution of features
    * 
    * @param featureLabels