3 import jalview.analysis.AlignmentSorter;
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.SplitFrame;
15 import jalview.io.DataSourceType;
16 import jalview.io.StockholmFile;
17 import jalview.util.MessageManager;
18 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
19 import jalview.ws.params.ArgumentI;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.List;
26 import javax.swing.JInternalFrame;
28 public class HMMAlignThread extends HmmerCommand implements Runnable
30 static final String HMMALIGN = "hmmalign";
32 static final String ARG_TRIM = "--trim";
35 * feature settings from view that job was associated with
37 protected FeatureRendererSettings featureSettings = null;
43 List<AlignmentOrder> orders;
47 HiddenMarkovModel hmm;
49 SequenceI[][] allResults;
52 * Constructor for the HMMAlignThread
57 public HMMAlignThread(AlignFrame af, List<ArgumentI> args)
60 alignment = af.getViewport().getAlignment();
61 if (alignment.getDataset() != null)
63 dataset = alignment.getDataset();
65 featureSettings = af.getFeatureRenderer().getSettings();
69 * Runs the HMMAlignThread: the data on the alignment or group is exported,
70 * then the command is executed in the command line and then the data is
71 * imported and displayed in a new frame (if true). The command is executed
72 * for each segemtn of the alignment.
77 hmm = af.getSelectedHMM();
80 System.err.println("Can't run hmmalign as no HMM profile selected");
84 long msgId = System.currentTimeMillis();
85 af.setProgressBar(MessageManager.getString("status.running_hmmalign"),
88 SequenceI[][] subAlignments = msa.getVisibleContigs('-');
90 List<AlignmentOrder> allOrders = new ArrayList<>();
91 allResults = new SequenceI[subAlignments.length][];
93 for (SequenceI[] seqs : subAlignments)
98 File modelFile = createTempFile("hmm", ".hmm");
99 File alignmentFile = createTempFile("output", ".sto");
100 File resultFile = createTempFile("input", ".sto");
102 exportStockholm(seqs, alignmentFile.getAbsoluteFile(), null);
103 exportHmm(hmm, modelFile.getAbsoluteFile());
105 boolean ran = runCommand(modelFile, alignmentFile, resultFile);
108 JvOptionPane.showInternalMessageDialog(af,
109 MessageManager.getString("warn.hmmalign_failed"));
113 SequenceI[] result = importData(resultFile, allOrders);
114 allResults[job] = result;
116 alignmentFile.delete();
118 } catch (IOException e)
125 displayResults(allOrders);
127 af.setProgressBar("", msgId);
131 * Executes the hmmalign command and returns true if successful, false if an
135 * the HMM to align to
136 * @param alignmentFile
137 * the sequences to align
139 * the file to hold the results of alignment
141 * @throws IOException
143 private boolean runCommand(File modelFile, File alignmentFile,
147 String command = getCommandPath(HMMALIGN);
152 List<String> args = new ArrayList<>();
157 for (ArgumentI arg : params)
159 String name = arg.getName();
160 if (MessageManager.getString("label.trim_termini").equals(name))
167 args.add(resultFile.getAbsolutePath());
168 args.add(modelFile.getAbsolutePath());
169 args.add(alignmentFile.getAbsolutePath());
171 return runCommand(args);
175 * Imports the data from the file holding the output of hmmalign
179 * a list of alignment orders to add to
182 * @throws IOException
184 private SequenceI[] importData(File resultFile,
185 List<AlignmentOrder> allOrders) throws IOException
187 StockholmFile file = new StockholmFile(resultFile.getAbsolutePath(),
188 DataSourceType.FILE);
189 SequenceI[] result = file.getSeqsAsArray();
190 AlignmentOrder msaorder = new AlignmentOrder(result);
191 AlignmentSorter.recoverOrder(result);
192 recoverSequences(result);
193 allOrders.add(msaorder);
199 * Gathers the sequences in preparation for the alignment.
201 private void prepareAlignment()
203 msa = af.gatherSequencesForAlignment();
207 * Displays the results of all 'jobs' in a new frame
211 private void displayResults(List<AlignmentOrder> allOrders)
213 AlignmentOrder[] arrOrders = allOrders
214 .toArray(new AlignmentOrder[allOrders.size()]);
215 Object[] newview = msa.getUpdatedView(allResults, arrOrders, '-');
216 SequenceI[] seqs = (SequenceI[]) newview[0];
217 HiddenColumns hidden = (HiddenColumns) newview[1];
218 Alignment al = new Alignment(seqs);
219 al.setProperty("Alignment Program", "hmmalign");
222 al.setDataset(dataset);
225 displayInNewFrame(al, allOrders, hidden);
229 * Displays the results in a new frame
232 * The alignment containing the results
234 * The order of the sequences in the alignment on which the jobs were
237 * Hidden columns in the previous alignment
239 private void displayInNewFrame(AlignmentI al,
240 List<AlignmentOrder> alorders, HiddenColumns hidden)
242 AlignFrame alignFrame = new AlignFrame(al, hidden, AlignFrame.DEFAULT_WIDTH,
243 AlignFrame.DEFAULT_HEIGHT);
245 // initialise with same renderer settings as in parent alignframe.
246 alignFrame.getFeatureRenderer().transferSettings(this.featureSettings);
248 addSortByMenuItems(alignFrame, alorders);
250 // TODO: refactor retrieve and show as new splitFrame as Desktop method
253 * If alignment was requested from one half of a SplitFrame, show in a
254 * SplitFrame with the other pane similarly aligned.
256 AlignFrame requestedBy = this.af;
257 if (requestedBy != null && requestedBy.getSplitViewContainer() != null
258 && requestedBy.getSplitViewContainer()
259 .getComplement(requestedBy) != null)
261 AlignmentI complement = requestedBy.getSplitViewContainer()
262 .getComplement(requestedBy);
263 String complementTitle = requestedBy.getSplitViewContainer()
264 .getComplementTitle(requestedBy);
265 // becomes null if the alignment window was closed before the alignment
267 AlignmentI copyComplement = new Alignment(complement);
268 // todo should this be done by copy constructor?
269 copyComplement.setGapCharacter(complement.getGapCharacter());
270 // share the same dataset (and the mappings it holds)
271 copyComplement.setDataset(complement.getDataset());
272 copyComplement.alignAs(al);
273 if (copyComplement.getHeight() > 0)
275 alignFrame.setTitle(this.af.getTitle());
276 AlignFrame af2 = new AlignFrame(copyComplement,
277 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
278 af2.setTitle(complementTitle);
279 String linkedTitle = MessageManager
280 .getString("label.linked_view_title");
281 JInternalFrame splitFrame = new SplitFrame(
282 al.isNucleotide() ? alignFrame : af2, al.isNucleotide() ? af2 : alignFrame);
283 Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
289 * Not from SplitFrame, or failed to created a complementary alignment
291 Desktop.addInternalFrame(alignFrame, alignFrame.getTitle(), AlignFrame.DEFAULT_WIDTH,
292 AlignFrame.DEFAULT_HEIGHT);
296 * Adds sort order options to the AlignFrame menus
301 protected void addSortByMenuItems(AlignFrame alignFrame,
302 List<AlignmentOrder> alorders)
305 if (alorders.size() == 1)
307 alignFrame.addSortByOrderMenuItem("hmmalign" + " Ordering", alorders.get(0));
311 // construct a non-redundant ordering set
312 List<String> names = new ArrayList<>();
313 for (int i = 0, l = alorders.size(); i < l; i++)
315 String orderName = " Region " + i;
320 if (alorders.get(i).equals(alorders.get(j)))
324 orderName += "," + j;
332 if (i == 0 && j == 1)
338 names.add(orderName);
341 for (int i = 0, l = alorders.size(); i < l; i++)
343 alignFrame.addSortByOrderMenuItem("hmmalign" + (names.get(i)) + " Ordering",
350 * Runs hmmalign, and waits for the results to be imported before continuing
352 public void hmmalignWaitTillComplete()
354 Thread loader = new Thread(this);
357 while (loader.isAlive())
362 } catch (Exception ex)