3 import jalview.api.AlignViewportI;
4 import jalview.bin.Cache;
5 import jalview.datamodel.Alignment;
6 import jalview.datamodel.AlignmentI;
7 import jalview.datamodel.AnnotatedCollectionI;
8 import jalview.datamodel.SequenceGroup;
9 import jalview.datamodel.SequenceI;
10 import jalview.gui.AlignFrame;
11 import jalview.gui.AlignViewport;
12 import jalview.gui.AlignmentPanel;
13 import jalview.gui.JvOptionPane;
14 import jalview.io.DataSourceType;
15 import jalview.io.FileParse;
16 import jalview.io.HMMFile;
17 import jalview.util.MessageManager;
18 import jalview.ws.params.ArgumentI;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Hashtable;
24 import java.util.Iterator;
25 import java.util.List;
28 * A class that runs the hmmbuild command as a separate process.
33 public class HMMBuild extends HmmerCommand
35 static final String ARG_AMINO = "--amino";
37 static final String ARG_DNA = "--dna";
39 static final String ARG_RNA = "--rna";
47 public HMMBuild(AlignFrame alignFrame, List<ArgumentI> args)
49 super(alignFrame, args);
53 * Builds a HMM from an alignment (and/or groups), then imports and adds it to
54 * the alignment (and/or groups). Call this method directly to execute
55 * synchronously, or via start() in a new Thread for asynchronously.
62 Cache.log.error("No parameters to HMMBuild!|");
66 long msgID = System.currentTimeMillis();
67 af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
70 AlignViewportI viewport = af.getViewport();
74 * run hmmbuild for alignment and/or groups as selected
76 List<AnnotatedCollectionI> runBuildFor = parseParameters(viewport);
78 for (AnnotatedCollectionI grp : runBuildFor)
84 viewport.updateInformation(af.alignPanel);
85 af.buildColourMenu(); // to enable HMMER colour schemes
86 af.setProgressBar("", msgID);
91 * Scans the parameters to determine whether to run hmmmbuild for the whole
92 * alignment or specified subgroup(s) or both
97 protected List<AnnotatedCollectionI> parseParameters(
98 AlignViewportI viewport)
100 List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
101 for (ArgumentI arg : params)
103 String name = arg.getName();
104 if (MessageManager.getString("label.hmmbuild_for").equals(name))
106 String value = arg.getValue();
107 if (MessageManager.getString("label.alignment").equals(value))
109 runBuildFor.add(alignment);
111 else if (MessageManager.getString("label.groups_and_alignment")
114 runBuildFor.add(alignment);
115 runBuildFor.addAll(viewport.getAlignment().getGroups());
117 else if (MessageManager.getString("label.groups").equals(value))
119 runBuildFor.addAll(viewport.getAlignment().getGroups());
121 else if (MessageManager.getString("label.selected_group")
124 runBuildFor.add(viewport.getSelectionGroup());
127 else if (MessageManager.getString("label.use_reference")
130 // todo disable this option if no RF annotation on alignment
131 if (!af.getViewport().hasReferenceAnnotation())
133 JvOptionPane.showInternalMessageDialog(af, MessageManager
134 .getString("warn.no_reference_annotation"));
143 * Runs hmmbuild on the given sequences (alignment or group)
147 private void runHMMBuild(AnnotatedCollectionI ac)
150 File alignmentFile = null;
153 hmmFile = createTempFile("hmm", ".hmm");
154 alignmentFile = createTempFile("output", ".sto");
155 List<SequenceI> seqs = ac.getSequences();
156 List<SequenceI> copy = new ArrayList<>();
159 if (ac instanceof Alignment)
161 AlignmentI al = (Alignment) ac;
162 // todo pad gaps in an unaligned SequenceGroup as well?
170 * copy over sequences, excluding hmm consensus sequences
171 * hmm sequences are also deleted in preparation for
172 * re-adding them when recalculated; Information annotation is not
173 * deleted, it will be updated to reference the new hmm sequence
174 * by InformationThread.findOrCreateAnnotation
176 Iterator<SequenceI> it = copy.iterator();
179 SequenceI seq = it.next();
180 if (seq.isHMMConsensusSequence())
182 alignment.deleteSequence(seq);
187 SequenceI[] copyArray = copy.toArray(new SequenceI[copy.size()]);
188 Hashtable sequencesHash = stashSequences(copyArray);
190 exportStockholm(copyArray, alignmentFile, ac);
192 recoverSequences(sequencesHash, seqs.toArray(new SequenceI[] {}));
194 boolean ran = runCommand(alignmentFile, hmmFile, ac);
199 importData(hmmFile, ac);
200 } catch (Exception e)
209 if (alignmentFile != null)
211 alignmentFile.delete();
217 * Constructs and executes the hmmbuild command as a separate process
219 * @param sequencesFile
220 * the alignment from which the HMM is built
222 * the output file to which the HMM is written
224 * alignment or group for which the hmm is generated
227 * @throws IOException
229 private boolean runCommand(File sequencesFile, File hmmFile,
230 AnnotatedCollectionI group) throws IOException
232 String cmd = getCommandPath(HMMBUILD);
235 return false; // executable not found
237 List<String> args = new ArrayList<>();
241 * HMM name (will be given to consensus sequence) is
242 * - as specified by an input parameter if set
243 * - else group name with _HMM appended (if for a group)
244 * - else align fame title with _HMM appended (if title is not too long)
245 * - else "Alignment_HMM"
251 for (ArgumentI arg : params)
253 String argName = arg.getName();
257 name = arg.getValue().trim();
259 case "Use Reference Annotation":
266 if (group instanceof SequenceGroup)
268 name = ((SequenceGroup) group).getName() + "_HMM";
273 if (af != null && af.getTitle().length() < 15)
275 name = af.getTitle();
279 name = "Alignment_HMM";
284 args.add(name.replace(' ', '_'));
285 if (!alignment.isNucleotide())
287 args.add(ARG_AMINO); // TODO check for rna
294 args.add(hmmFile.getAbsolutePath());
295 args.add(sequencesFile.getAbsolutePath());
297 return runCommand(args);
301 * Imports the .hmm file produced by hmmbuild, and inserts the HMM consensus
302 * sequence (with attached HMM profile) as the first sequence in the alignment
303 * or group for which it was generated
307 * (optional) the group for which the hmm was generated
308 * @throws IOException
310 private void importData(File hmmFile, AnnotatedCollectionI ac)
313 HMMFile file = new HMMFile(
314 new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
315 SequenceI[] seqs = file.getSeqsAsArray();
316 SequenceI hmmSeq = seqs[0];
317 hmmSeq.createDatasetSequence();
318 if (ac instanceof SequenceGroup)
320 SequenceGroup grp = (SequenceGroup) ac;
321 hmmSeq.insertCharAt(0, ac.getStartRes(), '-');
322 hmmSeq.insertCharAt(ac.getEndRes() + 1,
323 alignment.getWidth() - ac.getEndRes() - 1, '-');
324 hmmSeq.updateHMMMapping();
325 SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
326 int topIndex = alignment.findIndex(topSeq);
327 alignment.insertSequenceAt(topIndex, hmmSeq);
328 ac.setSeqrep(hmmSeq);
329 grp.addSequence(hmmSeq, false);
330 grp.setHmmConsensus(hmmSeq);
334 alignment.insertSequenceAt(0, hmmSeq);
335 alignment.setHmmConsensus(hmmSeq);
338 AlignViewport viewport = af.getViewport();
339 if (viewport != null)
341 AlignmentPanel alignPanel = viewport.getAlignPanel();
342 viewport.alignmentChanged(alignPanel);
343 alignPanel.adjustAnnotationHeight();
344 viewport.updateSequenceIdColours();
346 if (alignPanel.alignFrame.getSelectedHMM() == null)
348 alignPanel.alignFrame.setSelectedHMMSequence(hmmSeq);