JAL-3899 Update usages of uniquify and deuniquify.
[jalview.git] / src / jalview / hmmer / HMMBuild.java
index 97dc59a..fa9cd92 100644 (file)
@@ -1,10 +1,12 @@
 package jalview.hmmer;
 
+import jalview.analysis.SeqsetUtils.SequenceInfo;
 import jalview.api.AlignViewportI;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ResidueCount;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
@@ -12,16 +14,16 @@ import jalview.gui.JvOptionPane;
 import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.io.HMMFile;
+import jalview.util.FileUtils;
 import jalview.util.MessageManager;
-import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.params.ArgumentI;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * A class that runs the hmmbuild command as a separate process.
@@ -56,7 +58,7 @@ public class HMMBuild extends HmmerCommand
   @Override
   public void run()
   {
-    if (params == null)
+    if (params == null || params.isEmpty())
     {
       Cache.log.error("No parameters to HMMBuild!|");
       return;
@@ -97,20 +99,26 @@ public class HMMBuild extends HmmerCommand
           AlignViewportI viewport)
   {
     List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
+    boolean foundArg = false;
+
     for (ArgumentI arg : params)
     {
       String name = arg.getName();
       if (MessageManager.getString("label.hmmbuild_for").equals(name))
       {
+        foundArg = true;
         String value = arg.getValue();
+
         if (MessageManager.getString("label.alignment").equals(value))
         {
-          runBuildFor.add(alignment);
+          runBuildFor.add(viewport.getAlignmentView(false)
+                  .getVisibleAlignment('-'));
         }
         else if (MessageManager.getString("label.groups_and_alignment")
                 .equals(value))
         {
-          runBuildFor.add(alignment);
+          runBuildFor.add(viewport.getAlignmentView(false)
+                  .getVisibleAlignment('-'));
           runBuildFor.addAll(viewport.getAlignment().getGroups());
         }
         else if (MessageManager.getString("label.groups").equals(value))
@@ -135,6 +143,15 @@ public class HMMBuild extends HmmerCommand
         }
       }
     }
+
+    /*
+     * default is to build for the whole alignment
+     */
+    if (!foundArg)
+    {
+      runBuildFor.add(alignment);
+    }
+
     return runBuildFor;
   }
 
@@ -149,11 +166,8 @@ public class HMMBuild extends HmmerCommand
     File alignmentFile = null;
     try
     {
-      hmmFile = createTempFile("hmm", ".hmm");
-      alignmentFile = createTempFile("output", ".sto");
-      List<SequenceI> seqs = ac.getSequences();
-      List<SequenceI> copy = new ArrayList<>();
-      copy.addAll(seqs);
+      hmmFile = FileUtils.createTempFile("hmm", ".hmm");
+      alignmentFile = FileUtils.createTempFile("output", ".sto");
 
       if (ac instanceof Alignment)
       {
@@ -165,34 +179,41 @@ public class HMMBuild extends HmmerCommand
         }
       }
 
-      /*
-       * copy over sequences, excluding hmm consensus sequences
-       * hmm sequences are also deleted in preparation for 
-       * re-adding them when recalculated; Information annotation is not
-       * deleted, it will be updated to reference the new hmm sequence
-       * by InformationThread.findOrCreateAnnotation
-       */
-      Iterator<SequenceI> it = copy.iterator();
-      while (it.hasNext())
+      deleteHmmSequences(ac);
+
+      List<SequenceI> copy = new ArrayList<>();
+      if (ac instanceof Alignment)
+      {
+        copy.addAll(ac.getSequences());
+      }
+      else
       {
-        SequenceI seq = it.next();
-        if (seq.isHMMConsensusSequence())
+        SequenceI[] sel = ((SequenceGroup) ac)
+                                               .getSelectionAsNewSequences((AlignmentI) ac.getContext());
+        for (SequenceI seq : sel)
         {
-          alignment.deleteSequence(seq);
-          it.remove();
+          if (seq != null)
+          {
+            copy.add(seq);
+          }
         }
       }
