JAL-2629 partial refactoring of Hmmer command classes
[jalview.git] / src / jalview / hmmer / HmmerCommand.java
diff --git a/src/jalview/hmmer/HmmerCommand.java b/src/jalview/hmmer/HmmerCommand.java
new file mode 100644 (file)
index 0000000..0f45184
--- /dev/null
@@ -0,0 +1,275 @@
+package jalview.hmmer;
+
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.gui.Preferences;
+import jalview.io.HMMFile;
+import jalview.io.StockholmFile;
+import jalview.util.MessageManager;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * Base class for hmmbuild, hmmalign and hmmsearch
+ * 
+ * @author TZVanaalten
+ *
+ */
+public class HmmerCommand
+{
+  public static final String HMMBUILD = "hmmbuild";
+
+  public String JALVIEWDIRECTORY = System.getProperty("user.dir")
+          + File.separator;
+
+  public String OUTPUTALIGNMENT;
+
+  public final String SPACE = " ";
+
+  public final String ALLCOL = "--allcol ";
+
+  public final String TRIM = "--trim ";
+
+  public final String FORCEAMINO = "--amino ";
+
+  public final String FORCEDNA = "--dna ";
+
+  public final String FORCERNA = "--rna ";
+
+  Hashtable hash = new Hashtable();
+
+  List<SequenceI> hmmSeqs;
+
+  protected AlignFrame af;
+
+  public static boolean isHmmerAvailable()
+  {
+    File exec = getExecutable(HMMBUILD, Cache.getProperty(Preferences.HMMER_PATH));
+    return exec != null;
+  }
+
+  /**
+   * Uniquifies the sequences when exporting and stores their details in a
+   * hashtable.
+   * 
+   * @param seqs
+   */
+  public void uniquifySequences(SequenceI[] seqs)
+  {
+    hash = jalview.analysis.SeqsetUtils.uniquify(seqs, true);
+  }
+
+  /**
+   * Recover the sequence data lost by uniquifying.
+   * 
+   * @param seqs
+   */
+  public void recoverSequenceNames(SequenceI[] seqs)
+  {
+    jalview.analysis.SeqsetUtils.deuniquify(hash, seqs);
+  }
+
+  /**
+   * Runs a command in the command line.
+   * 
+   * @param command
+   * @throws IOException
+   * @throws InterruptedException
+   */
+  public boolean runCommand(String command)
+          throws IOException, InterruptedException
+  {
+    try
+    {
+      final Process p = Runtime.getRuntime().exec(command);
+
+      new Thread(new Runnable()
+      {
+        @Override
+        public void run()
+        {
+          BufferedReader input = new BufferedReader(
+                  new InputStreamReader(p.getInputStream()));
+          String line = null;
+
+          try
+          {
+            while ((line = input.readLine()) != null)
+            {
+              System.out.println(line);
+            }
+          } catch (IOException e)
+          {
+            e.printStackTrace();
+          }
+        }
+      }).start();
+
+      p.waitFor();
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Exports an alignment and/or HMM to the specified file.
+   * 
+   * @param alignment
+   * @throws IOException
+   */
+  public void exportData(SequenceI[] seqs, File stoLocation,
+          HiddenMarkovModel hmm, File hmmLocation, AnnotatedCollectionI al)
+          throws IOException
+  {
+    if (seqs != null)
+    {
+      AlignmentI newAl = new Alignment(seqs);
+      if (stoLocation != null && al != null)
+      {
+        for (AlignmentAnnotation annot : al.getAlignmentAnnotation())
+        {
+          if (annot.label.contains("Reference") || "RF".equals(annot.label))
+          {
+            AlignmentAnnotation newRF;
+            if (annot.annotations.length > newAl.getWidth())
+            {
+              Annotation[] rfAnnots = new Annotation[newAl.getWidth()];
+              System.arraycopy(annot.annotations, 0, rfAnnots, 0,
+                      rfAnnots.length);
+              newRF = new AlignmentAnnotation("RF", "Reference Positions",
+                      rfAnnots);
+            }
+            else
+            {
+              newRF = new AlignmentAnnotation(annot);
+            }
+            newAl.addAnnotation(newRF);
+          }
+        }
+      }
+
+      StockholmFile file = new StockholmFile(newAl);
+      String output = file.print(seqs, false);
+      PrintWriter writer = new PrintWriter(stoLocation);
+      writer.println(output);
+      writer.close();
+    }
+
+    if (hmm != null)
+    {
+      HMMFile file = new HMMFile(hmm);
+      PrintWriter writer = new PrintWriter(hmmLocation);
+      writer.print(file.print());
+      writer.close();
+    }
+  }
+
+  /**
+   * Adds any HMM sequences removed before submitting the alignment as a job
+   * back into the alignment.
+   * 
+   * @param af
+   */
+  public void addHMMConsensusSequences(AlignFrame af)
+  {
+    AlignmentI al = af.getViewport().getAlignment();
+    if (hmmSeqs == null || hmmSeqs.size() < 1)
+    {
+      return;
+    }
+    for (SequenceI seq : hmmSeqs)
+    {
+      Integer position = seq.getPreviousPosition();
+      al.getSequences().add(position, seq);
+    }
+    af.getViewport().setAlignment(al);
+    af.alignPanel.adjustAnnotationHeight();
+    af.getViewport().updateSequenceIdColours();
+    af.buildSortByAnnotationScoresMenu();
+  }
+
+  /**
+   * Returns the list of HMM sequences removed
+   * 
+   * @return
+   */
+  public List<SequenceI> getHmmSeqs()
+  {
+    return hmmSeqs;
+  }
+
+  /**
+   * Sets the list of removed HMM sequences
+   * 
+   * @param hmmSeqs
+   */
+  public void setHmmSeqs(List<SequenceI> hmmSeqs)
+  {
+    this.hmmSeqs = hmmSeqs;
+  }
+
+  /**
+   * Answers the full path to the given hmmer executable, or null if file cannot
+   * be found or is not executable
+   * 
+   * @param cmd
+   *          command short name e.g. hmmalign
+   * @return
+   */
+  protected String getCommandRoot(String cmd)
+  {
+    String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH);
+    File file = getExecutable(cmd, binariesFolder);
+    if (file == null && af != null)
+    {
+        JvOptionPane.showInternalMessageDialog(af,
+                MessageManager.getString("warn.hmm_command_failed"));
+    }
+
+    return file == null ? null : file.getAbsolutePath();
+  }
+
+  /**
+   * Answers the executable file for the given hmmer command, or null if not
+   * found or not executable. The path to the executable is the command name
+   * prefixed by the hmmer binaries folder path, optionally with .exe appended.
+   * 
+   * @param cmd
+   *          hmmer command short name, for example hmmbuild
+   * @param binaryPath
+   *          parent folder containing hmmer executables
+   * @return
+   */
+  public static File getExecutable(String cmd, String binaryPath)
+  {
+    File file = new File(binaryPath, cmd);
+    if (!file.canExecute())
+    {
+      file = new File(binaryPath, cmd + ".exe");
+      {
+        if (!file.canExecute())
+        {
+          file = null;
+        }
+      }
+    }
+    return file;
+  }
+}