package jalview.hmmer;
+import jalview.analysis.SeqsetUtils;
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.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.File;
import java.io.FileNotFoundException;
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
{
+ AlignViewport viewport;
+
+ boolean multiJob = false;
- AlignFrame af;
AlignmentI alignment;
+ SequenceGroup group;
+
+ List<ArgumentI> params;
+
+ boolean forGroup = false;
+
+ File hmmTemp = null;
+
+ File stoTemp = null;
+
long barID;
- Map<Integer, SequenceI> hmmSeqs;
-
- public HMMBuildThread(AlignFrame af)
+ /**
+ * This is used for validation purposes. Do not use!
+ *
+ * @param viewport
+ */
+ public HMMBuildThread(AlignmentI alignment)
+ {
+ this.alignment = alignment;
+ forGroup = false;
+ }
+
+ public HMMBuildThread(AlignFrame af, List<ArgumentI> args)
{
this.af = af;
- alignment = af.getViewport().getAlignment();
+ viewport = af.getViewport();
+ params = args;
}
+ /**
+ * Builds a HMM from an alignment, then imports and adds it to the alignment.
+ */
@Override
public void run()
{
barID = System.currentTimeMillis();
- af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
- barID);
+ if (af != null)
+ {
+ af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
+ barID);
+ }
- try
+ List<SequenceGroup> groups = new ArrayList<>();
+ if (params != null)
{
- try
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+ if (MessageManager.getString("label.hmmbuild_for").equals(name))
+ {
+ String value = arg.getValue();
+ if ("Alignment".equals(value))
+ {
+ alignment = viewport.getAlignment();
+ break;
+ }
+ else if ("All groups and alignment".equals(value))
+ {
+ alignment = viewport.getAlignment();
+ groups.addAll(viewport.getAlignment().getGroups());
+ if (groups.size() > 0)
+ {
+ multiJob = true;
+ }
+ break;
+ }
+ else if ("All groups".equals(value))
+ {
+ alignment = null;
+ groups = viewport.getAlignment().getGroups();
+ if (groups.size() > 0)
+ {
+ multiJob = true;
+ }
+ break;
+ }
+ else if ("Selected group".equals(value))
+ {
+ alignment = null;
+ groups.add(viewport.getSelectionGroup());
+ break;
+ }
+ }
+ else if (MessageManager.getString("label.use_reference")
+ .equals(name))
+ {
+ if (!af.getViewport().hasReferenceAnnotation())
+ {
+ if (af != null)
+ {
+ af.setProgressBar(
+ MessageManager.getString("status.running_hmmbuild"),
+ barID);
+ }
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .getString("warn.no_reference_annotation"));
+ return;
+ }
+ }
+ }
+ }
+ else if (viewport != null)
{
- exportAlignment();
- } catch (FileNotFoundException e)
+ alignment = viewport.getAlignment();
+ }
+
+ if (alignment != null)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ forGroup = false;
+ runHMMBuild();
+ }
+ if (alignment == null)
+ {
+ alignment = viewport.getAlignment();
}
- try
+
+ if (groups != null && groups.size() > 0)
{
- runCommand();
- } catch (IOException | InterruptedException e)
+ for (SequenceGroup grp : groups)
+ {
+ group = grp;
+ forGroup = true;
+ runHMMBuild();
+ }
+ }
+
+ if (af != null)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ af.setProgressBar("", barID);
+ }
+ }
+
+ private void runHMMBuild()
+ {
+ if (alignment == null && group == null)
+ {
+ JOptionPane.showMessageDialog(af,
+ MessageManager.getString("warn.no_sequence_data"));
}
try
{
- importData();
- } catch (IOException | InterruptedException e)
+ hmmTemp = File.createTempFile("hmm", ".hmm");
+ hmmTemp.deleteOnExit();
+ stoTemp = File.createTempFile("output", ".sto");
+ stoTemp.deleteOnExit();
+ } catch (IOException e1)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ e1.printStackTrace();
}
- } catch (Exception e)
+
+ try
{
+ try
+ {
+ SequenceI[] array;
+ List<SequenceI> hmmSeqs = null;
+ if (forGroup)
+ {
+ hmmSeqs = group.getHMMConsensusSequences();
+ if (hmmSeqs.size() > 0)
+ {
+ // todo why this test? means can't re-run hmmbuild on a group?
+ return;
+ }
+ array = group.getSelectionAsNewSequences(alignment);
+ }
+ else
+ {
+ hmmSeqs = alignment.getHMMConsensusSequences();
+ 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())
+ {
+ newArr[index] = new Sequence(seq);
+ index++;
+ }
+ }
+
+ uniquifySequences(newArr);
- } finally
+ if (forGroup)
+ {
+ exportData(newArr, stoTemp, null, null, group);
+ }
+ else
+ {
+ exportData(newArr, stoTemp, null, null, alignment);
+ }
+
+ SeqsetUtils.deuniquify(hash, array);
+
+ } catch (FileNotFoundException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ }
+ try
+ {
+ boolean ran = runCommand();
+ if (!ran)
+ {
+ return;
+ }
+ } catch (IOException | InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ try
+ {
+
+ importData();
+ } catch (IOException | InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } catch (Exception e)
{
- af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
- barID);
+ e.printStackTrace();
}
}
-
- private void exportAlignment() throws IOException
+ /**
+ * Executes the hmmbuild command in the command line.
+ *
+ * @return
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private boolean runCommand() throws IOException, InterruptedException
{
- hmmSeqs = alignment.getHMMConsensusSequences(true);
- if (!alignment.isAligned())
+ String binaryPath = getCommandRoot(HMMBUILD);
+ if (binaryPath == null)
+ {
+ return false;
+ }
+ String command = binaryPath + SPACE;
+ String name = null;
+
+ if (params != null)
+ {
+ for (ArgumentI arg : params)
+ {
+ String argName = arg.getName();
+ switch (argName)
+ {
+ case "HMM Name":
+ name = arg.getValue();
+ name = name.trim();
+ break;
+ case "Use Reference Annotation":
+ command += "--hand ";
+ break;
+
+ }
+ }
+ }
+
+ if (forGroup && multiJob)
+ {
+ name = group.getName() + "_HMM";
+ }
+
+ if (name == null || "".equals(name))
+ {
+ if (af != null)
+ {
+ if (af.getTitle().length() < 15)
+ {
+ name = af.getTitle();
+ }
+ }
+ if (name == null || "".equals(name))
+ {
+ name = "Alignment";
+ }
+
+ }
+
+ command += "-n " + name.replace(' ', '_') + SPACE;
+ if (!alignment.isNucleotide())
+ {
+ command += FORCEAMINO; // TODO check for rna
+ }
+ else
{
- alignment.padGaps();
+ command += FORCEDNA;
}
- HMMERCommands.exportData(alignment, true, false,
- new HiddenMarkovModel());
+
+ command += hmmTemp.getAbsolutePath() + SPACE + stoTemp.getAbsolutePath()
+ + SPACE;
+ return runCommand(command);
}
-
- private void runCommand() throws IOException, InterruptedException
+
+ /**
+ * Imports the .hmm file produced by hmmbuild.
+ *
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private void importData() throws IOException, InterruptedException
{
- final String command = 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(hmmTemp.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);
+ }
+
+ 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();
}
-
- 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<Integer, SequenceI> 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();
}
-
-
-
-
}