JAL-3336 add better method of determining where data table begins
[jalview.git] / src / jalview / hmmer / HMMSearch.java
index a58b949..57786e5 100644 (file)
@@ -4,6 +4,7 @@ import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
@@ -180,9 +181,9 @@ public class HMMSearch extends HmmerCommand
           File hitsAlignmentFile, File hmmFile) throws IOException
   {
     args.add("-o");
-    args.add(getFilePath(searchOutputFile));
+    args.add(getFilePath(searchOutputFile, true));
     args.add("-A");
-    args.add(getFilePath(hitsAlignmentFile));
+    args.add(getFilePath(hitsAlignmentFile, true));
 
     boolean dbFound = false;
     String dbPath = "";
@@ -195,6 +196,7 @@ public class HMMSearch extends HmmerCommand
     String seqScoreCutoff = null;
     String domScoreCutoff = null;
     databaseName = "Alignment";
+    boolean searchAlignment = false;
 
     if (params != null)
     {
@@ -206,6 +208,18 @@ public class HMMSearch extends HmmerCommand
         {
           seqsToReturn = Integer.parseInt(arg.getValue());
         }
+        else if (MessageManager.getString("action.search").equals(name))
+        {
+          searchAlignment = arg.getValue().equals(
+                  MessageManager.getString(HMMSearch.THIS_ALIGNMENT_KEY));
+        }
+        else if (MessageManager.getString(DATABASE_KEY).equals(name))
+        {
+          dbPath = arg.getValue();
+          int pos = dbPath.lastIndexOf(File.separator);
+          databaseName = dbPath.substring(pos + 1);
+          databaseFile = new File(dbPath);
+        }
         else if (MessageManager.getString(AUTO_ALIGN_SEQS_KEY)
                 .equals(name))
         {
@@ -280,8 +294,9 @@ public class HMMSearch extends HmmerCommand
       args.add(domScoreCutoff);
     }
 
-    if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY)
-            .equals(dbPath))
+//    if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY)
+//            .equals(dbPath))
+      if (searchAlignment)
     {
       /*
        * no external database specified for search, so
@@ -299,8 +314,8 @@ public class HMMSearch extends HmmerCommand
       exportStockholm(copy.getSequencesArray(), databaseFile, null);
     }
 
-    args.add(getFilePath(hmmFile));
-    args.add(getFilePath(databaseFile));
+    args.add(getFilePath(hmmFile, true));
+    args.add(getFilePath(databaseFile, true));
   }
 
   /**
@@ -326,14 +341,55 @@ public class HMMSearch extends HmmerCommand
       StockholmFile file = new StockholmFile(new FileParse(
               inputAlignmentTemp.getAbsolutePath(), DataSourceType.FILE));
       seqs = file.getSeqsAsArray();
-
+      // look for PP cons and ref seq in alignment only annotation
+      AlignmentAnnotation modelpos = null, ppcons = null;
+      for (AlignmentAnnotation aa : file.getAnnotations())
+      {
+        if (aa.sequenceRef == null)
+        {
+          if (aa.label.equals("Reference Positions")) // RF feature type in
+                                                      // stockholm parser
+          {
+            modelpos = aa;
+          }
+          if (aa.label.equals("Posterior Probability"))
+          {
+            ppcons = aa;
+          }
+        }
+      }
       readTable(searchOutputFile);
 
       int seqCount = Math.min(seqs.length, seqsToReturn);
       SequenceI[] hmmAndSeqs = new SequenceI[seqCount + 1];
+      hmmSeq = hmmSeq.deriveSequence(); // otherwise all bad things happen
       hmmAndSeqs[0] = hmmSeq;
       System.arraycopy(seqs, 0, hmmAndSeqs, 1, seqCount);
-
+      if (modelpos != null)
+      {
+        // TODO need - get ungapped sequence method
+        hmmSeq.setSequence(
+                hmmSeq.getDatasetSequence().getSequenceAsString());
+        Annotation[] refpos = modelpos.annotations;
+        // insert gaps to match with refseq positions
+        int gc = 0, lcol = 0;
+        for (int c = 0; c < refpos.length; c++)
+        {
+          if (refpos[c] != null && ("x".equals(refpos[c].displayCharacter)))
+          {
+            if (gc > 0)
+            {
+              hmmSeq.insertCharAt(lcol + 1, gc, '-');
+            }
+            gc = 0;
+            lcol = c;
+          }
+          else
+          {
+            gc++;
+          }
+        }
+      }
       if (realign)
       {
         realignResults(hmmAndSeqs);
@@ -341,6 +397,14 @@ public class HMMSearch extends HmmerCommand
       else
       {
         AlignmentI al = new Alignment(hmmAndSeqs);
+        if (ppcons != null)
+        {
+          al.addAnnotation(ppcons);
+        }
+        if (modelpos != null)
+        {
+          al.addAnnotation(modelpos);
+        }
         AlignFrame alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
                 AlignFrame.DEFAULT_HEIGHT);
         String ttl = "hmmSearch of " + databaseName + " using "
@@ -406,23 +470,28 @@ public class HMMSearch extends HmmerCommand
     {
       line = br.readLine();
     }
-    for (int i = 0; i < 5; i++)
+    while (!line.contains("-------"))
     {
       line = br.readLine();
     }
+    line = br.readLine();
 
     int index = 0;
     while (!"  ------ inclusion threshold ------".equals(line)
             && !"".equals(line))
     {
       SequenceI seq = seqs[index];
+      AlignmentAnnotation pp = seq
+              .getAlignmentAnnotations("", "Posterior Probability")
+              .get(0);
       Scanner scanner = new Scanner(line);
       String str = scanner.next();
       addScoreAnnotation(str, seq, "hmmsearch E-value",
-              "Full sequence E-value");
+              "Full sequence E-value", pp);
       str = scanner.next();
       addScoreAnnotation(str, seq, "hmmsearch Score",
-              "Full sequence bit score");
+              "Full sequence bit score", pp);
+      seq.removeAlignmentAnnotation(pp);
       scanner.close();
       line = br.readLine();
       index++;
@@ -443,10 +512,38 @@ public class HMMSearch extends HmmerCommand
   protected void addScoreAnnotation(String value, SequenceI seq,
           String label, String description)
   {
+    addScoreAnnotation(value, seq, label, description, null);
+  }
+
+  /**
+   * A helper method that adds one score-only (non-positional) annotation to a
+   * sequence
+   * 
+   * @param value
+   * @param seq
+   * @param label
+   * @param description
+   * @param pp
+   *          existing posterior probability annotation - values copied to new
+   *          annotation row
+   */
+  protected void addScoreAnnotation(String value, SequenceI seq,
+          String label, String description, AlignmentAnnotation pp)
+  {
     try
     {
-      AlignmentAnnotation annot = new AlignmentAnnotation(label,
+      AlignmentAnnotation annot = null;
+      if (pp == null)
+      {
+        new AlignmentAnnotation(label,
               description, null);
+      }
+      else
+      {
+        annot = new AlignmentAnnotation(pp);
+        annot.label = label;
+        annot.description = description;
+      }
       annot.setCalcId(HMMSEARCH);
       double eValue = Double.parseDouble(value);
       annot.setScore(eValue);