3 import jalview.bin.Cache;
4 import jalview.datamodel.Alignment;
5 import jalview.datamodel.AlignmentI;
6 import jalview.datamodel.AlignmentOrder;
7 import jalview.datamodel.AlignmentView;
8 import jalview.datamodel.HiddenColumns;
9 import jalview.datamodel.HiddenMarkovModel;
10 import jalview.datamodel.SequenceI;
11 import jalview.gui.AlignFrame;
12 import jalview.gui.Desktop;
13 import jalview.gui.JvOptionPane;
14 import jalview.gui.Preferences;
15 import jalview.gui.SplitFrame;
16 import jalview.io.DataSourceType;
17 import jalview.io.StockholmFile;
18 import jalview.util.MessageManager;
19 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.List;
27 import javax.swing.JInternalFrame;
28 import javax.swing.JOptionPane;
30 public class HMMAlignThread implements Runnable
34 * feature settings from view that job was associated with
36 protected FeatureRendererSettings featureSettings = null;
39 * Object containing frequently used commands.
41 HMMERCommands cmds = new HMMERCommands();
49 List<AlignmentOrder> orders;
53 HiddenMarkovModel hmm;
59 Map<Integer, SequenceI> hmmSeqs;
65 File inputTemp = null;
67 List<AlignmentOrder> allOrders;
69 SequenceI[][] allResults;
72 * Constructor for the HMMAlignThread. If create new frame is set to true, a
73 * new frame will be created.
76 * @param createNewFrame
78 public HMMAlignThread(AlignFrame af, boolean createNewFrame)
81 alignment = af.getViewport().getAlignment();
82 if (alignment.getDataset() != null)
84 dataset = alignment.getDataset();
86 newFrame = createNewFrame;
87 featureSettings = af.getFeatureRenderer().getSettings();
91 * Runs the HMMAlignThread: the data on the alignment or group is exported,
92 * then the command is executed in the command line and then the data is
93 * imported and displayed in a new frame (if true). The command is executed
94 * for each segemtn of the alignment.
99 if (af.getSelectedHMM() == null)
101 JOptionPane.showMessageDialog(af,
102 MessageManager.getString("warn.no_selected_hmm"));
107 hmm = af.getSelectedHMM();
109 barID = System.currentTimeMillis();
110 af.setProgressBar(MessageManager.getString("status.running_hmmalign"),
112 cmds.HMMERFOLDER = Cache.getProperty(Preferences.HMMER_PATH);
114 // if (!alignment.isAligned())
116 // alignment.padGaps();
119 SequenceI[][] subAlignments = msa.getVisibleContigs('-');
120 allOrders = new ArrayList<>();
121 allResults = new SequenceI[subAlignments.length][];
123 for (SequenceI[] seqs : subAlignments)
125 cmds.uniquifySequences(seqs);
128 createTemporaryFiles();
129 } catch (IOException e2)
131 e2.printStackTrace();
135 cmds.exportData(seqs, outTemp.getAbsoluteFile(), hmm,
136 hmmTemp.getAbsoluteFile());
137 } catch (IOException e1)
139 e1.printStackTrace();
143 boolean ran = runCommand();
146 JvOptionPane.showInternalMessageDialog(af,
147 MessageManager.getString("warn.hmmalign_failed"));
150 } catch (IOException | InterruptedException e)
157 } catch (IOException | InterruptedException e)
159 // TODO Auto-generated catch block
165 displayResults(newFrame);
167 af.setProgressBar(MessageManager.getString("status.running_hmmalign"),
173 * Creates temporary files for exporting and importing the data.
175 * @throws IOException
177 private void createTemporaryFiles() throws IOException
179 hmmTemp = File.createTempFile("hmm", ".hmm");
180 hmmTemp.deleteOnExit();
181 outTemp = File.createTempFile("output", ".sto");
182 outTemp.deleteOnExit();
183 inputTemp = File.createTempFile("input", ".sto");
184 inputTemp.deleteOnExit();
188 * Executes the hmmalign command in the command line.
191 * @throws IOException
192 * @throws InterruptedException
194 private boolean runCommand() throws IOException, InterruptedException
196 File file = new File(cmds.HMMERFOLDER + "/hmmalign");
197 if (!file.canExecute())
199 file = new File(cmds.HMMERFOLDER + "/hmmalign.exe");
201 if (!file.canExecute())
207 String command = cmds.HMMERFOLDER + cmds.HMMALIGN;
208 String version = Cache.getProperty("HMMER_VERSION");
209 if (!"3.1b2".equals(version))
211 command += cmds.ALLCOL;
214 String bool = Cache.getProperty("TRIM_TERMINI");
215 if ("false".equals(bool))
221 command += cmds.TRIM;
223 command += " -o " + inputTemp.getAbsolutePath() + cmds.SPACE
224 + hmmTemp.getAbsolutePath() + cmds.SPACE
225 + outTemp.getAbsolutePath();
226 return cmds.runCommand(command);
230 * Imports the data from the temporary file to which the output of hmmalign is
234 * The index of the 'job' (or region of an alignment).
235 * @throws IOException
236 * @throws InterruptedException
238 private void importData(int index)
239 throws IOException, InterruptedException
241 StockholmFile file = new StockholmFile(inputTemp.getAbsolutePath(),
242 DataSourceType.FILE);
243 SequenceI[] result = file.getSeqsAsArray();
244 AlignmentOrder msaorder = new AlignmentOrder(result);
245 jalview.analysis.AlignmentSorter.recoverOrder(result);
246 jalview.analysis.SeqsetUtils.deuniquify(cmds.hash, result);
247 allOrders.add(msaorder);
248 allResults[index] = result;
255 * Gathers the sequences in preparation for the alignment.
257 private void prepareAlignment()
259 // hmmSeqs = alignment.getHMMConsensusSequences(true);
260 msa = af.gatherSequencesForAlignment();
264 * Displays the results of all 'jobs'.
268 private void displayResults(boolean newFrame)
270 AlignmentOrder[] arrOrders = allOrders
271 .toArray(new AlignmentOrder[allOrders.size()]);
272 Object[] newview = msa.getUpdatedView(allResults,
274 SequenceI[] alignment = (SequenceI[]) newview[0];
275 HiddenColumns hidden = (HiddenColumns) newview[1];
276 Alignment al = new Alignment(alignment);
277 al.setProperty("Alignment Program", "hmmalign");
280 al.setDataset(dataset);
285 displayInNewFrame(al, allOrders, hidden);
290 * Displays the results in a new frame.
293 * The alignment containing the results.
295 * The order of the sequences in the alignment on which the jobs were
298 * Hidden columns in the previous alignment.
300 private void displayInNewFrame(AlignmentI al,
301 List<AlignmentOrder> alorders, HiddenColumns hidden)
303 AlignFrame af = new AlignFrame(al, hidden, AlignFrame.DEFAULT_WIDTH,
304 AlignFrame.DEFAULT_HEIGHT);
306 // initialise with same renderer settings as in parent alignframe.
307 af.getFeatureRenderer().transferSettings(this.featureSettings);
309 if (allOrders.size() > 0)
311 addSortByMenuItems(af, allOrders);
314 // TODO: refactor retrieve and show as new splitFrame as Desktop method
317 * If alignment was requested from one half of a SplitFrame, show in a
318 * SplitFrame with the other pane similarly aligned.
320 AlignFrame requestedBy = this.af;
321 if (requestedBy != null && requestedBy.getSplitViewContainer() != null
322 && requestedBy.getSplitViewContainer()
323 .getComplement(requestedBy) != null)
325 AlignmentI complement = requestedBy.getSplitViewContainer()
326 .getComplement(requestedBy);
327 String complementTitle = requestedBy.getSplitViewContainer()
328 .getComplementTitle(requestedBy);
329 // becomes null if the alignment window was closed before the alignment
331 AlignmentI copyComplement = new Alignment(complement);
332 // todo should this be done by copy constructor?
333 copyComplement.setGapCharacter(complement.getGapCharacter());
334 // share the same dataset (and the mappings it holds)
335 copyComplement.setDataset(complement.getDataset());
336 copyComplement.alignAs(al);
337 if (copyComplement.getHeight() > 0)
339 af.setTitle(this.af.getTitle());
340 AlignFrame af2 = new AlignFrame(copyComplement,
341 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
342 af2.setTitle(complementTitle);
343 String linkedTitle = MessageManager
344 .getString("label.linked_view_title");
345 JInternalFrame splitFrame = new SplitFrame(
346 al.isNucleotide() ? af : af2, al.isNucleotide() ? af2 : af);
347 Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
353 * Not from SplitFrame, or failed to created a complementary alignment
355 Desktop.addInternalFrame(af, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
356 AlignFrame.DEFAULT_HEIGHT);
360 * Add sort order options to the AlignFrame menus.
365 protected void addSortByMenuItems(AlignFrame af,
366 List<AlignmentOrder> alorders)
369 if (alorders.size() == 1)
371 af.addSortByOrderMenuItem("hmmalign" + " Ordering", alorders.get(0));
375 // construct a non-redundant ordering set
376 List<String> names = new ArrayList<>();
377 for (int i = 0, l = alorders.size(); i < l; i++)
379 String orderName = " Region " + i;
384 if (alorders.get(i).equals(alorders.get(j)))
388 orderName += "," + j;
396 if (i == 0 && j == 1)
402 names.add(orderName);
405 for (int i = 0, l = alorders.size(); i < l; i++)
407 af.addSortByOrderMenuItem("hmmalign" + (names.get(i)) + " Ordering",