JAL-2629 hmm search UI and structural improvements, inclusion thresholds
[jalview.git] / src / jalview / hmmer / Search.java
diff --git a/src/jalview/hmmer/Search.java b/src/jalview/hmmer/Search.java
new file mode 100644 (file)
index 0000000..24bd6b7
--- /dev/null
@@ -0,0 +1,294 @@
+package jalview.hmmer;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Scanner;
+
+public abstract class Search extends HmmerCommand
+{
+
+  static final String JACKHMMER = "jackhmmer";
+
+  static final String HMMSEARCH = "hmmsearch";
+
+  boolean realign = false;
+
+  boolean trim = false;
+
+  SequenceI[] seqs;
+
+  String databaseName;
+
+  boolean searchAlignment = true;
+
+  Hashtable sequencesHash;
+
+  public Search(AlignFrame alignFrame, List<ArgumentI> args)
+  {
+    super(alignFrame, args);
+  }
+
+  @Override
+  public void run()
+  {
+  }
+
+  /**
+   * Reads in the scores table output by jackhmmer and adds annotation to
+   * sequences for E-value and bit score
+   * 
+   * @param inputTableTemp
+   * @throws IOException
+   */
+  void readTable(File inputTableTemp) throws IOException
+  {
+    BufferedReader br = new BufferedReader(new FileReader(inputTableTemp));
+    String line = "";
+    while (!line.startsWith("Query:"))
+    {
+      line = br.readLine();
+    }
+    while (!line.contains("-------"))
+    {
+      line = br.readLine();
+    }
+    line = br.readLine();
+
+    int index = 0;
+
+    while (!"  ------ inclusion threshold ------".equals(line)
+            && !"".equals(line))
+    {
+
+      Scanner scanner = new Scanner(line);
+      String evalue = scanner.next();
+
+      if (evalue.equals("+") || evalue.equals("-"))
+      {
+        evalue = scanner.next();
+      }
+
+      String score = scanner.next();
+      checkSequenceOrder(index, scanner);
+      SequenceI seq = seqs[index];
+      addScoreAnnotations(evalue, score, seq);
+      scanner.close();
+      line = br.readLine();
+      index++;
+    }
+
+    br.close();
+  }
+
+  void checkSequenceOrder(int index, Scanner scanner)
+  {
+    String seqName = null;
+
+    for (int i = 0; i < 7; i++)
+    {
+      seqName = scanner.next();
+    }
+
+    if (!seqs[index].getName().equals(seqName))
+    {
+      SequenceI temp = seqs[index];
+
+      for (int j = 0; j < seqs.length; j++)
+      {
+        if (seqs[j].getName().equals(seqName))
+        {
+          seqs[index] = seqs[j];
+          seqs[j] = temp;
+          break;
+        }
+      }
+    }
+  }
+
+  void addScoreAnnotations(String eValue, String bitScore, SequenceI seq)
+  {
+    String label = "Search Scores";
+    String description = "Full sequence bit score and E-Value";
+
+    try
+    {
+      AlignmentAnnotation annot = new AlignmentAnnotation(label,
+              description, null);
+
+      annot.label = label;
+      annot.description = description;
+
+      annot.setCalcId(JACKHMMER);
+
+      double dEValue = Double.parseDouble(eValue);
+      annot.setEValue(dEValue);
+
+      double dBitScore = Double.parseDouble(bitScore);
+      annot.setBitScore(dBitScore);
+
+      annot.setSequenceRef(seq);
+      seq.addAlignmentAnnotation(annot);
+
+    } catch (NumberFormatException e)
+    {
+      System.err.println("Error parsing " + label + " from " + eValue
+              + " & " + bitScore);
+    }
+  }
+
+  void buildArguments(List<String> args, File searchOutputFile,
+          File hitsAlignmentFile, File queryFile) throws IOException
+  {
+    args.add("-o");
+    args.add(getFilePath(searchOutputFile, true));
+    args.add("-A");
+    args.add(getFilePath(hitsAlignmentFile, true));
+
+    File databaseFile = null;
+
+    boolean useEvalueCutoff = false;
+    boolean useScoreCutoff = false;
+    String seqReportingEvalueCutoff = null;
+    String domReportingEvalueCutoff = null;
+    String seqReportingScoreCutoff = null;
+    String domReportingScoreCutoff = null;
+    String seqInclusionEvalueCutoff = null;
+    String domInclusionEvalueCutoff = null;
+    String seqInclusionScoreCutoff = null;
+    String domInclusionScoreCutoff = null;
+    databaseName = "Alignment";
+
+    if (params != null)
+    {
+      for (ArgumentI arg : params)
+      {
+        String name = arg.getName();
+
+        if (MessageManager.getString(REPORTING_CUTOFF_KEY).equals(name))
+        {
+          if (MessageManager.getString(CUTOFF_EVALUE)
+                  .equals(arg.getValue()))
+          {
+            useEvalueCutoff = true;
+          }
+          else if (MessageManager.getString(CUTOFF_SCORE)
+                  .equals(arg.getValue()))
+          {
+            useScoreCutoff = true;
+          }
+        }
+        else if (MessageManager.getString(REPORTING_SEQ_EVALUE_KEY)
+                .equals(name))
+        {
+          seqReportingEvalueCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(REPORTING_SEQ_SCORE_KEY)
+                .equals(name))
+        {
+          seqReportingScoreCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(REPORTING_DOM_EVALUE_KEY)
+                .equals(name))
+        {
+          domReportingEvalueCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(REPORTING_DOM_SCORE_KEY)
+                .equals(name))
+        {
+          domReportingScoreCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(INCLUSION_SEQ_EVALUE_KEY)
+                .equals(name))
+        {
+          seqInclusionEvalueCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(INCLUSION_SEQ_SCORE_KEY)
+                .equals(name))
+        {
+          seqInclusionScoreCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(INCLUSION_DOM_EVALUE_KEY)
+                .equals(name))
+        {
+          domInclusionEvalueCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(INCLUSION_DOM_SCORE_KEY)
+                .equals(name))
+        {
+          domInclusionScoreCutoff = arg.getValue();
+        }
+        else if (MessageManager.getString(DATABASE_KEY).equals(name))
+        {
+          databaseFile = new File(arg.getValue());
+          if (!arg.getValue().isEmpty())
+          {
+            searchAlignment = false;
+          }
+        }
+      }
+    }
+
+    if (useEvalueCutoff)
+    {
+      args.add("-E");
+      args.add(seqReportingEvalueCutoff);
+      args.add("--domE");
+      args.add(domReportingEvalueCutoff);
+
+      args.add("--incE");
+      args.add(seqInclusionEvalueCutoff);
+      args.add("--incdomE");
+      args.add(domInclusionEvalueCutoff);
+    }
+    else if (useScoreCutoff)
+    {
+      args.add("-T");
+      args.add(seqReportingScoreCutoff);
+      args.add("--domT");
+      args.add(domReportingScoreCutoff);
+
+      args.add("--incT");
+      args.add(seqInclusionEvalueCutoff);
+      args.add("--incdomT");
+      args.add(domInclusionEvalueCutoff);
+    }
+
+    // if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY)
+    // .equals(dbPath))
+    if (searchAlignment)
+    {
+      /*
+       * no external database specified for search, so
+       * export current alignment as 'database' to search
+       */
+      databaseFile = FileUtils.createTempFile("database", ".sto");
+      AlignmentI al = af.getViewport().getAlignment();
+      AlignmentI copy = new Alignment(al);
+
+      deleteHmmSequences(copy);
+
+      if (searchAlignment)
+      {
+        sequencesHash = stashSequences(copy.getSequencesArray());
+      }
+
+      exportStockholm(copy.getSequencesArray(), databaseFile, null);
+    }
+
+    args.add(getFilePath(queryFile, true));
+    args.add(getFilePath(databaseFile, true));
+  }
+}