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.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.workers.InformationThread;
19 import jalview.ws.params.ArgumentI;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Hashtable;
25 import java.util.Iterator;
26 import java.util.List;
29 * A class that runs the hmmbuild command as a separate process.
34 public class HMMBuild extends HmmerCommand
36 static final String ARG_AMINO = "--amino";
38 static final String ARG_DNA = "--dna";
40 static final String ARG_RNA = "--rna";
48 public HMMBuild(AlignFrame alignFrame, List<ArgumentI> args)
50 super(alignFrame, args);
54 * Builds a HMM from an alignment (and/or groups), then imports and adds it to
55 * the alignment (and/or groups). Call this method directly to execute
56 * synchronously, or via start() in a new Thread for asynchronously.
61 long msgID = System.currentTimeMillis();
62 af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
65 AlignViewportI viewport = af.getViewport();
68 List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
71 for (ArgumentI arg : params)
73 String name = arg.getName();
74 if (MessageManager.getString("label.hmmbuild_for").equals(name))
76 String value = arg.getValue();
77 if (MessageManager.getString("label.alignment")
80 runBuildFor.add(alignment);
82 else if (MessageManager.getString("label.groups_and_alignment")
85 runBuildFor.add(alignment);
86 runBuildFor.addAll(viewport.getAlignment().getGroups());
88 else if (MessageManager.getString("label.groups").equals(value))
90 runBuildFor.addAll(viewport.getAlignment().getGroups());
92 else if (MessageManager.getString("label.selected_group")
95 runBuildFor.add(viewport.getSelectionGroup());
98 else if (MessageManager.getString("label.use_reference")
101 // todo disable this option if no RF annotation on alignment
102 if (!af.getViewport().hasReferenceAnnotation())
104 JvOptionPane.showInternalMessageDialog(af, MessageManager
105 .getString("warn.no_reference_annotation"));
113 * run hmmbuild for alignment and/or groups as selected
115 for (AnnotatedCollectionI grp : runBuildFor)
121 viewport.updateInformation(af.alignPanel);
122 af.buildColourMenu(); // to enable HMMER colour schemes
123 af.setProgressBar("", msgID);
128 * Runs hmmbuild on the given sequences (alignment or group)
132 private void runHMMBuild(AnnotatedCollectionI ac)
135 File alignmentFile = null;
138 hmmFile = createTempFile("hmm", ".hmm");
139 alignmentFile = createTempFile("output", ".sto");
140 List<SequenceI> seqs = ac.getSequences();
141 List<SequenceI> copy = new ArrayList<>();
144 if (ac instanceof Alignment)
146 AlignmentI al = (Alignment) ac;
147 // todo pad gaps in an unaligned SequenceGroup as well?
155 * copy over sequences, excluding hmm consensus sequences
156 * hmm sequences and their Information annotation are also deleted
157 * in preparation for re-adding them when recalculated
159 Iterator<SequenceI> it = copy.iterator();
162 SequenceI seq = it.next();
163 if (seq.isHMMConsensusSequence())
165 // todo leave it to InformationThread to delete annotations?
166 AlignmentAnnotation[] seqAnnotations = seq
168 if (seqAnnotations != null)
170 for (AlignmentAnnotation ann : seqAnnotations)
172 if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
174 alignment.deleteAnnotation(ann);
178 alignment.deleteSequence(seq);
183 SequenceI[] copyArray = copy.toArray(new SequenceI[copy.size()]);
184 Hashtable sequencesHash = stashSequences(copyArray);
186 exportStockholm(copyArray, alignmentFile, ac);
188 recoverSequences(sequencesHash, seqs.toArray(new SequenceI[] {}));
190 boolean ran = runCommand(alignmentFile, hmmFile, ac);
195 importData(hmmFile, ac);
196 } catch (Exception e)
205 if (alignmentFile != null)
207 alignmentFile.delete();
213 * Constructs and executes the hmmbuild command as a separate process
215 * @param sequencesFile
216 * the alignment from which the HMM is built
218 * the output file to which the HMM is written
220 * alignment or group for which the hmm is generated
223 * @throws IOException
225 private boolean runCommand(File sequencesFile, File hmmFile,
226 AnnotatedCollectionI group) throws IOException
228 String cmd = getCommandPath(HMMBUILD);
231 return false; // executable not found
233 List<String> args = new ArrayList<>();
237 * HMM name (will be given to consensus sequence) is
238 * - as specified by an input parameter if set
239 * - else group name with _HMM appended (if for a group)
240 * - else align fame title with _HMM appended (if title is not too long)
241 * - else "Alignment_HMM"
247 for (ArgumentI arg : params)
249 String argName = arg.getName();
253 name = arg.getValue().trim();
255 case "Use Reference Annotation":
262 if (group instanceof SequenceGroup)
264 name = ((SequenceGroup) group).getName() + "_HMM";
269 if (af != null && af.getTitle().length() < 15)
271 name = af.getTitle();
275 name = "Alignment_HMM";
280 args.add(name.replace(' ', '_'));
281 if (!alignment.isNucleotide())
283 args.add(ARG_AMINO); // TODO check for rna
290 args.add(hmmFile.getAbsolutePath());
291 args.add(sequencesFile.getAbsolutePath());
293 return runCommand(args);
297 * Imports the .hmm file produced by hmmbuild, and inserts the HMM consensus
298 * sequence (with attached HMM profile) as the first sequence in the alignment
299 * or group for which it was generated
303 * (optional) the group for which the hmm was generated
304 * @throws IOException
306 private void importData(File hmmFile, AnnotatedCollectionI ac)
309 HMMFile file = new HMMFile(
310 new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
311 SequenceI[] seqs = file.getSeqsAsArray();
312 SequenceI hmmSeq = seqs[0];
313 hmmSeq.createDatasetSequence();
314 if (ac instanceof SequenceGroup)
316 SequenceGroup grp = (SequenceGroup) ac;
317 hmmSeq.insertCharAt(0, ac.getStartRes(), '-');
318 hmmSeq.insertCharAt(ac.getEndRes() + 1,
319 alignment.getWidth() - ac.getEndRes() - 1, '-');
320 hmmSeq.updateHMMMapping();
321 SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
322 int topIndex = alignment.findIndex(topSeq);
323 alignment.insertSequenceAt(topIndex, hmmSeq);
324 ac.setSeqrep(hmmSeq);
325 grp.addSequence(hmmSeq, false);
326 grp.setHmmConsensus(hmmSeq);
330 alignment.insertSequenceAt(0, hmmSeq);
331 alignment.setHmmConsensus(hmmSeq);
334 AlignViewport viewport = af.getViewport();
335 if (viewport != null)
337 AlignmentPanel alignPanel = viewport.getAlignPanel();
338 viewport.alignmentChanged(alignPanel);
339 alignPanel.adjustAnnotationHeight();
340 viewport.updateSequenceIdColours();
342 if (alignPanel.alignFrame.getSelectedHMM() == null)
344 alignPanel.alignFrame.setSelectedHMMSequence(hmmSeq);