X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fhmmer%2FHMMBuildThread.java;h=c52fb86db794abe86e59cbd8322c3e222857fe40;hb=e6fd15cb3a149fb6a8852448260b7b6e52dd2dcc;hp=e48dce3d69503083ae9cda343b3248d1cdc869a3;hpb=bb7c8e1f39eca07ec0bc544df298ee58f109b011;p=jalview.git diff --git a/src/jalview/hmmer/HMMBuildThread.java b/src/jalview/hmmer/HMMBuildThread.java index e48dce3..c52fb86 100644 --- a/src/jalview/hmmer/HMMBuildThread.java +++ b/src/jalview/hmmer/HMMBuildThread.java @@ -1,109 +1,376 @@ package jalview.hmmer; -import jalview.bin.Cache; +import jalview.api.AlignViewportI; import jalview.datamodel.AlignmentI; -import jalview.datamodel.HiddenMarkovModel; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; -import jalview.gui.Preferences; +import jalview.gui.AlignViewport; +import jalview.gui.JvOptionPane; import jalview.io.DataSourceType; -import jalview.io.FileFormat; +import jalview.io.FileParse; +import jalview.io.HMMFile; import jalview.util.MessageManager; +import jalview.ws.params.ArgumentI; -import java.io.FileNotFoundException; +import java.io.File; import java.io.IOException; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; -public class HMMBuildThread implements Runnable +import javax.swing.JOptionPane; + +public class HMMBuildThread extends HmmerCommand implements Runnable { + static final String ARG_AMINO = "--amino"; - AlignFrame af; - AlignmentI alignment; + static final String ARG_DNA = "--dna"; - long barID; + static final String ARG_RNA = "--rna"; + + AlignmentI alignment; - Map hmmSeqs; - - public HMMBuildThread(AlignFrame af) + /** + * Constructor + * + * @param alignFrame + * @param args + */ + public HMMBuildThread(AlignFrame alignFrame, List args) { - this.af = af; - alignment = af.getViewport().getAlignment(); + super(alignFrame, args); } + /** + * Builds a HMM from an alignment (and/or groups), then imports and adds it to + * the alignment (and/or groups) + */ @Override public void run() { - barID = System.currentTimeMillis(); - af.setProgressBar(MessageManager.getString("status.running_hmmbuild"), - barID); - HMMERCommands.HMMERFOLDER = Cache.getProperty(Preferences.HMMER_PATH); - - try + long msgID = System.currentTimeMillis(); + if (af != null) { + af.setProgressBar(MessageManager.getString("status.running_hmmbuild"), + msgID); + } + + AlignViewportI viewport = af.getViewport(); try { - hmmSeqs = alignment.getHMMConsensusSequences(true); - HMMERCommands.exportData(alignment, true, false, - new HiddenMarkovModel()); - } catch (FileNotFoundException e) + if (viewport != null) + { + alignment = viewport.getAlignment(); + } + List groups = new ArrayList<>(); + if (params != null) + { + for (ArgumentI arg : params) + { + String name = arg.getName(); + if (MessageManager.getString("label.hmmbuild_for").equals(name)) + { + String value = arg.getValue(); + if (MessageManager.getString("label.alignment").equals(value)) + { + alignment = viewport.getAlignment(); + } + else if (MessageManager.getString("label.groups_and_alignment") + .equals(value)) + { + alignment = viewport.getAlignment(); + groups.addAll(viewport.getAlignment().getGroups()); + } + else if (MessageManager.getString("label.groups").equals(value)) + { + alignment = null; + groups = viewport.getAlignment().getGroups(); + } + else if ("label.selected_group".equals(value)) + { + alignment = null; + groups.add(viewport.getSelectionGroup()); + } + } + else if (MessageManager.getString("label.use_reference") + .equals(name)) + { + // todo disable this option if no RF annotation on alignment + if (!af.getViewport().hasReferenceAnnotation()) + { + JvOptionPane.showInternalMessageDialog(af, MessageManager + .getString("warn.no_reference_annotation")); + // return; + } + } + } + } + + if (alignment != null) + { + runHMMBuild(null); + } + + if (alignment == null) + { + alignment = viewport.getAlignment(); + } + + for (SequenceGroup grp : groups) + { + runHMMBuild(grp); + } + } finally { - // TODO Auto-generated catch block - e.printStackTrace(); + if (af != null) + { + af.setProgressBar("", msgID); + } + } + } + /** + * Runs hmmbuild on the alignment, or on the group if one is specified + * + * @param grp + */ + private void runHMMBuild(SequenceGroup group) + { + if (alignment == null && group == null) + { + JOptionPane.showMessageDialog(af, + MessageManager.getString("warn.no_sequence_data")); } + File hmmFile = null; + File alignmentFile = null; try { - runCommand(); - } catch (IOException | InterruptedException e) + hmmFile = createTempFile("hmm", ".hmm"); + alignmentFile = createTempFile("output", ".sto"); + SequenceI[] array; + List hmmSeqs = null; + if (group != null) + { + hmmSeqs = group.getHMMConsensusSequences(); + array = group.getSelectionAsNewSequences(alignment); + } + else + { + hmmSeqs = alignment.getHMMConsensusSequences(); + // todo pad gaps in an unaligned SequenceGroup as well? + if (!alignment.isAligned()) + { + alignment.padGaps(); + } + array = alignment.getSequencesArray(); + } + + if (array.length < 1) + { + if (af != null) + { + JOptionPane.showMessageDialog(af, + MessageManager.getString("warn.no_sequence_data")); + } + return; + } + + /* + * copy over sequences excluding hmm consensus sequences + */ + SequenceI[] newArr = new SequenceI[array.length - hmmSeqs.size()]; + int index = 0; + for (SequenceI seq : array) + { + if (seq.isHMMConsensusSequence()) + { + alignment.deleteSequence(seq); + } + else + { + newArr[index] = new Sequence(seq); + index++; + } + } + + stashSequences(newArr); + + exportStockholm(newArr, alignmentFile, + group != null ? group : alignment); + + recoverSequences(array); + + boolean ran = runCommand(alignmentFile, hmmFile, group); + if (!ran) + { + return; + } + importData(hmmFile, group); + } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); + } finally + { + if (hmmFile != null) + { + hmmFile.delete(); + } + if (alignmentFile != null) + { + alignmentFile.delete(); + } } - try + } + + /** + * Constructs and executes the hmmbuild command as a separate process + * + * @param sequences + * the alignment from which the HMM is built + * @param hmm + * the output file to which the HMM is written + * @param group + * (optional) group for which the hmm is generated + * + * @return + * @throws IOException + * @throws InterruptedException + */ + private boolean runCommand(File sequences, File hmm, SequenceGroup group) + throws IOException, InterruptedException + { + + String cmd = getCommandPath(HMMBUILD); + if (cmd == null) { - importData(); - } catch (IOException | InterruptedException e) + return false; + } + List args = new ArrayList<>(); + args.add(cmd); + String name = null; + + if (params != null) { - // TODO Auto-generated catch block - e.printStackTrace(); + for (ArgumentI arg : params) + { + String argName = arg.getName(); + switch (argName) + { + case "HMM Name": + name = arg.getValue(); + name = name.trim(); + break; + case "Use Reference Annotation": + args.add("--hand"); + break; + } + } } - } catch (Exception e) + + if (group != null) { + name = group.getName() + "_HMM"; + } - } finally + if (name == null || "".equals(name)) { - af.setProgressBar(MessageManager.getString("status.running_hmmbuild"), - barID); + if (af != null) + { + if (af.getTitle().length() < 15) + { + name = af.getTitle(); + } + } + if (name == null || "".equals(name)) + { + name = "Alignment"; + } + } - } - + args.add("-n"); + args.add(name.replace(' ', '_')); + if (!alignment.isNucleotide()) + { + args.add(ARG_AMINO); // TODO check for rna + } + else + { + args.add(ARG_DNA); + } + + args.add(hmm.getAbsolutePath()); + args.add(sequences.getAbsolutePath()); + + return runCommand(args); + } - - private void runCommand() throws IOException, InterruptedException + /** + * Imports the .hmm file produced by hmmbuild, and inserts the HMM consensus + * sequence (with attached HMM profile) as the first sequence in the alignment + * or group for which it was generated + * + * @param hmmFile + * @oparam group (optional) the group for which the hmm was generated + * @throws IOException + * @throws InterruptedException + */ + private void importData(File hmmFile, SequenceGroup group) + throws IOException, InterruptedException { - final String command = HMMERCommands.HMMERFOLDER - + HMMERCommands.HMMBUILD + HMMERCommands.NAME - + af.getName() + HMMERCommands.SPACE - + HMMERCommands.JALVIEWDIRECTORY + HMMERCommands.HMMBUFFER - + HMMERCommands.JALVIEWDIRECTORY + HMMERCommands.ALIGNMENTBUFFER; - HMMERCommands.runCommand(command); + HMMFile file = new HMMFile( + new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE)); + SequenceI[] seqs = file.getSeqsAsArray(); + SequenceI seq = seqs[0]; + seq.createDatasetSequence(); + if (group != null) + { + seq.insertCharAt(0, group.getStartRes(), '-'); + seq.insertCharAt(group.getEndRes() + 1, + alignment.getWidth() - group.getEndRes() - 1, '-'); + seq.updateHMMMapping(); + SequenceI topSeq = group.getSequencesInOrder(alignment)[0]; + int topIndex = alignment.findIndex(topSeq); + alignment.insertSequenceAt(topIndex, seq); + group.setSeqrep(seq); + group.addSequence(seq, false); + } + else + { + alignment.insertSequenceAt(0, seq); + } + + AlignViewport viewport = af.getViewport(); + if (viewport != null) + { + viewport.alignmentChanged(viewport.getAlignPanel()); + viewport.getAlignPanel().adjustAnnotationHeight(); + viewport.updateSequenceIdColours(); + + if (viewport.getAlignPanel().alignFrame.getSelectedHMM() == null) + { + viewport.getAlignPanel().alignFrame.setSelectedHMMSequence(seq); + } + } } - - private void importData() throws IOException, InterruptedException + + /** + * Runs hmmbuild, and waits for the results to be imported before continuing + */ + public void hmmbuildWaitTillComplete() { - af.loadJalviewDataFile(HMMERCommands.HMMBUFFER, DataSourceType.FILE, - FileFormat.HMMER3, null); - for (Map.Entry entry : hmmSeqs.entrySet()) + Thread loader = new Thread(this); + loader.start(); + + while (loader.isAlive()) { - SequenceI seq = entry.getValue(); - Integer pos = entry.getKey(); - HMMERCommands.addHMMConsensusSequence(af, seq, pos); + try + { + Thread.sleep(500); + } catch (Exception ex) + { + } } - af.alignPanel.alignmentChanged(); } - - - - }