Merge branch 'mmw/bug/JAL-4241-annotation-alignment-fix-slivka' into development...
[jalview.git] / src / jalview / analysis / SeqsetUtils.java
index 6683e3b..5420aff 100755 (executable)
@@ -20,6 +20,8 @@
  */
 package jalview.analysis;
 
+import jalview.bin.Cache;
+import jalview.bin.Console;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.PDBEntry;
@@ -28,15 +30,18 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Vector;
+import static java.lang.String.format;
+
+import java.nio.CharBuffer;
 
 public class SeqsetUtils
 {
@@ -76,8 +81,8 @@ public class SeqsetUtils
       ArrayList<SequenceFeature> feats = new ArrayList<>(
           seq.getFeatures().getAllFeatures());
       sqinfo.features = Optional.of(feats);
-      sqinfo.pdbId = Optional.of(Objects.requireNonNullElse(
-          seq.getAllPDBEntries(), new ArrayList<>()));
+      var pdbEntries = seq.getAllPDBEntries();
+      sqinfo.pdbId = Optional.of(pdbEntries != null ? pdbEntries : new ArrayList<>());
     }
     if (seq.hasHMMProfile())
     {
@@ -88,6 +93,32 @@ public class SeqsetUtils
   }
 
   /**
+   * Filter the sequence through the mask leaving only characters at positions
+   * where the mask value was true. The length of the resulting array is
+   * the cardinality of the mask from 0 to sequence length.
+   *
+   * @param sequence
+   *          input sequence
+   * @param mask
+   *          mask used to filter the sequence characters
+   * @return input array filtered through the mask
+   */
+  public static char[] filterSequence(char[] sequence, BitSet mask)
+  {
+    mask = mask.get(0, sequence.length);
+    char[] result = new char[mask.cardinality()];
+    for (int i = mask.nextSetBit(0), j = 0; i >= 0;)
+    {
+      result[j++] = sequence[i];
+      if (i == Integer.MAX_VALUE)
+        // prevents integer overflow of (i + 1)
+        break;
+      i = mask.nextSetBit(i + 1);
+    }
+    return result;
+  }
+
+  /**
    * Recover essential properties of a sequence from a hashtable TODO: replace
    * these methods with something more elegant.
    * 
@@ -117,9 +148,12 @@ public class SeqsetUtils
       sq.setDescription(sqinfo.description.get());
     if (sqinfo.dataset.isPresent())
     {
-      assert sqinfo.features.isEmpty() :
-        "Setting dataset sequence for a sequence which has sequence features. " +
-          "Dataset sequence features will not be visible.";
+      if (sqinfo.features.isPresent())
+      {
+        Console.warn("Setting dataset sequence for a sequence which has " +
+            "sequence features. Dataset sequence features will not be visible.");
+        assert false;
+      }
       sq.setDatasetSequence(sqinfo.dataset.get());
     }
     if (sqinfo.hmm.isPresent())
@@ -240,25 +274,27 @@ public class SeqsetUtils
         {
           if (!quiet)
           {
-            System.err.println("Can't find '" + ((String) key)
-                    + "' in uniquified alignment");
+            Console.warn(format("Can't find '%s' in uniquified alignment",
+                key));
           }
         }
       } catch (ClassCastException ccastex) {
         if (!quiet)
         {
-          System.err.println("Unexpected object in SeqSet map : "+key.getClass());
+          Console.error("Unexpected object in SeqSet map : "+ key.getClass());
         }
       }
     }
     if (unmatched.size() > 0 && !quiet)
     {
-      System.err.println("Did not find matches for :");
-      for (Enumeration<SequenceI> i = unmatched.elements();
-          i.hasMoreElements();)
+      StringBuilder sb = new StringBuilder("Did not find match for sequences: ");
+      Enumeration<SequenceI> i = unmatched.elements();
+      sb.append(i.nextElement().getName());
+      for (; i.hasMoreElements();)
       {
-        System.out.println(((SequenceI) i.nextElement()).getName());
+        sb.append(", " + i.nextElement().getName());
       }
+      Console.warn(sb.toString());
       return false;
     }