JAL-2629 add basic parameter adjustment to hmmsearch/align
[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           if (af != null)
156           {
157             JvOptionPane.showInternalMessageDialog(af,
158                   MessageManager.getString("warn.hmmbuild_failed"));
159           }
160           return;
161         }
162     } catch (IOException | InterruptedException e)
163     {
164       // TODO Auto-generated catch block
165       e.printStackTrace();
166     }
167     try
168     {
169
170       importData();
171     } catch (IOException | InterruptedException e)
172     {
173       // TODO Auto-generated catch block
174       e.printStackTrace();
175     }
176     } catch (Exception e)
177     {
178       e.printStackTrace();
179     } finally
180     {
181       if (af != null)
182       {
183         af.setProgressBar(
184                 MessageManager.getString("status.running_hmmbuild"),
185               barID);
186       }
187     }
188   }
189
190   
191
192   /**
193    * Executes the hmmbuild command in the command line.
194    * 
195    * @return
196    * @throws IOException
197    * @throws InterruptedException
198    */
199   private boolean runCommand() throws IOException, InterruptedException
200   {
201     File file = new File(cmds.HMMERFOLDER + "/hmmbuild");
202     if (!file.canExecute())
203     {
204       file = new File(cmds.HMMERFOLDER + "/hmmbuild.exe");
205       {
206         if (!file.canExecute())
207         {
208           return false;
209         }
210       }
211     }
212     String command = cmds.HMMERFOLDER + cmds.HMMBUILD + cmds.NAME;
213     if (forGroup)
214     {
215       command += group.getName();
216     }
217     else
218     {
219       String name = null;
220       if (af != null)
221       {
222         // name = af.getTitle();
223         name = "replace";
224       }
225       if (name == null || name == "" || name == " " || name == "  ")
226       {
227         name = "Alignment";
228       }
229       command += name;
230     }
231     command += cmds.SPACE;
232     if (!alignment.isNucleotide())
233     {
234       command += cmds.FORCEAMINO; // TODO check for rna
235     }
236     else
237     {
238       command += cmds.FORCEDNA;
239     }
240
241     command += hmmTemp.getAbsolutePath()
242             + cmds.SPACE + stoTemp.getAbsolutePath() + cmds.SPACE;
243     return cmds.runCommand(command);
244   }
245   
246   /**
247    * Imports the .hmm file produced by hmmbuild.
248    * 
249    * @throws IOException
250    * @throws InterruptedException
251    */
252   private void importData() throws IOException, InterruptedException
253   {
254     if (af != null)
255     {
256       cmds.addHMMConsensusSequences(af);
257
258       FileLoader loader = new FileLoader();
259       loader.LoadFileOntoAlignmentWaitTillLoaded(viewport,
260               hmmTemp.getAbsolutePath(), DataSourceType.FILE,
261               FileFormat.HMMER3);
262     }
263     else
264     {
265       HMMFile file = new HMMFile(new FileParse(hmmTemp.getAbsolutePath(),
266               DataSourceType.FILE));
267       alignment.addSequence(file.getSeqsAsArray()[0]);
268     }
269     hmmTemp.delete();
270     stoTemp.delete();
271   }
272   
273   /**
274    * Runs hmmbuild, and waits for the results to be imported before continuing
275    */
276   public void hmmbuildWaitTillComplete()
277   {
278     Thread loader = new Thread(this);
279     loader.start();
280
281     while (loader.isAlive())
282     {
283       try
284       {
285         Thread.sleep(500);
286       } catch (Exception ex)
287       {
288       }
289     }
290   }
291 }