3 import jalview.api.AlignViewportI;
4 import jalview.datamodel.Alignment;
5 import jalview.datamodel.AlignmentAnnotation;
6 import jalview.datamodel.AlignmentI;
7 import jalview.datamodel.AnnotatedCollectionI;
8 import jalview.datamodel.Sequence;
9 import jalview.datamodel.SequenceGroup;
10 import jalview.datamodel.SequenceI;
11 import jalview.gui.AlignFrame;
12 import jalview.gui.AlignViewport;
13 import jalview.gui.AlignmentPanel;
14 import jalview.gui.JvOptionPane;
15 import jalview.io.DataSourceType;
16 import jalview.io.FileParse;
17 import jalview.io.HMMFile;
18 import jalview.util.MessageManager;
19 import jalview.workers.InformationThread;
20 import jalview.ws.params.ArgumentI;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
27 import javax.swing.JOptionPane;
29 public class HMMBuildThread extends HmmerCommand implements Runnable
31 static final String ARG_AMINO = "--amino";
33 static final String ARG_DNA = "--dna";
35 static final String ARG_RNA = "--rna";
45 public HMMBuildThread(AlignFrame alignFrame, List<ArgumentI> args)
47 super(alignFrame, args);
51 * Builds a HMM from an alignment (and/or groups), then imports and adds it to
52 * the alignment (and/or groups)
57 long msgID = System.currentTimeMillis();
60 af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
64 AlignViewportI viewport = af.getViewport();
69 alignment = viewport.getAlignment();
71 List<SequenceGroup> groups = new ArrayList<>();
74 for (ArgumentI arg : params)
76 String name = arg.getName();
77 if (MessageManager.getString("label.hmmbuild_for").equals(name))
79 String value = arg.getValue();
80 if (MessageManager.getString("label.alignment").equals(value))
82 alignment = viewport.getAlignment();
84 else if (MessageManager.getString("label.groups_and_alignment")
87 alignment = viewport.getAlignment();
88 groups.addAll(viewport.getAlignment().getGroups());
90 else if (MessageManager.getString("label.groups").equals(value))
93 groups = viewport.getAlignment().getGroups();
95 else if ("label.selected_group".equals(value))
98 groups.add(viewport.getSelectionGroup());
101 else if (MessageManager.getString("label.use_reference")
104 // todo disable this option if no RF annotation on alignment
105 if (!af.getViewport().hasReferenceAnnotation())
107 JvOptionPane.showInternalMessageDialog(af, MessageManager
108 .getString("warn.no_reference_annotation"));
115 if (alignment != null)
117 // alignment.findOrCreateAnnotation("", HMMBUILD, autoCalc, seqRef,
119 runHMMBuild(alignment);
122 if (alignment == null)
124 alignment = viewport.getAlignment();
127 for (AnnotatedCollectionI grp : groups)
135 viewport.updateInformation(af.alignPanel);
136 af.buildColourMenu(); // enable HMMER colour schemes
137 af.setProgressBar("", msgID);
143 * Runs hmmbuild on the alignment, or on the group if one is specified
147 private void runHMMBuild(AnnotatedCollectionI ac)
151 JOptionPane.showMessageDialog(af,
152 MessageManager.getString("warn.no_sequence_data"));
155 File alignmentFile = null;
158 hmmFile = createTempFile("hmm", ".hmm");
159 alignmentFile = createTempFile("output", ".sto");
161 List<SequenceI> hmmSeqs = null;
162 hmmSeqs = ac.getHMMConsensusSequences();
163 if (ac instanceof SequenceGroup)
165 array = ((SequenceGroup) ac)
166 .getSelectionAsNewSequences(alignment);
170 AlignmentI al = (Alignment) ac;
171 // todo pad gaps in an unaligned SequenceGroup as well?
176 array = al.getSequencesArray();
179 if (array.length < 1)
183 JOptionPane.showMessageDialog(af,
184 MessageManager.getString("warn.no_sequence_data"));
190 * copy over sequences, excluding hmm consensus sequences
191 * hmm sequences and their Information annotation are also deleted
192 * in preparation for re-adding them when recalculated
194 SequenceI[] newArr = new SequenceI[array.length - hmmSeqs.size()];
196 for (SequenceI seq : array)
198 if (seq.isHMMConsensusSequence())
200 AlignmentAnnotation[] seqAnnotations = seq
202 if (seqAnnotations != null)
204 for (AlignmentAnnotation ann : seqAnnotations)
206 if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
208 alignment.deleteAnnotation(ann);
212 alignment.deleteSequence(seq);
216 newArr[index] = new Sequence(seq);
221 stashSequences(newArr);
223 exportStockholm(newArr, alignmentFile,
224 ac != null ? ac : alignment);
226 recoverSequences(array);
228 boolean ran = runCommand(alignmentFile, hmmFile, ac);
233 importData(hmmFile, ac);
234 } catch (Exception e)
243 if (alignmentFile != null)
245 alignmentFile.delete();
251 * Constructs and executes the hmmbuild command as a separate process
253 * @param sequencesFile
254 * the alignment from which the HMM is built
256 * the output file to which the HMM is written
258 * alignment or group for which the hmm is generated
261 * @throws IOException
263 private boolean runCommand(File sequencesFile, File hmmFile,
264 AnnotatedCollectionI group) throws IOException
266 String cmd = getCommandPath(HMMBUILD);
269 return false; // executable not found
271 List<String> args = new ArrayList<>();
275 * HMM name (will be given to consensus sequence) is
276 * - as specified by an input parameter if set
277 * - else group name with _HMM appended (if for a group)
278 * - else align fame title with _HMM appended (if title is not too long)
279 * - else "Alignment_HMM"
285 for (ArgumentI arg : params)
287 String argName = arg.getName();
291 name = arg.getValue().trim();
293 case "Use Reference Annotation":
300 if (group instanceof SequenceGroup)
302 name = ((SequenceGroup) group).getName() + "_HMM";
307 if (af != null && af.getTitle().length() < 15)
309 name = af.getTitle();
313 name = "Alignment_HMM";
318 args.add(name.replace(' ', '_'));
319 if (!alignment.isNucleotide())
321 args.add(ARG_AMINO); // TODO check for rna
328 args.add(hmmFile.getAbsolutePath());
329 args.add(sequencesFile.getAbsolutePath());
331 return runCommand(args);
335 * Imports the .hmm file produced by hmmbuild, and inserts the HMM consensus
336 * sequence (with attached HMM profile) as the first sequence in the alignment
337 * or group for which it was generated
341 * (optional) the group for which the hmm was generated
342 * @throws IOException
344 private void importData(File hmmFile, AnnotatedCollectionI ac)
347 HMMFile file = new HMMFile(
348 new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
349 SequenceI[] seqs = file.getSeqsAsArray();
350 SequenceI seq = seqs[0];
351 seq.createDatasetSequence();
352 if (ac instanceof SequenceGroup)
354 SequenceGroup grp = (SequenceGroup) ac;
355 seq.insertCharAt(0, ac.getStartRes(), '-');
356 seq.insertCharAt(ac.getEndRes() + 1,
357 alignment.getWidth() - ac.getEndRes() - 1, '-');
358 seq.updateHMMMapping();
359 SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
360 int topIndex = alignment.findIndex(topSeq);
361 alignment.insertSequenceAt(topIndex, seq);
363 grp.addSequence(seq, false);
367 alignment.insertSequenceAt(0, seq);
370 AlignViewport viewport = af.getViewport();
371 if (viewport != null)
373 AlignmentPanel alignPanel = viewport.getAlignPanel();
374 viewport.alignmentChanged(alignPanel);
375 alignPanel.adjustAnnotationHeight();
376 viewport.updateSequenceIdColours();
378 if (alignPanel.alignFrame.getSelectedHMM() == null)
380 alignPanel.alignFrame.setSelectedHMMSequence(seq);
386 * Runs hmmbuild, and waits for the results to be imported before continuing
388 public void hmmbuildWaitTillComplete()
390 Thread loader = new Thread(this);
393 while (loader.isAlive())
398 } catch (Exception ex)