JAL-2629 partial refactoring of Hmmer command classes
[jalview.git] / src / jalview / hmmer / HmmerCommand.java
1 package jalview.hmmer;
2
3 import jalview.bin.Cache;
4 import jalview.datamodel.Alignment;
5 import jalview.datamodel.AlignmentAnnotation;
6 import jalview.datamodel.AlignmentI;
7 import jalview.datamodel.AnnotatedCollectionI;
8 import jalview.datamodel.Annotation;
9 import jalview.datamodel.HiddenMarkovModel;
10 import jalview.datamodel.SequenceI;
11 import jalview.gui.AlignFrame;
12 import jalview.gui.JvOptionPane;
13 import jalview.gui.Preferences;
14 import jalview.io.HMMFile;
15 import jalview.io.StockholmFile;
16 import jalview.util.MessageManager;
17
18 import java.io.BufferedReader;
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStreamReader;
22 import java.io.PrintWriter;
23 import java.util.Hashtable;
24 import java.util.List;
25
26 /**
27  * Base class for hmmbuild, hmmalign and hmmsearch
28  * 
29  * @author TZVanaalten
30  *
31  */
32 public class HmmerCommand
33 {
34   public static final String HMMBUILD = "hmmbuild";
35
36   public String JALVIEWDIRECTORY = System.getProperty("user.dir")
37           + File.separator;
38
39   public String OUTPUTALIGNMENT;
40
41   public final String SPACE = " ";
42
43   public final String ALLCOL = "--allcol ";
44
45   public final String TRIM = "--trim ";
46
47   public final String FORCEAMINO = "--amino ";
48
49   public final String FORCEDNA = "--dna ";
50
51   public final String FORCERNA = "--rna ";
52
53   Hashtable hash = new Hashtable();
54
55   List<SequenceI> hmmSeqs;
56
57   protected AlignFrame af;
58
59   public static boolean isHmmerAvailable()
60   {
61     File exec = getExecutable(HMMBUILD, Cache.getProperty(Preferences.HMMER_PATH));
62     return exec != null;
63   }
64
65   /**
66    * Uniquifies the sequences when exporting and stores their details in a
67    * hashtable.
68    * 
69    * @param seqs
70    */
71   public void uniquifySequences(SequenceI[] seqs)
72   {
73     hash = jalview.analysis.SeqsetUtils.uniquify(seqs, true);
74   }
75
76   /**
77    * Recover the sequence data lost by uniquifying.
78    * 
79    * @param seqs
80    */
81   public void recoverSequenceNames(SequenceI[] seqs)
82   {
83     jalview.analysis.SeqsetUtils.deuniquify(hash, seqs);
84   }
85
86   /**
87    * Runs a command in the command line.
88    * 
89    * @param command
90    * @throws IOException
91    * @throws InterruptedException
92    */
93   public boolean runCommand(String command)
94           throws IOException, InterruptedException
95   {
96     try
97     {
98       final Process p = Runtime.getRuntime().exec(command);
99
100       new Thread(new Runnable()
101       {
102         @Override
103         public void run()
104         {
105           BufferedReader input = new BufferedReader(
106                   new InputStreamReader(p.getInputStream()));
107           String line = null;
108
109           try
110           {
111             while ((line = input.readLine()) != null)
112             {
113               System.out.println(line);
114             }
115           } catch (IOException e)
116           {
117             e.printStackTrace();
118           }
119         }
120       }).start();
121
122       p.waitFor();
123     } catch (Exception e)
124     {
125       e.printStackTrace();
126       return false;
127     }
128     return true;
129   }
130
131   /**
132    * Exports an alignment and/or HMM to the specified file.
133    * 
134    * @param alignment
135    * @throws IOException
136    */
137   public void exportData(SequenceI[] seqs, File stoLocation,
138           HiddenMarkovModel hmm, File hmmLocation, AnnotatedCollectionI al)
139           throws IOException
140   {
141     if (seqs != null)
142     {
143       AlignmentI newAl = new Alignment(seqs);
144       if (stoLocation != null && al != null)
145       {
146         for (AlignmentAnnotation annot : al.getAlignmentAnnotation())
147         {
148           if (annot.label.contains("Reference") || "RF".equals(annot.label))
149           {
150             AlignmentAnnotation newRF;
151             if (annot.annotations.length > newAl.getWidth())
152             {
153               Annotation[] rfAnnots = new Annotation[newAl.getWidth()];
154               System.arraycopy(annot.annotations, 0, rfAnnots, 0,
155                       rfAnnots.length);
156               newRF = new AlignmentAnnotation("RF", "Reference Positions",
157                       rfAnnots);
158             }
159             else
160             {
161               newRF = new AlignmentAnnotation(annot);
162             }
163             newAl.addAnnotation(newRF);
164           }
165         }
166       }
167
168       StockholmFile file = new StockholmFile(newAl);
169       String output = file.print(seqs, false);
170       PrintWriter writer = new PrintWriter(stoLocation);
171       writer.println(output);
172       writer.close();
173     }
174
175     if (hmm != null)
176     {
177       HMMFile file = new HMMFile(hmm);
178       PrintWriter writer = new PrintWriter(hmmLocation);
179       writer.print(file.print());
180       writer.close();
181     }
182   }
183
184   /**
185    * Adds any HMM sequences removed before submitting the alignment as a job
186    * back into the alignment.
187    * 
188    * @param af
189    */
190   public void addHMMConsensusSequences(AlignFrame af)
191   {
192     AlignmentI al = af.getViewport().getAlignment();
193     if (hmmSeqs == null || hmmSeqs.size() < 1)
194     {
195       return;
196     }
197     for (SequenceI seq : hmmSeqs)
198     {
199       Integer position = seq.getPreviousPosition();
200       al.getSequences().add(position, seq);
201     }
202     af.getViewport().setAlignment(al);
203     af.alignPanel.adjustAnnotationHeight();
204     af.getViewport().updateSequenceIdColours();
205     af.buildSortByAnnotationScoresMenu();
206   }
207
208   /**
209    * Returns the list of HMM sequences removed
210    * 
211    * @return
212    */
213   public List<SequenceI> getHmmSeqs()
214   {
215     return hmmSeqs;
216   }
217
218   /**
219    * Sets the list of removed HMM sequences
220    * 
221    * @param hmmSeqs
222    */
223   public void setHmmSeqs(List<SequenceI> hmmSeqs)
224   {
225     this.hmmSeqs = hmmSeqs;
226   }
227
228   /**
229    * Answers the full path to the given hmmer executable, or null if file cannot
230    * be found or is not executable
231    * 
232    * @param cmd
233    *          command short name e.g. hmmalign
234    * @return
235    */
236   protected String getCommandRoot(String cmd)
237   {
238     String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH);
239     File file = getExecutable(cmd, binariesFolder);
240     if (file == null && af != null)
241     {
242         JvOptionPane.showInternalMessageDialog(af,
243                 MessageManager.getString("warn.hmm_command_failed"));
244     }
245
246     return file == null ? null : file.getAbsolutePath();
247   }
248
249   /**
250    * Answers the executable file for the given hmmer command, or null if not
251    * found or not executable. The path to the executable is the command name
252    * prefixed by the hmmer binaries folder path, optionally with .exe appended.
253    * 
254    * @param cmd
255    *          hmmer command short name, for example hmmbuild
256    * @param binaryPath
257    *          parent folder containing hmmer executables
258    * @return
259    */
260   public static File getExecutable(String cmd, String binaryPath)
261   {
262     File file = new File(binaryPath, cmd);
263     if (!file.canExecute())
264     {
265       file = new File(binaryPath, cmd + ".exe");
266       {
267         if (!file.canExecute())
268         {
269           file = null;
270         }
271       }
272     }
273     return file;
274   }
275 }