+      // TODO rather than copy alignment data we should anonymize in situ -
+      // export/File import could use anonymization hash to reinstate references
+      // at import level ?
 
       SequenceI[] copyArray = copy.toArray(new SequenceI[copy.size()]);
-      Hashtable sequencesHash = stashSequences(copyArray);
+      Map<String, SequenceInfo> sequencesHash = stashSequences(copyArray);
 
       exportStockholm(copyArray, alignmentFile, ac);
 
-      recoverSequences(sequencesHash, seqs.toArray(new SequenceI[] {}));
+      recoverSequences(sequencesHash, copy.toArray(new SequenceI[] {}));
 
       boolean ran = runCommand(alignmentFile, hmmFile, ac);
       if (!ran)
       {
+        JvOptionPane.showInternalMessageDialog(af, MessageManager
+                .formatMessage("warn.command_failed", "hmmbuild"));
         return;
       }
       importData(hmmFile, ac);
@@ -240,7 +261,7 @@ public class HMMBuild extends HmmerCommand
      * HMM name (will be given to consensus sequence) is
      * - as specified by an input parameter if set
      * - else group name with _HMM appended (if for a group)
-     * - else align fame title with _HMM appended (if title is not too long)
+     * - else align frame title with _HMM appended (if title is not too long)
      * - else "Alignment_HMM" 
      */
     String name = "";
@@ -290,8 +311,8 @@ public class HMMBuild extends HmmerCommand
       args.add(ARG_DNA);
     }
 
-    args.add(hmmFile.getAbsolutePath());
-    args.add(sequencesFile.getAbsolutePath());
+    args.add(getFilePath(hmmFile, true));
+    args.add(getFilePath(sequencesFile, true));
 
     return runCommand(args);
   }
@@ -309,34 +330,43 @@ public class HMMBuild extends HmmerCommand
   private void importData(File hmmFile, AnnotatedCollectionI ac)
           throws IOException
   {
+    if (hmmFile.length() == 0L)
+    {
+      Cache.log.error("Error: hmmbuild produced empty hmm file");
+      return;
+    }
+
     HMMFile file = new HMMFile(
             new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
-    SequenceI[] seqs = file.getSeqsAsArray();
-    SequenceI hmmSeq = seqs[0];
-    hmmSeq.createDatasetSequence();
+    SequenceI hmmSeq = file.getHMM().getConsensusSequence();
+
+
+
+    ResidueCount counts = new ResidueCount(alignment.getSequences());
+    hmmSeq.getHMM().setBackgroundFrequencies(counts);
+
+    if (hmmSeq == null)
+    {
+      // hmmbuild failure not detected earlier
+      return;
+    }
+
     if (ac instanceof SequenceGroup)
     {
       SequenceGroup grp = (SequenceGroup) ac;
-      hmmSeq.insertCharAt(0, ac.getStartRes(), '-');
+      char gapChar = alignment.getGapCharacter();
+      hmmSeq.insertCharAt(0, ac.getStartRes(), gapChar);
       hmmSeq.insertCharAt(ac.getEndRes() + 1,
-              alignment.getWidth() - ac.getEndRes() - 1, '-');
-      hmmSeq.updateHMMMapping();
+              alignment.getWidth() - ac.getEndRes() - 1, gapChar);
       SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
       int topIndex = alignment.findIndex(topSeq);
       alignment.insertSequenceAt(topIndex, hmmSeq);
       ac.setSeqrep(hmmSeq);
       grp.addSequence(hmmSeq, false);
-      grp.setHmmConsensus(hmmSeq);
     }
     else
     {
       alignment.insertSequenceAt(0, hmmSeq);
-      alignment.setHmmConsensus(hmmSeq);
-    }
-
-    if (af.getSelectedHMM() == null)
-    {
-      af.setSelectedHMMSequence(hmmSeq);
     }
   }
 }