3 import jalview.analysis.SeqsetUtils;
4 import jalview.bin.Cache;
5 import jalview.datamodel.Alignment;
6 import jalview.datamodel.AlignmentAnnotation;
7 import jalview.datamodel.AlignmentI;
8 import jalview.datamodel.AnnotatedCollectionI;
9 import jalview.datamodel.Annotation;
10 import jalview.datamodel.HiddenMarkovModel;
11 import jalview.datamodel.SequenceI;
12 import jalview.gui.AlignFrame;
13 import jalview.gui.JvOptionPane;
14 import jalview.gui.Preferences;
15 import jalview.io.HMMFile;
16 import jalview.io.StockholmFile;
17 import jalview.util.FileUtils;
18 import jalview.util.MessageManager;
19 import jalview.util.Platform;
20 import jalview.ws.params.ArgumentI;
22 import java.io.BufferedReader;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.io.PrintWriter;
27 import java.util.ArrayList;
28 import java.util.Hashtable;
29 import java.util.List;
32 * Base class for hmmbuild, hmmalign and hmmsearch
37 public abstract class HmmerCommand implements Runnable
39 public static final String HMMBUILD = "hmmbuild";
41 protected final AlignFrame af;
43 protected final AlignmentI alignment;
45 protected final List<ArgumentI> params;
53 public HmmerCommand(AlignFrame alignFrame, List<ArgumentI> args)
56 alignment = af.getViewport().getAlignment();
61 * Answers true if preference HMMER_PATH is set, and its value is the path to
62 * a directory that contains an executable <code>hmmbuild</code> or
63 * <code>hmmbuild.exe</code>, else false
67 public static boolean isHmmerAvailable()
69 File exec = FileUtils.getExecutable(HMMBUILD,
70 Cache.getProperty(Preferences.HMMER_PATH));
75 * Uniquifies the sequences when exporting and stores their details in a
80 protected Hashtable stashSequences(SequenceI[] seqs)
82 return SeqsetUtils.uniquify(seqs, true);
86 * Restores the sequence data lost by uniquifying
91 protected void recoverSequences(Hashtable hashtable, SequenceI[] seqs)
93 SeqsetUtils.deuniquify(hashtable, seqs);
97 * Runs a command as a separate process and waits for it to complete. Answers
98 * true if the process return status is zero, else false.
101 * the executable command and any arguments to it
102 * @throws IOException
104 public boolean runCommand(List<String> command)
107 List<String> commands = Platform.isWindows() ? wrapWithCygwin(command)
112 ProcessBuilder pb = new ProcessBuilder(commands);
113 pb.redirectErrorStream(true); // merge syserr to sysout
114 final Process p = pb.start();
115 new Thread(new Runnable()
120 BufferedReader input = new BufferedReader(
121 new InputStreamReader(p.getInputStream()));
124 String line = input.readLine();
127 System.out.println(line);
128 line = input.readLine();
130 } catch (IOException e)
138 int exitValue = p.exitValue();
141 Cache.log.error("Command failed, return code = " + exitValue);
142 Cache.log.error("Command/args were: " + commands.toString());
144 return exitValue == 0; // 0 is success, by convention
145 } catch (Exception e)
153 * Converts the given command to a Cygwin "run" command wrapper
158 protected List<String> wrapWithCygwin(List<String> command)
160 File runCygwin = FileUtils.getExecutable("run",
161 Cache.getProperty(Preferences.CYGWIN_PATH));
162 if (runCygwin == null)
164 Cache.log.error("Cygwin shell not found");
168 List<String> wrapped = new ArrayList<>();
169 wrapped.add(runCygwin.getAbsolutePath());
170 if (!command.isEmpty())
172 wrapped.add(command.get(0));
173 // wrapped.add("--quote");
174 StringBuilder args = new StringBuilder();
175 for (String arg : command.subList(1, command.size()))
177 args.append(" ").append(arg);
179 wrapped.add(args.toString());
181 // TODO this doesn't yet pass parameters successfully
187 * Exports an alignment, and reference (RF) annotation if present, to the
188 * specified file, in Stockholm format
193 * @throws IOException
195 public void exportStockholm(SequenceI[] seqs, File toFile,
196 AnnotatedCollectionI annotated) throws IOException
202 AlignmentI newAl = new Alignment(seqs);
203 if (!newAl.isAligned())
208 if (toFile != null && annotated != null)
210 AlignmentAnnotation[] annots = annotated.getAlignmentAnnotation();
213 for (AlignmentAnnotation annot : annots)
215 if (annot.label.contains("Reference") || "RF".equals(annot.label))
217 AlignmentAnnotation newRF;
218 if (annot.annotations.length > newAl.getWidth())
220 Annotation[] rfAnnots = new Annotation[newAl.getWidth()];
221 System.arraycopy(annot.annotations, 0, rfAnnots, 0,
223 newRF = new AlignmentAnnotation("RF", "Reference Positions",
228 newRF = new AlignmentAnnotation(annot);
230 newAl.addAnnotation(newRF);
236 StockholmFile file = new StockholmFile(newAl);
237 String output = file.print(seqs, false);
238 PrintWriter writer = new PrintWriter(toFile);
239 writer.println(output);
244 * Answers the full path to the given hmmer executable, or null if file cannot
245 * be found or is not executable
248 * command short name e.g. hmmalign
251 protected String getCommandPath(String cmd)
253 String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH);
254 File file = FileUtils.getExecutable(cmd, binariesFolder);
255 if (file == null && af != null)
257 JvOptionPane.showInternalMessageDialog(af,
258 MessageManager.getString("warn.hmm_command_failed"));
261 return file == null ? null : file.getAbsolutePath();
265 * Exports an HMM to the specified file
269 * @throws IOException
271 public void exportHmm(HiddenMarkovModel hmm, File hmmFile)
276 HMMFile file = new HMMFile(hmm);
277 PrintWriter writer = new PrintWriter(hmmFile);
278 writer.print(file.print());