4260c347b1b02ff294e4c4ef025c56e6bd98d1a9
[jalview.git] / src / jalview / hmmer / HMMBuildThread.java
1 package jalview.hmmer;
2
3
4 import jalview.bin.Cache;
5 import jalview.datamodel.AlignmentI;
6 import jalview.datamodel.Sequence;
7 import jalview.datamodel.SequenceGroup;
8 import jalview.datamodel.SequenceI;
9 import jalview.gui.AlignFrame;
10 import jalview.gui.AlignViewport;
11 import jalview.gui.JvOptionPane;
12 import jalview.gui.Preferences;
13 import jalview.io.DataSourceType;
14 import jalview.io.FileFormat;
15 import jalview.io.FileLoader;
16 import jalview.io.FileParse;
17 import jalview.io.HMMFile;
18 import jalview.util.MessageManager;
19 import jalview.ws.params.ArgumentI;
20
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.util.List;
25
26 import javax.swing.JOptionPane;
27
28 public class HMMBuildThread implements Runnable
29 {
30   HMMERCommands cmds = new HMMERCommands();
31   AlignFrame af;
32
33   AlignViewport viewport;
34   AlignmentI alignment;
35   SequenceGroup group;
36
37   List<ArgumentI> params;
38
39
40   boolean forGroup = false;
41
42   File hmmTemp = null;
43
44   File stoTemp = null;
45
46   long barID;
47   
48   /**
49    * This is used for validation purposes. Do not use!
50    * 
51    * @param viewport
52    */
53   public HMMBuildThread(AlignmentI alignment)
54   {
55     this.alignment = alignment;
56     forGroup = false;
57   }
58
59   public HMMBuildThread(AlignFrame af, List<ArgumentI> args)
60   {
61     this.af = af;
62     if (af.getViewport().getSelectionGroup() != null)
63     {
64       group = af.getViewport().getSelectionGroup();
65       forGroup = true;
66     }
67     viewport = af.getViewport();
68     alignment = viewport.getAlignment();
69     params = args;
70
71   }
72
73   /**
74    * Builds a HMM from an alignment, then imports and adds it to the alignment.
75    */
76   @Override
77   public void run()
78   {
79     barID = System.currentTimeMillis();
80     if (af != null)
81     {
82     af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
83             barID);
84     }
85     cmds.HMMERFOLDER = Cache.getProperty(Preferences.HMMER_PATH);
86     if (alignment == null && group == null)
87     {
88       JOptionPane.showMessageDialog(af,
89               MessageManager.getString("warn.no_sequence_data"));
90       return;
91     }
92     try
93     {
94       hmmTemp = File.createTempFile("hmm", ".hmm");
95       hmmTemp.deleteOnExit();
96       stoTemp = File.createTempFile("output", ".sto");
97       stoTemp.deleteOnExit();
98     } catch (IOException e1)
99     {
100       e1.printStackTrace();
101     }
102
103     try
104     {
105     try
106     {
107         SequenceI[] array;
108         List<SequenceI> seqs = alignment
109                 .getHMMConsensusSequences(true);
110         cmds.setHmmSeqs(seqs);
111         if (forGroup)
112         {
113           array = group.getSelectionAsNewSequences(alignment);
114         }
115         else
116         {
117           if (!alignment.isAligned())
118           {
119             alignment.padGaps();
120           }
121           array = alignment.getSequencesArray();
122         }
123         if (array.length < 1)
124         {
125           if (af != null)
126           {
127             JOptionPane.showMessageDialog(af,
128                   MessageManager.getString("warn.no_sequence_data"));
129           }
130           return;
131         }
132         SequenceI[] newArr = new SequenceI[array.length];
133         int index = 0;
134         for (SequenceI seq : array)
135         {
136           newArr[index] = new Sequence(seq);
137           index++;
138         }
139
140         cmds.uniquifySequences(newArr);
141         cmds.exportData(newArr, stoTemp, null, null);
142         jalview.analysis.SeqsetUtils.deuniquify(cmds.hash, array);
143
144     } catch (FileNotFoundException e)
145     {
146       // TODO Auto-generated catch block
147       e.printStackTrace();
148
149     }
150     try
151     {
152         boolean ran = runCommand();
153         if (!ran)
154         {
155           return;
156         }
157     } catch (IOException | InterruptedException e)
158     {
159       // TODO Auto-generated catch block
160       e.printStackTrace();
161     }
162     try
163     {
164
165       importData();
166     } catch (IOException | InterruptedException e)
167     {
168       // TODO Auto-generated catch block
169       e.printStackTrace();
170     }
171     } catch (Exception e)
172     {
173       e.printStackTrace();
174     } finally
175     {
176       if (af != null)
177       {
178         af.setProgressBar(
179                 MessageManager.getString("status.running_hmmbuild"),
180               barID);
181       }
182     }
183   }
184
185   
186
187   /**
188    * Executes the hmmbuild command in the command line.
189    * 
190    * @return
191    * @throws IOException
192    * @throws InterruptedException
193    */
194   private boolean runCommand() throws IOException, InterruptedException
195   {
196     File file = new File(cmds.HMMERFOLDER + "/hmmbuild");
197     if (!file.canExecute())
198     {
199       file = new File(cmds.HMMERFOLDER + "/hmmbuild.exe");
200       {
201         if (!file.canExecute())
202         {
203           if (af != null)
204           {
205             JvOptionPane.showInternalMessageDialog(af,
206                     MessageManager.getString("warn.hmmbuild_failed"));
207           }
208           return false;
209         }
210       }
211     }
212     String command = cmds.HMMERFOLDER + cmds.HMMBUILD + cmds.SPACE;
213     String name = null;
214
215     if (params != null)
216     {
217       for (ArgumentI arg : params)
218       {
219         String argName = arg.getName();
220         switch (argName)
221         {
222         case "HMM Name":
223           name = arg.getValue();
224           break;
225         case "Use Reference Annotation":
226           command += "--hand ";
227           if (!af.getViewport().hasReferenceAnnotation())
228           {
229             JvOptionPane.showInternalMessageDialog(af, MessageManager
230                     .getString("warn.no_reference_annotation"));
231             return false;
232           }
233           break;
234
235         }
236
237       }
238     }
239
240     if (name == null || name == "" || name == " ")
241     {
242       if (forGroup)
243       {
244         name = group.getName();
245       }
246       else
247       {
248         if (af != null)
249         {
250           name = af.getTitle();
251         }
252         if (name == null || name == "" || name == " " || name == "  ")
253         {
254           name = "Alignment";
255         }
256       }
257     }
258
259     command += "-n " + name + cmds.SPACE;
260     if (!alignment.isNucleotide())
261     {
262       command += cmds.FORCEAMINO; // TODO check for rna
263     }
264     else
265     {
266       command += cmds.FORCEDNA;
267     }
268
269     command += hmmTemp.getAbsolutePath()
270             + cmds.SPACE + stoTemp.getAbsolutePath() + cmds.SPACE;
271     return cmds.runCommand(command);
272   }
273   
274   /**
275    * Imports the .hmm file produced by hmmbuild.
276    * 
277    * @throws IOException
278    * @throws InterruptedException
279    */
280   private void importData() throws IOException, InterruptedException
281   {
282     if (af != null)
283     {
284       cmds.addHMMConsensusSequences(af);
285
286       FileLoader loader = new FileLoader();
287       loader.LoadFileOntoAlignmentWaitTillLoaded(viewport,
288               hmmTemp.getAbsolutePath(), DataSourceType.FILE,
289               FileFormat.HMMER3);
290     }
291     else
292     {
293       HMMFile file = new HMMFile(new FileParse(hmmTemp.getAbsolutePath(),
294               DataSourceType.FILE));
295       alignment.addSequence(file.getSeqsAsArray()[0]);
296     }
297     hmmTemp.delete();
298     stoTemp.delete();
299   }
300   
301   /**
302    * Runs hmmbuild, and waits for the results to be imported before continuing
303    */
304   public void hmmbuildWaitTillComplete()
305   {
306     Thread loader = new Thread(this);
307     loader.start();
308
309     while (loader.isAlive())
310     {
311       try
312       {
313         Thread.sleep(500);
314       } catch (Exception ex)
315       {
316       }
317     }
318   }
319 }