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;
38 HMMERCommands cmds = new HMMERCommands();
46 List<AlignmentOrder> orders;
50 HiddenMarkovModel hmm;
56 Map<Integer, SequenceI> hmmSeqs;
62 File inputTemp = null;
64 List<AlignmentOrder> allOrders;
66 SequenceI[][] allResults;
68 public HMMAlignThread(AlignFrame af, boolean createNewFrame)
71 alignment = af.getViewport().getAlignment();
72 if (alignment.getDataset() != null)
74 dataset = alignment.getDataset();
76 newFrame = createNewFrame;
77 featureSettings = af.getFeatureRenderer().getSettings();
83 if (af.getViewport().getSelectedHMM() == null)
85 JOptionPane.showMessageDialog(af,
86 MessageManager.getString("warn.no_selected_hmm"));
91 hmm = af.getViewport().getSelectedHMM();
93 barID = System.currentTimeMillis();
94 af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
96 cmds.HMMERFOLDER = Cache.getProperty(Preferences.HMMER_PATH);
98 // if (!alignment.isAligned())
100 // alignment.padGaps();
103 SequenceI[][] subAlignments = msa.getVisibleContigs('-');
104 allOrders = new ArrayList<>();
105 allResults = new SequenceI[subAlignments.length][];
107 for (SequenceI[] seqs : subAlignments)
109 cmds.uniquifySequences(seqs);
112 createTemporaryFiles();
113 } catch (IOException e2)
115 e2.printStackTrace();
119 cmds.exportData(seqs, outTemp.getAbsoluteFile(), hmm,
120 hmmTemp.getAbsoluteFile());
121 } catch (IOException e1)
123 e1.printStackTrace();
127 boolean ran = runCommand();
130 JvOptionPane.showInternalMessageDialog(af,
131 MessageManager.getString("warn.hmmalign_failed"));
134 } catch (IOException | InterruptedException e)
141 } catch (IOException | InterruptedException e)
143 // TODO Auto-generated catch block
149 displayResults(newFrame);
151 af.setProgressBar(MessageManager.getString("status.running_hmmalign"),
156 private void createTemporaryFiles() throws IOException
158 hmmTemp = File.createTempFile("hmm", ".hmm");
159 hmmTemp.deleteOnExit();
160 outTemp = File.createTempFile("output", ".sto");
161 outTemp.deleteOnExit();
162 inputTemp = File.createTempFile("input", ".sto");
163 inputTemp.deleteOnExit();
166 private boolean runCommand() throws IOException, InterruptedException
168 File file = new File(cmds.HMMERFOLDER + "/binaries/hmmalign.exe");
169 if (!file.canExecute())
173 String command = cmds.HMMERFOLDER + cmds.HMMALIGN;
174 if (!hmm.getFileHeader().contains("HMMER3/f"))
176 command += cmds.ALLCOL;
179 String bool = Cache.getProperty("TRIM_TERMINI");
180 if ("false".equals(bool))
186 command += cmds.TRIM;
188 command += " -o" + inputTemp.getAbsolutePath() + cmds.SPACE
189 + hmmTemp.getAbsolutePath() + cmds.SPACE
190 + outTemp.getAbsolutePath();
191 return cmds.runCommand(command);
194 private void importData(int index)
195 throws IOException, InterruptedException
197 StockholmFile file = new StockholmFile(inputTemp.getAbsolutePath(),
198 DataSourceType.FILE);
199 SequenceI[] result = file.getSeqsAsArray();
200 AlignmentOrder msaorder = new AlignmentOrder(result);
201 // always recover the order - makes parseResult()'s life easier.
202 jalview.analysis.AlignmentSorter.recoverOrder(result);
203 jalview.analysis.SeqsetUtils.deuniquify(cmds.hash, result);
204 allOrders.add(msaorder);
205 allResults[index] = result;
210 FileLoader loader = new FileLoader();
211 AlignFrame aFrame = new AlignFrame(new Alignment(new SequenceI[1]),
212 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
213 Desktop.addInternalFrame(aFrame, aFrame.getTitle(),
214 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
216 af.getName() + "Aligned to " + hmm.getName() + "'s HMM");
217 af.getViewport().setAlignment(null);
219 aFrame.loadJalviewDataFile(inputTemp.getAbsolutePath(),
220 DataSourceType.FILE, FileFormat.Stockholm, null);
224 Map<Integer, SequenceI> copy = new HashMap<>(
226 addSeqs(aFrame, copy);
227 SequenceI seq = aFrame.getViewport().getAlignment()
229 seq.getHMM().mapToReferenceAnnotation(aFrame, seq);
230 addSeqs(af, hmmSeqs);
234 af.getViewport().getAlignment().getSequences().clear();
235 af.setIsRecurring(true);
236 af.loadJalviewDataFile(inputTemp.getAbsolutePath(),
237 DataSourceType.FILE, FileFormat.Stockholm, null);
238 af.setIsRecurring(false);
239 addSeqs(af, hmmSeqs);
247 private void prepareAlignment()
249 // hmmSeqs = alignment.getHMMConsensusSequences(true);
250 msa = af.gatherSequencesForAlignment();
253 private void displayResults(boolean newFrame)
255 AlignmentOrder[] arrOrders = allOrders
256 .toArray(new AlignmentOrder[allOrders.size()]);
257 Object[] newview = msa.getUpdatedView(allResults,
259 SequenceI[] alignment = (SequenceI[]) newview[0];
260 HiddenColumns hidden = (HiddenColumns) newview[1];
261 Alignment al = new Alignment(alignment);
262 al.setProperty("Alignment Program", "hmmalign");
265 al.setDataset(dataset);
270 displayInNewFrame(al, allOrders, hidden);
274 private void displayInNewFrame(AlignmentI al,
275 List<AlignmentOrder> alorders, HiddenColumns hidden)
277 AlignFrame af = new AlignFrame(al, hidden, AlignFrame.DEFAULT_WIDTH,
278 AlignFrame.DEFAULT_HEIGHT);
280 // initialise with same renderer settings as in parent alignframe.
281 af.getFeatureRenderer().transferSettings(this.featureSettings);
283 if (allOrders.size() > 0)
285 addSortByMenuItems(af, allOrders);
288 // TODO: refactor retrieve and show as new splitFrame as Desktop method
291 * If alignment was requested from one half of a SplitFrame, show in a
292 * SplitFrame with the other pane similarly aligned.
294 AlignFrame requestedBy = this.af;
295 if (requestedBy != null && requestedBy.getSplitViewContainer() != null
296 && requestedBy.getSplitViewContainer()
297 .getComplement(requestedBy) != null)
299 AlignmentI complement = requestedBy.getSplitViewContainer()
300 .getComplement(requestedBy);
301 String complementTitle = requestedBy.getSplitViewContainer()
302 .getComplementTitle(requestedBy);
303 // becomes null if the alignment window was closed before the alignment
305 AlignmentI copyComplement = new Alignment(complement);
306 // todo should this be done by copy constructor?
307 copyComplement.setGapCharacter(complement.getGapCharacter());
308 // share the same dataset (and the mappings it holds)
309 copyComplement.setDataset(complement.getDataset());
310 copyComplement.alignAs(al);
311 if (copyComplement.getHeight() > 0)
313 af.setTitle(this.af.getTitle());
314 AlignFrame af2 = new AlignFrame(copyComplement,
315 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
316 af2.setTitle(complementTitle);
317 String linkedTitle = MessageManager
318 .getString("label.linked_view_title");
319 JInternalFrame splitFrame = new SplitFrame(
320 al.isNucleotide() ? af : af2, al.isNucleotide() ? af2 : af);
321 Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
327 * Not from SplitFrame, or failed to created a complementary alignment
329 Desktop.addInternalFrame(af, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
330 AlignFrame.DEFAULT_HEIGHT);
334 * Add sort order options to the AlignFrame menus.
339 protected void addSortByMenuItems(AlignFrame af,
340 List<AlignmentOrder> alorders)
343 if (alorders.size() == 1)
345 af.addSortByOrderMenuItem("hmmalign" + " Ordering", alorders.get(0));
349 // construct a non-redundant ordering set
350 List<String> names = new ArrayList<>();
351 for (int i = 0, l = alorders.size(); i < l; i++)
353 String orderName = " Region " + i;
358 if (alorders.get(i).equals(alorders.get(j)))
362 orderName += "," + j;
370 if (i == 0 && j == 1)
376 names.add(orderName);
379 for (int i = 0, l = alorders.size(); i < l; i++)
381 af.addSortByOrderMenuItem("hmmalign" + (names.get(i)) + " Ordering",