package jalview.hmmer;
-
-import jalview.bin.Cache;
+import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.gui.AlignFrame;
import jalview.gui.AlignViewport;
import jalview.gui.JvOptionPane;
-import jalview.gui.Preferences;
import jalview.io.DataSourceType;
-import jalview.io.FileFormat;
-import jalview.io.FileLoader;
import jalview.io.FileParse;
import jalview.io.HMMFile;
import jalview.util.MessageManager;
import jalview.ws.params.ArgumentI;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
-public class HMMBuildThread implements Runnable
+public class HMMBuildThread extends HmmerCommand implements Runnable
{
- HMMERCommands cmds = new HMMERCommands();
- AlignFrame af;
-
- AlignViewport viewport;
- AlignmentI alignment;
- SequenceGroup group;
-
- List<ArgumentI> params;
+ static final String ARG_AMINO = "--amino";
+ static final String ARG_DNA = "--dna";
- boolean forGroup = false;
+ static final String ARG_RNA = "--rna";
- File hmmTemp = null;
-
- File stoTemp = null;
+ AlignmentI alignment;
- long barID;
-
/**
- * This is used for validation purposes. Do not use!
+ * Constructor
*
- * @param viewport
+ * @param alignFrame
+ * @param args
*/
- public HMMBuildThread(AlignmentI alignment)
- {
- this.alignment = alignment;
- forGroup = false;
- }
-
- public HMMBuildThread(AlignFrame af, List<ArgumentI> args)
+ public HMMBuildThread(AlignFrame alignFrame, List<ArgumentI> args)
{
- this.af = af;
- if (af.getViewport().getSelectionGroup() != null)
- {
- group = af.getViewport().getSelectionGroup();
- forGroup = true;
- }
- viewport = af.getViewport();
- alignment = viewport.getAlignment();
- params = args;
-
+ super(alignFrame, args);
}
/**
- * Builds a HMM from an alignment, then imports and adds it to the alignment.
+ * 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();
+ long msgID = System.currentTimeMillis();
if (af != null)
{
- af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
- barID);
- }
- cmds.HMMERFOLDER = Cache.getProperty(Preferences.HMMER_PATH);
- if (alignment == null && group == null)
- {
- JOptionPane.showMessageDialog(af,
- MessageManager.getString("warn.no_sequence_data"));
- return;
+ af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
+ msgID);
}
+
+ AlignViewportI viewport = af.getViewport();
try
{
- hmmTemp = File.createTempFile("hmm", ".hmm");
- hmmTemp.deleteOnExit();
- stoTemp = File.createTempFile("output", ".sto");
- stoTemp.deleteOnExit();
- } catch (IOException e1)
+ if (viewport != null)
+ {
+ alignment = viewport.getAlignment();
+ }
+ List<SequenceGroup> 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
{
- e1.printStackTrace();
+ if (af != null)
+ {
+ af.setProgressBar("", msgID);
+ }
}
+ }
- try
+ /**
+ * 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
{
- SequenceI[] array;
- List<SequenceI> seqs = alignment
- .getHMMConsensusSequences(true);
- cmds.setHmmSeqs(seqs);
- if (forGroup)
+ hmmFile = createTempFile("hmm", ".hmm");
+ alignmentFile = createTempFile("output", ".sto");
+ SequenceI[] array;
+ List<SequenceI> 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())
{
- array = group.getSelectionAsNewSequences(alignment);
+ alignment.padGaps();
}
- else
+ array = alignment.getSequencesArray();
+ }
+
+ if (array.length < 1)
+ {
+ if (af != null)
{
- if (!alignment.isAligned())
- {
- alignment.padGaps();
- }
- array = alignment.getSequencesArray();
+ JOptionPane.showMessageDialog(af,
+ MessageManager.getString("warn.no_sequence_data"));
}
- if (array.length < 1)
+ 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())
{
- if (af != null)
- {
- JOptionPane.showMessageDialog(af,
- MessageManager.getString("warn.no_sequence_data"));
- }
- return;
+ alignment.deleteSequence(seq);
}
- SequenceI[] newArr = new SequenceI[array.length];
- int index = 0;
- for (SequenceI seq : array)
+ else
{
newArr[index] = new Sequence(seq);
index++;
}
+ }
- cmds.uniquifySequences(newArr);
- cmds.exportData(newArr, stoTemp, null, null);
- jalview.analysis.SeqsetUtils.deuniquify(cmds.hash, array);
+ stashSequences(newArr);
- } catch (FileNotFoundException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ exportStockholm(newArr, alignmentFile,
+ group != null ? group : alignment);
- }
- try
- {
- boolean ran = runCommand();
- if (!ran)
- {
- return;
- }
- } catch (IOException | InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try
- {
+ recoverSequences(array);
- importData();
- } catch (IOException | InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ boolean ran = runCommand(alignmentFile, hmmFile, group);
+ if (!ran)
+ {
+ return;
+ }
+ importData(hmmFile, group);
} catch (Exception e)
{
e.printStackTrace();
} finally
{
- if (af != null)
+ if (hmmFile != null)
+ {
+ hmmFile.delete();
+ }
+ if (alignmentFile != null)
{
- af.setProgressBar(
- MessageManager.getString("status.running_hmmbuild"),
- barID);
+ alignmentFile.delete();
}
}
}
-
-
/**
- * Executes the hmmbuild command in the command line.
+ * 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() throws IOException, InterruptedException
+ private boolean runCommand(File sequences, File hmm, SequenceGroup group)
+ throws IOException, InterruptedException
{
- File file = new File(cmds.HMMERFOLDER + "/hmmbuild");
- if (!file.canExecute())
+
+ String cmd = getCommandPath(HMMBUILD);
+ if (cmd == null)
{
- file = new File(cmds.HMMERFOLDER + "/hmmbuild.exe");
- {
- if (!file.canExecute())
- {
- if (af != null)
- {
- JvOptionPane.showInternalMessageDialog(af,
- MessageManager.getString("warn.hmmbuild_failed"));
- }
- return false;
- }
- }
+ return false;
}
- String command = cmds.HMMERFOLDER + cmds.HMMBUILD + cmds.SPACE;
+ List<String> args = new ArrayList<>();
+ args.add(cmd);
String name = null;
if (params != null)
{
case "HMM Name":
name = arg.getValue();
+ name = name.trim();
break;
case "Use Reference Annotation":
- command += "--hand ";
- if (!af.getViewport().hasReferenceAnnotation())
- {
- JvOptionPane.showInternalMessageDialog(af, MessageManager
- .getString("warn.no_reference_annotation"));
- return false;
- }
+ args.add("--hand");
break;
-
}
-
}
}
- if (name == null || name == "" || name == " ")
+ if (group != null)
{
- if (forGroup)
- {
- name = group.getName();
- }
- else
+ name = group.getName() + "_HMM";
+ }
+
+ if (name == null || "".equals(name))
+ {
+ if (af != null)
{
- if (af != null)
+ if (af.getTitle().length() < 15)
{
name = af.getTitle();
}
- if (name == null || name == "" || name == " " || name == " ")
- {
- name = "Alignment";
- }
}
+ if (name == null || "".equals(name))
+ {
+ name = "Alignment";
+ }
+
}
- command += "-n " + name + cmds.SPACE;
+ args.add("-n");
+ args.add(name.replace(' ', '_'));
if (!alignment.isNucleotide())
{
- command += cmds.FORCEAMINO; // TODO check for rna
+ args.add(ARG_AMINO); // TODO check for rna
}
else
{
- command += cmds.FORCEDNA;
+ args.add(ARG_DNA);
}
- command += hmmTemp.getAbsolutePath()
- + cmds.SPACE + stoTemp.getAbsolutePath() + cmds.SPACE;
- return cmds.runCommand(command);
+ args.add(hmm.getAbsolutePath());
+ args.add(sequences.getAbsolutePath());
+
+ return runCommand(args);
}
-
+
/**
- * Imports the .hmm file produced by hmmbuild.
+ * 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() throws IOException, InterruptedException
+ private void importData(File hmmFile, SequenceGroup group)
+ throws IOException, InterruptedException
{
- if (af != null)
+ HMMFile file = new HMMFile(
+ new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
+ SequenceI[] seqs = file.getSeqsAsArray();
+ SequenceI seq = seqs[0];
+ seq.createDatasetSequence();
+ if (group != null)
{
- cmds.addHMMConsensusSequences(af);
-
- FileLoader loader = new FileLoader();
- loader.LoadFileOntoAlignmentWaitTillLoaded(viewport,
- hmmTemp.getAbsolutePath(), DataSourceType.FILE,
- FileFormat.HMMER3);
+ 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
{
- HMMFile file = new HMMFile(new FileParse(hmmTemp.getAbsolutePath(),
- DataSourceType.FILE));
- alignment.addSequence(file.getSeqsAsArray()[0]);
+ 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);
+ }
}
- hmmTemp.delete();
- stoTemp.delete();
}
-
+
/**
* Runs hmmbuild, and waits for the results to be imported before continuing
*/