+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;
+ }
+}