JAL-2629 removed SequenceI.get/setLastPosition and related code
[jalview.git] / src / jalview / hmmer / HMMBuildThread.java
index 48796e4..24106d6 100644 (file)
 package jalview.hmmer;
 
-import jalview.bin.Cache;
+import jalview.analysis.SeqsetUtils;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
 import jalview.gui.JvOptionPane;
-import jalview.gui.Preferences;
 import jalview.io.DataSourceType;
-import jalview.io.FileFormat;
+import jalview.io.FileParse;
+import jalview.io.HMMFile;
 import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.swing.JOptionPane;
 
-public class HMMBuildThread implements Runnable
+public class HMMBuildThread extends HmmerCommand implements Runnable
 {
-  HMMERCommands cmds = new HMMERCommands();
-  AlignFrame af;
+  AlignViewport viewport;
+
+  boolean multiJob = false;
+
   AlignmentI alignment;
 
   SequenceGroup group;
 
-  boolean canRun = true;
+  List<ArgumentI> params;
+
+  boolean forGroup = false;
 
   File hmmTemp = null;
 
   File stoTemp = null;
 
   long barID;
-  
-  public HMMBuildThread(AlignFrame af)
+
+  /**
+   * This is used for validation purposes. Do not use!
+   * 
+   * @param viewport
+   */
+  public HMMBuildThread(AlignmentI alignment)
   {
-    this.af = af;
-    if (af.getViewport().getSelectionGroup() != null)
-    {
-      group = af.getViewport().getSelectionGroup();
-    }
-    alignment = af.getViewport().getAlignment();
+    this.alignment = alignment;
+    forGroup = false;
+  }
 
+  public HMMBuildThread(AlignFrame af, List<ArgumentI> args)
+  {
+    this.af = af;
+    viewport = af.getViewport();
+    params = args;
   }
 
+  /**
+   * Builds a HMM from an alignment, then imports and adds it to the alignment.
+   */
   @Override
   public void run()
   {
     barID = System.currentTimeMillis();
-    af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
-            barID);
-    cmds.HMMERFOLDER = Cache.getProperty(Preferences.HMMER_PATH);
+    if (af != null)
+    {
+      af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
+              barID);
+    }
+
+    List<SequenceGroup> groups = new ArrayList<>();
+    if (params != null)
+    {
+      for (ArgumentI arg : params)
+      {
+        String name = arg.getName();
+        if (MessageManager.getString("label.hmmbuild_for").equals(name))
+        {
+          String value = arg.getValue();
+          if ("Alignment".equals(value))
+          {
+            alignment = viewport.getAlignment();
+            break;
+          }
+          else if ("All groups and alignment".equals(value))
+          {
+            alignment = viewport.getAlignment();
+            groups.addAll(viewport.getAlignment().getGroups());
+            if (groups.size() > 0)
+            {
+              multiJob = true;
+            }
+            break;
+          }
+          else if ("All groups".equals(value))
+          {
+            alignment = null;
+            groups = viewport.getAlignment().getGroups();
+            if (groups.size() > 0)
+            {
+              multiJob = true;
+            }
+            break;
+          }
+          else if ("Selected group".equals(value))
+          {
+            alignment = null;
+            groups.add(viewport.getSelectionGroup());
+            break;
+          }
+        }
+        else if (MessageManager.getString("label.use_reference")
+                .equals(name))
+        {
+          if (!af.getViewport().hasReferenceAnnotation())
+          {
+            if (af != null)
+            {
+              af.setProgressBar(
+                      MessageManager.getString("status.running_hmmbuild"),
+                      barID);
+            }
+            JvOptionPane.showInternalMessageDialog(af, MessageManager
+                    .getString("warn.no_reference_annotation"));
+            return;
+          }
+        }
+      }
+    }
+    else if (viewport != null)
+    {
+      alignment = viewport.getAlignment();
+    }
+
+    if (alignment != null)
+    {
+      forGroup = false;
+      runHMMBuild();
+    }
+
+    if (alignment == null)
+    {
+      alignment = viewport.getAlignment();
+    }
+
+    if (groups != null && groups.size() > 0)
+    {
+      for (SequenceGroup grp : groups)
+      {
+        group = grp;
+        forGroup = true;
+        runHMMBuild();
+      }
+    }
+
+    if (af != null)
+    {
+      af.setProgressBar("", barID);
+    }
+  }
+
+  private void runHMMBuild()
+  {
     if (alignment == null && group == null)
     {
       JOptionPane.showMessageDialog(af,
-              MessageManager.getString("label.no_sequence_data"));
-      return;
+              MessageManager.getString("warn.no_sequence_data"));
     }
     try
     {
@@ -71,107 +184,233 @@ public class HMMBuildThread implements Runnable
 
     try
     {
-    try
-    {
+      try
+      {
         SequenceI[] array;
-        List<SequenceI> seqs = alignment
-                .getHMMConsensusSequences(true);
-        cmds.setHmmSeqs(seqs);
-        if (group != null)
+        List<SequenceI> hmmSeqs = null;
+        if (forGroup)
         {
+          hmmSeqs = group.getHMMConsensusSequences();
+          if (hmmSeqs.size() > 0)
+          {
+            // todo why this test? means can't re-run hmmbuild on a group?
+            return;
+          }
           array = group.getSelectionAsNewSequences(alignment);
         }
         else
         {
+          hmmSeqs = alignment.getHMMConsensusSequences();
           if (!alignment.isAligned())
           {
             alignment.padGaps();
           }
           array = alignment.getSequencesArray();
         }
-        cmds.uniquifySequences(array);
-        cmds.exportData(array, stoTemp, null, null);
-        jalview.analysis.SeqsetUtils.deuniquify(cmds.hash, array);
 
-    } catch (FileNotFoundException e)
-    {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
+        if (array.length < 1)
+        {
+          if (af != null)
+          {
+            JOptionPane.showMessageDialog(af,
+                    MessageManager.getString("warn.no_sequence_data"));
+          }
+          return;
+        }
 
-    }
-    try
-    {
+        /*
+         * copy over sequences excluding hmm consensus sequences
+         */
+        SequenceI[] newArr = new SequenceI[array.length - hmmSeqs.size()];
+        int index = 0;
+        for (SequenceI seq : array)
+        {
+          if (!seq.isHMMConsensusSequence())
+          {
+            newArr[index] = new Sequence(seq);
+            index++;
+          }
+        }
+
+        uniquifySequences(newArr);
+
+        if (forGroup)
+        {
+          exportData(newArr, stoTemp, null, null, group);
+        }
+        else
+        {
+          exportData(newArr, stoTemp, null, null, alignment);
+        }
+
+        SeqsetUtils.deuniquify(hash, array);
+
+      } catch (FileNotFoundException e)
+      {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+
+      }
+      try
+      {
         boolean ran = runCommand();
         if (!ran)
         {
-          JvOptionPane.showInternalMessageDialog(af,
-                  MessageManager.getString("warn.hmmbuild_failed"));
           return;
         }
-    } catch (IOException | InterruptedException e)
-    {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    }
-    try
-    {
+      } catch (IOException | InterruptedException e)
+      {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+      try
+      {
 
-      importData();
-    } catch (IOException | InterruptedException e)
-    {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    }
+        importData();
+      } catch (IOException | InterruptedException e)
+      {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
     } catch (Exception e)
     {
       e.printStackTrace();
-    } finally
-    {
-      af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
-              barID);
     }
   }
 
-  
-
-  
+  /**
+   * Executes the hmmbuild command in the command line.
+   * 
+   * @return
+   * @throws IOException
+   * @throws InterruptedException
+   */
   private boolean runCommand() throws IOException, InterruptedException
   {
-    File file = new File(cmds.HMMERFOLDER + "/binaries/hmmbuild.exe");
-    if (!file.canExecute())
+    String binaryPath = getCommandRoot(HMMBUILD);
+    if (binaryPath == null)
     {
       return false;
     }
-    String command = cmds.HMMERFOLDER + cmds.HMMBUILD + cmds.NAME
-            + af.getName() + cmds.SPACE;
+    String command = binaryPath + SPACE;
+    String name = null;
+
+    if (params != null)
+    {
+      for (ArgumentI arg : params)
+      {
+        String argName = arg.getName();
+        switch (argName)
+        {
+        case "HMM Name":
+          name = arg.getValue();
+          name = name.trim();
+          break;
+        case "Use Reference Annotation":
+          command += "--hand ";
+          break;
+
+        }
+      }
+    }
+
+    if (forGroup && multiJob)
+    {
+      name = group.getName() + "_HMM";
+    }
+
+    if (name == null || "".equals(name))
+    {
+      if (af != null)
+      {
+        if (af.getTitle().length() < 15)
+        {
+          name = af.getTitle();
+        }
+      }
+      if (name == null || "".equals(name))
+      {
+        name = "Alignment";
+      }
+
+    }
+
+    command += "-n " + name.replace(' ', '_') + SPACE;
     if (!alignment.isNucleotide())
     {
-      command += cmds.FORCEAMINO; // TODO check for rna
+      command += FORCEAMINO; // TODO check for rna
     }
     else
     {
-      command += cmds.FORCEDNA;
+      command += FORCEDNA;
     }
 
-    command += hmmTemp.getAbsolutePath()
-            + cmds.SPACE + stoTemp.getAbsolutePath() + cmds.SPACE;
-    return cmds.runCommand(command);
+    command += hmmTemp.getAbsolutePath() + SPACE + stoTemp.getAbsolutePath()
+            + SPACE;
+    return runCommand(command);
   }
-  
+
+  /**
+   * Imports the .hmm file produced by hmmbuild.
+   * 
+   * @throws IOException
+   * @throws InterruptedException
+   */
   private void importData() throws IOException, InterruptedException
   {
-    cmds.addHMMConsensusSequences(af);
-    af.loadJalviewDataFile(hmmTemp.getAbsolutePath(), DataSourceType.FILE,
-            FileFormat.HMMER3, null);
+    HMMFile file = new HMMFile(
+            new FileParse(hmmTemp.getAbsolutePath(), DataSourceType.FILE));
+    SequenceI[] seqs = file.getSeqsAsArray();
+    SequenceI seq = seqs[0];
+    seq.createDatasetSequence();
+    if (group != null)
+    {
+      seq.insertCharAt(0, group.getStartRes(), '-');
+      seq.insertCharAt(group.getEndRes() + 1,
+              alignment.getWidth() - group.getEndRes() - 1, '-');
+      seq.updateHMMMapping();
+      SequenceI topSeq = group.getSequencesInOrder(alignment)[0];
+      int topIndex = alignment.findIndex(topSeq);
+      alignment.insertSequenceAt(topIndex, seq);
+      group.setSeqrep(seq);
+      group.addSequence(seq, false);
+    }
+    else
+    {
+      alignment.insertSequenceAt(0, seq);
+    }
+
+    if (viewport != null)
+    {
+      viewport.alignmentChanged(viewport.getAlignPanel());
+      viewport.getAlignPanel().adjustAnnotationHeight();
+      viewport.updateSequenceIdColours();
+
+      if (viewport.getAlignPanel().alignFrame.getSelectedHMM() == null)
+      {
+        viewport.getAlignPanel().alignFrame.setSelectedHMMSequence(seq);
+      }
+    }
     hmmTemp.delete();
     stoTemp.delete();
   }
-  
-  public boolean canRun()
+
+  /**
+   * Runs hmmbuild, and waits for the results to be imported before continuing
+   */
+  public void hmmbuildWaitTillComplete()
   {
-    return canRun;
+    Thread loader = new Thread(this);
+    loader.start();
+
+    while (loader.isAlive())
+    {
+      try
+      {
+        Thread.sleep(500);
+      } catch (Exception ex)
+      {
+      }
+    }
   }
-  
-  
 }