JAL-2629 simplifying method signatures in Hmmer command classes
[jalview.git] / src / jalview / hmmer / HmmerCommand.java
1 package jalview.hmmer;
2
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.MessageManager;
18 import jalview.ws.params.ArgumentI;
19
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.PrintWriter;
25 import java.util.Hashtable;
26 import java.util.List;
27
28 /**
29  * Base class for hmmbuild, hmmalign and hmmsearch
30  * 
31  * @author TZVanaalten
32  *
33  */
34 public class HmmerCommand
35 {
36   public static final String HMMBUILD = "hmmbuild";
37
38   private Hashtable hash = new Hashtable();
39
40   protected AlignFrame af;
41
42   protected List<ArgumentI> params;
43
44   public HmmerCommand(AlignFrame alignFrame, List<ArgumentI> args)
45   {
46     af = alignFrame;
47     params = args;
48   }
49
50   public static boolean isHmmerAvailable()
51   {
52     File exec = getExecutable(HMMBUILD, Cache.getProperty(Preferences.HMMER_PATH));
53     return exec != null;
54   }
55
56   /**
57    * Uniquifies the sequences when exporting and stores their details in a
58    * hashtable
59    * 
60    * @param seqs
61    */
62   protected void stashSequences(SequenceI[] seqs)
63   {
64     hash = SeqsetUtils.uniquify(seqs, true);
65   }
66
67   /**
68    * Restores the sequence data lost by uniquifying
69    * 
70    * @param seqs
71    */
72   protected void recoverSequences(SequenceI[] seqs)
73   {
74     SeqsetUtils.deuniquify(hash, seqs);
75   }
76
77   /**
78    * Runs a command as a separate process
79    * 
80    * @param command
81    *          the executable command and any arguments to it
82    * @throws IOException
83    */
84   public boolean runCommand(List<String> command)
85           throws IOException
86   {
87     try
88     {
89       ProcessBuilder pb = new ProcessBuilder(command);
90       pb.redirectErrorStream(true); // send syserr to sysout
91       final Process p = pb.start();
92       new Thread(new Runnable()
93       {
94         @Override
95         public void run()
96         {
97           BufferedReader input = new BufferedReader(
98                   new InputStreamReader(p.getInputStream()));
99           try
100           {
101             String line = input.readLine();
102             while (line != null)
103             {
104               System.out.println(line);
105               line = input.readLine();
106             }
107           } catch (IOException e)
108           {
109             e.printStackTrace();
110           }
111         }
112       }).start();
113
114       p.waitFor();
115       return p.exitValue() == 0; // 0 is success, by convention
116     } catch (Exception e)
117     {
118       e.printStackTrace();
119       return false;
120     }
121   }
122
123   /**
124    * Exports an alignment (and possibly annotation) to the specified file, in
125    * Stockholm format
126    * 
127    * @param seqs
128    * @param toFile
129    * @param annotated
130    * @throws IOException
131    */
132   public void exportStockholm(SequenceI[] seqs, File toFile,
133           AnnotatedCollectionI annotated)
134           throws IOException
135   {
136     if (seqs != null)
137     {
138       AlignmentI newAl = new Alignment(seqs);
139       if (toFile != null && annotated != null)
140       {
141         for (AlignmentAnnotation annot : annotated.getAlignmentAnnotation())
142         {
143           if (annot.label.contains("Reference") || "RF".equals(annot.label))
144           {
145             AlignmentAnnotation newRF;
146             if (annot.annotations.length > newAl.getWidth())
147             {
148               Annotation[] rfAnnots = new Annotation[newAl.getWidth()];
149               System.arraycopy(annot.annotations, 0, rfAnnots, 0,
150                       rfAnnots.length);
151               newRF = new AlignmentAnnotation("RF", "Reference Positions",
152                       rfAnnots);
153             }
154             else
155             {
156               newRF = new AlignmentAnnotation(annot);
157             }
158             newAl.addAnnotation(newRF);
159           }
160         }
161       }
162
163       StockholmFile file = new StockholmFile(newAl);
164       String output = file.print(seqs, false);
165       PrintWriter writer = new PrintWriter(toFile);
166       writer.println(output);
167       writer.close();
168     }
169   }
170
171   /**
172    * Answers the full path to the given hmmer executable, or null if file cannot
173    * be found or is not executable
174    * 
175    * @param cmd
176    *          command short name e.g. hmmalign
177    * @return
178    */
179   protected String getCommandPath(String cmd)
180   {
181     String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH);
182     File file = getExecutable(cmd, binariesFolder);
183     if (file == null && af != null)
184     {
185         JvOptionPane.showInternalMessageDialog(af,
186                 MessageManager.getString("warn.hmm_command_failed"));
187     }
188
189     return file == null ? null : file.getAbsolutePath();
190   }
191
192   /**
193    * Answers the executable file for the given hmmer command, or null if not
194    * found or not executable. The path to the executable is the command name
195    * prefixed by the hmmer binaries folder path, optionally with .exe appended.
196    * 
197    * @param cmd
198    *          hmmer command short name, for example hmmbuild
199    * @param binaryPath
200    *          parent folder containing hmmer executables
201    * @return
202    */
203   public static File getExecutable(String cmd, String binaryPath)
204   {
205     File file = new File(binaryPath, cmd);
206     if (!file.canExecute())
207     {
208       file = new File(binaryPath, cmd + ".exe");
209       {
210         if (!file.canExecute())
211         {
212           file = null;
213         }
214       }
215     }
216     return file;
217   }
218
219   /**
220    * A convenience method to create a temporary file that is deleted on exit of
221    * the JVM
222    * 
223    * @param prefix
224    * @param suffix
225    * @return
226    * @throws IOException
227    */
228   protected File createTempFile(String prefix, String suffix)
229           throws IOException
230   {
231     File f = File.createTempFile(prefix, suffix);
232     f.deleteOnExit();
233     return f;
234
235   }
236
237   /**
238    * Exports an HMM to the specified file
239    * 
240    * @param hmm
241    * @param hmmFile
242    * @throws IOException
243    */
244   public void exportHmm(HiddenMarkovModel hmm, File hmmFile)
245           throws IOException
246   {
247     if (hmm != null)
248     {
249       HMMFile file = new HMMFile(hmm);
250       PrintWriter writer = new PrintWriter(hmmFile);
251       writer.print(file.print());
252       writer.close();
253     }
254   }
255 }