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.JvOptionPane;
13 import jalview.io.DataSourceType;
14 import jalview.io.FileParse;
15 import jalview.io.HMMFile;
16 import jalview.util.MessageManager;
17 import jalview.ws.params.ArgumentI;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Hashtable;
23 import java.util.Iterator;
24 import java.util.List;
27 * A class that runs the hmmbuild command as a separate process.
32 public class HMMBuild extends HmmerCommand
34 static final String ARG_AMINO = "--amino";
36 static final String ARG_DNA = "--dna";
38 static final String ARG_RNA = "--rna";
46 public HMMBuild(AlignFrame alignFrame, List<ArgumentI> args)
48 super(alignFrame, args);
52 * Builds a HMM from an alignment (and/or groups), then imports and adds it to
53 * the alignment (and/or groups). Call this method directly to execute
54 * synchronously, or via start() in a new Thread for asynchronously.
61 Cache.log.error("No parameters to HMMBuild!|");
65 long msgID = System.currentTimeMillis();
66 af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
69 AlignViewport viewport = af.getViewport();
73 * run hmmbuild for alignment and/or groups as selected
75 List<AnnotatedCollectionI> runBuildFor = parseParameters(viewport);
77 for (AnnotatedCollectionI grp : runBuildFor)
83 af.setProgressBar("", msgID);
84 viewport.alignmentChanged(af.alignPanel);
85 af.buildColourMenu(); // to enable HMMER colour schemes
90 * Scans the parameters to determine whether to run hmmmbuild for the whole
91 * alignment or specified subgroup(s) or both
96 protected List<AnnotatedCollectionI> parseParameters(
97 AlignViewportI viewport)
99 List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
100 for (ArgumentI arg : params)
102 String name = arg.getName();
103 if (MessageManager.getString("label.hmmbuild_for").equals(name))
105 String value = arg.getValue();
106 if (MessageManager.getString("label.alignment").equals(value))
108 runBuildFor.add(alignment);
110 else if (MessageManager.getString("label.groups_and_alignment")
113 runBuildFor.add(alignment);
114 runBuildFor.addAll(viewport.getAlignment().getGroups());
116 else if (MessageManager.getString("label.groups").equals(value))
118 runBuildFor.addAll(viewport.getAlignment().getGroups());
120 else if (MessageManager.getString("label.selected_group")
123 runBuildFor.add(viewport.getSelectionGroup());
126 else if (MessageManager.getString("label.use_reference")
129 // todo disable this option if no RF annotation on alignment
130 if (!af.getViewport().hasReferenceAnnotation())
132 JvOptionPane.showInternalMessageDialog(af, MessageManager
133 .getString("warn.no_reference_annotation"));
142 * Runs hmmbuild on the given sequences (alignment or group)
146 private void runHMMBuild(AnnotatedCollectionI ac)
149 File alignmentFile = null;
152 hmmFile = createTempFile("hmm", ".hmm");
153 alignmentFile = createTempFile("output", ".sto");
154 List<SequenceI> seqs = ac.getSequences();
155 List<SequenceI> copy = new ArrayList<>();
158 if (ac instanceof Alignment)
160 AlignmentI al = (Alignment) ac;
161 // todo pad gaps in an unaligned SequenceGroup as well?
169 * copy over sequences, excluding hmm consensus sequences
170 * hmm sequences are also deleted in preparation for
171 * re-adding them when recalculated; Information annotation is not
172 * deleted, it will be updated to reference the new hmm sequence
173 * by InformationThread.findOrCreateAnnotation
175 Iterator<SequenceI> it = copy.iterator();
178 SequenceI seq = it.next();
179 if (seq.isHMMConsensusSequence())
181 alignment.deleteSequence(seq);
186 SequenceI[] copyArray = copy.toArray(new SequenceI[copy.size()]);
187 Hashtable sequencesHash = stashSequences(copyArray);
189 exportStockholm(copyArray, alignmentFile, ac);
191 recoverSequences(sequencesHash, seqs.toArray(new SequenceI[] {}));
193 boolean ran = runCommand(alignmentFile, hmmFile, ac);
198 importData(hmmFile, ac);
199 } catch (Exception e)
208 if (alignmentFile != null)
210 alignmentFile.delete();
216 * Constructs and executes the hmmbuild command as a separate process
218 * @param sequencesFile
219 * the alignment from which the HMM is built
221 * the output file to which the HMM is written
223 * alignment or group for which the hmm is generated
226 * @throws IOException
228 private boolean runCommand(File sequencesFile, File hmmFile,
229 AnnotatedCollectionI group) throws IOException
231 String cmd = getCommandPath(HMMBUILD);
234 return false; // executable not found
236 List<String> args = new ArrayList<>();
240 * HMM name (will be given to consensus sequence) is
241 * - as specified by an input parameter if set
242 * - else group name with _HMM appended (if for a group)
243 * - else align fame title with _HMM appended (if title is not too long)
244 * - else "Alignment_HMM"
250 for (ArgumentI arg : params)
252 String argName = arg.getName();
256 name = arg.getValue().trim();
258 case "Use Reference Annotation":
265 if (group instanceof SequenceGroup)
267 name = ((SequenceGroup) group).getName() + "_HMM";
272 if (af != null && af.getTitle().length() < 15)
274 name = af.getTitle();
278 name = "Alignment_HMM";
283 args.add(name.replace(' ', '_'));
284 if (!alignment.isNucleotide())
286 args.add(ARG_AMINO); // TODO check for rna
293 args.add(hmmFile.getAbsolutePath());
294 args.add(sequencesFile.getAbsolutePath());
296 return runCommand(args);
300 * Imports the .hmm file produced by hmmbuild, and inserts the HMM consensus
301 * sequence (with attached HMM profile) as the first sequence in the alignment
302 * or group for which it was generated
306 * (optional) the group for which the hmm was generated
307 * @throws IOException
309 private void importData(File hmmFile, AnnotatedCollectionI ac)
312 HMMFile file = new HMMFile(
313 new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
314 SequenceI[] seqs = file.getSeqsAsArray();
315 SequenceI hmmSeq = seqs[0];
316 hmmSeq.createDatasetSequence();
317 if (ac instanceof SequenceGroup)
319 SequenceGroup grp = (SequenceGroup) ac;
320 hmmSeq.insertCharAt(0, ac.getStartRes(), '-');
321 hmmSeq.insertCharAt(ac.getEndRes() + 1,
322 alignment.getWidth() - ac.getEndRes() - 1, '-');
323 hmmSeq.updateHMMMapping();
324 SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
325 int topIndex = alignment.findIndex(topSeq);
326 alignment.insertSequenceAt(topIndex, hmmSeq);
327 ac.setSeqrep(hmmSeq);
328 grp.addSequence(hmmSeq, false);
329 grp.setHmmConsensus(hmmSeq);
333 alignment.insertSequenceAt(0, hmmSeq);
334 alignment.setHmmConsensus(hmmSeq);
337 if (af.getSelectedHMM() == null)
339 af.setSelectedHMMSequence(hmmSeq);