JAL-2629 some tidying of Hmmer commands (wip)
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 28 Feb 2018 17:50:03 +0000 (17:50 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 28 Feb 2018 17:50:03 +0000 (17:50 +0000)
src/jalview/analysis/AAFrequency.java
src/jalview/api/AlignViewportI.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceI.java
src/jalview/hmmer/HMMBuildThread.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/workers/InformationThread.java

index 10ae253..04f34dd 100755 (executable)
@@ -353,7 +353,7 @@ public class AAFrequency
    */
   public static float completeInformation(AlignmentAnnotation information,
           ProfilesI profiles, int startCol, int endCol, long nseq,
-          Float currentMax)
+          float currentMax)
   {
     // long now = System.currentTimeMillis();
     if (information == null || information.annotations == null
@@ -366,48 +366,40 @@ public class AAFrequency
       return 0;
     }
 
-    Float max = 0f;
+    float max = 0f;
+    SequenceI hmmSeq = information.sequenceRef;
+    HiddenMarkovModel hmm = hmmSeq.getHMM();
 
-    for (int i = startCol; i < endCol; i++)
+    for (int column = startCol; column < endCol; column++)
     {
-      ProfileI profile = profiles.get(i);
+      ProfileI profile = profiles.get(column);
       if (profile == null)
       {
         /*
          * happens if sequences calculated over were 
          * shorter than alignment width
          */
-        information.annotations[i] = null;
-        return 0;
+        information.annotations[column] = null;
+        return 0f;
       }
       
-      SequenceI hmmSeq = information.sequenceRef;
-      
-      HiddenMarkovModel hmm = hmmSeq.getHMM();
-      
-      float value = hmm.getInformationContent(i);
-
-      if (value > max)
+      float value = hmm.getInformationContent(column);
+      if (!Float.isNaN(value))
       {
-        max = value;
+        max = Math.max(max, value);
       }
 
-      String description = value + " bits";
-      information.annotations[i] = new Annotation(
+      String description = Float.isNaN(value) ? null
+              : String.format("%.4f bits", value);
+      information.annotations[column] = new Annotation(
               Character.toString(Character
-                      .toUpperCase(hmm.getConsensusAtAlignColumn(i))),
+                      .toUpperCase(hmm.getConsensusAtAlignColumn(column))),
               description, ' ', value);
     }
-    if (max > currentMax)
-    {
-      information.graphMax = max;
-      return max;
-    }
-    else
-    {
-      information.graphMax = currentMax;
-      return currentMax;
-    }
+
+    max = Math.max(max, currentMax);
+    information.graphMax = max;
+    return max;
   }
 
   /**
index 3f1b6a4..ea921c7 100644 (file)
@@ -503,8 +503,6 @@ public interface AlignViewportI extends ViewStyleI
 
   List<AlignmentAnnotation> getInformationAnnotations();
 
-  AlignmentAnnotation getInformationAnnotation(int index);
-
   void setSequenceInformationHash(ProfilesI info, int index);
 
   /**
index 9398c0b..6bffcae 100755 (executable)
@@ -28,6 +28,7 @@ import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.MapList;
 import jalview.util.StringUtils;
+import jalview.workers.InformationThread;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -61,8 +62,6 @@ public class Sequence extends ASequence implements SequenceI
 
   int end;
 
-  boolean hasInfo;
-
   HiddenMarkovModel hmm;
 
   boolean isHMMConsensusSequence = false;
@@ -1945,21 +1944,25 @@ public class Sequence extends ASequence implements SequenceI
   }
 
   @Override
-  public void setIsHMMConsensusSequence(boolean isHMMConsensusSequence)
+  public void setIsHMMConsensusSequence(boolean value)
   {
-    this.isHMMConsensusSequence = isHMMConsensusSequence;
+    this.isHMMConsensusSequence = value;
   }
 
   @Override
   public boolean hasHMMAnnotation()
   {
-    return hasInfo;
-  }
-
-  @Override
-  public void setHasInfo(boolean status)
-  {
-    hasInfo = true;
+    if (this.annotation == null) {
+      return false;
+    }
+    for (AlignmentAnnotation ann : annotation)
+    {
+      if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
+      {
+        return true;
+      }
+    }
+    return false;
   }
 
   /**
index ee8c052..b666f83 100755 (executable)
@@ -503,10 +503,12 @@ public interface SequenceI extends ASequenceI
 
   void setIsHMMConsensusSequence(boolean isHMMConsensusSequence);
 
+  /**
+   * Answers true if the sequence has annotation for Hidden Markov Model
+   * information content, else false
+   */
   boolean hasHMMAnnotation();
 
-  void setHasInfo(boolean status);
-
   /**
    * Returns a (possibly empty) list of sequence features that overlap the given
    * alignment column range, optionally restricted to one or more specified
index 1842393..60bde84 100644 (file)
@@ -1,17 +1,22 @@
 package jalview.hmmer;
 
 import jalview.api.AlignViewportI;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
+import jalview.gui.AlignmentPanel;
 import jalview.gui.JvOptionPane;
 import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.io.HMMFile;
 import jalview.util.MessageManager;
+import jalview.workers.InformationThread;
 import jalview.ws.params.ArgumentI;
 
 import java.io.File;
@@ -109,7 +114,9 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
 
       if (alignment != null)
       {
-        runHMMBuild(null);
+        // alignment.findOrCreateAnnotation("", HMMBUILD, autoCalc, seqRef,
+        // groupRef);
+        runHMMBuild(alignment);
       }
 
       if (alignment == null)
@@ -117,7 +124,7 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
         alignment = viewport.getAlignment();
       }
 
-      for (SequenceGroup grp : groups)
+      for (AnnotatedCollectionI grp : groups)
       {
         runHMMBuild(grp);
       }
@@ -125,6 +132,7 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
     {
       if (af != null)
       {
+        viewport.updateInformation(af.alignPanel);
         af.buildColourMenu(); // enable HMMER colour schemes
         af.setProgressBar("", msgID);
       }
@@ -136,9 +144,9 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
    * 
    * @param grp
    */
-  private void runHMMBuild(SequenceGroup group)
+  private void runHMMBuild(AnnotatedCollectionI ac)
   {
-    if (alignment == null && group == null)
+    if (ac == null)
     {
       JOptionPane.showMessageDialog(af,
               MessageManager.getString("warn.no_sequence_data"));
@@ -151,20 +159,21 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
       alignmentFile = createTempFile("output", ".sto");
       SequenceI[] array;
       List<SequenceI> hmmSeqs = null;
-      if (group != null)
+      hmmSeqs = ac.getHMMConsensusSequences();
+      if (ac instanceof SequenceGroup)
       {
-        hmmSeqs = group.getHMMConsensusSequences();
-        array = group.getSelectionAsNewSequences(alignment);
+        array = ((SequenceGroup) ac)
+                .getSelectionAsNewSequences(alignment);
       }
       else
       {
-        hmmSeqs = alignment.getHMMConsensusSequences();
+        AlignmentI al = (Alignment) ac;
         // todo pad gaps in an unaligned SequenceGroup as well?
-        if (!alignment.isAligned())
+        if (!al.isAligned())
         {
-          alignment.padGaps();
+          al.padGaps();
         }
-        array = alignment.getSequencesArray();
+        array = al.getSequencesArray();
       }
 
       if (array.length < 1)
@@ -178,7 +187,9 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
       }
 
       /*
-       * copy over sequences excluding hmm consensus sequences
+       * copy over sequences, excluding hmm consensus sequences
+       * hmm sequences and their Information annotation are also deleted
+       * in preparation for re-adding them when recalculated
        */
       SequenceI[] newArr = new SequenceI[array.length - hmmSeqs.size()];
       int index = 0;
@@ -186,6 +197,18 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
       {
         if (seq.isHMMConsensusSequence())
         {
+          AlignmentAnnotation[] seqAnnotations = seq
+                  .getAnnotation();
+          if (seqAnnotations != null)
+          {
+            for (AlignmentAnnotation ann : seqAnnotations)
+            {
+              if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
+              {
+                alignment.deleteAnnotation(ann);
+              }
+            }
+          }
           alignment.deleteSequence(seq);
         }
         else
@@ -198,16 +221,16 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
       stashSequences(newArr);
 
       exportStockholm(newArr, alignmentFile,
-              group != null ? group : alignment);
+              ac != null ? ac : alignment);
 
       recoverSequences(array);
 
-      boolean ran = runCommand(alignmentFile, hmmFile, group);
+      boolean ran = runCommand(alignmentFile, hmmFile, ac);
       if (!ran)
       {
         return;
       }
-      importData(hmmFile, group);
+      importData(hmmFile, ac);
     } catch (Exception e)
     {
       e.printStackTrace();
@@ -227,29 +250,35 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
   /**
    * Constructs and executes the hmmbuild command as a separate process
    * 
-   * @param sequences
+   * @param sequencesFile
    *          the alignment from which the HMM is built
-   * @param hmm
+   * @param hmmFile
    *          the output file to which the HMM is written
    * @param group
-   *          (optional) group for which the hmm is generated
+   *          alignment or group for which the hmm is generated
    * 
    * @return
    * @throws IOException
-   * @throws InterruptedException
    */
-  private boolean runCommand(File sequences, File hmm, SequenceGroup group)
-          throws IOException, InterruptedException
+  private boolean runCommand(File sequencesFile, File hmmFile,
+          AnnotatedCollectionI group) throws IOException
   {
-
     String cmd = getCommandPath(HMMBUILD);
     if (cmd == null)
     {
-      return false;
+      return false; // executable not found
     }
     List<String> args = new ArrayList<>();
     args.add(cmd);
-    String name = null;
+
+    /*
+     * HMM name (will be given to consensus sequence) is
+     * - as specified by an input parameter if set
+     * - else group name with _HMM appended (if for a group)
+     * - else align fame title with _HMM appended (if title is not too long)
+     * - else "Alignment_HMM" 
+     */
+    String name = "";
 
     if (params != null)
     {
@@ -259,8 +288,7 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
         switch (argName)
         {
         case "HMM Name":
-          name = arg.getValue();
-          name = name.trim();
+          name = arg.getValue().trim();
           break;
         case "Use Reference Annotation":
           args.add("--hand");
@@ -269,25 +297,21 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
       }
     }
 
-    if (group != null)
+    if (group instanceof SequenceGroup)
     {
-      name = group.getName() + "_HMM";
+      name = ((SequenceGroup) group).getName() + "_HMM";
     }
 
-    if (name == null || "".equals(name))
+    if ("".equals(name))
     {
-      if (af != null)
+      if (af != null && af.getTitle().length() < 15)
       {
-        if (af.getTitle().length() < 15)
-        {
-          name = af.getTitle();
-        }
+        name = af.getTitle();
       }
-      if (name == null || "".equals(name))
+      else
       {
-        name = "Alignment";
+        name = "Alignment_HMM";
       }
-
     }
 
     args.add("-n");
@@ -301,8 +325,8 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
       args.add(ARG_DNA);
     }
 
-    args.add(hmm.getAbsolutePath());
-    args.add(sequences.getAbsolutePath());
+    args.add(hmmFile.getAbsolutePath());
+    args.add(sequencesFile.getAbsolutePath());
 
     return runCommand(args);
   }
@@ -313,29 +337,30 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
    * or group for which it was generated
    * 
    * @param hmmFile
-   * @oparam group (optional) the group for which the hmm was generated
+   * @param ac
+   *          (optional) the group for which the hmm was generated
    * @throws IOException
-   * @throws InterruptedException
    */
-  private void importData(File hmmFile, SequenceGroup group)
-          throws IOException, InterruptedException
+  private void importData(File hmmFile, AnnotatedCollectionI ac)
+          throws IOException
   {
     HMMFile file = new HMMFile(
             new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
     SequenceI[] seqs = file.getSeqsAsArray();
     SequenceI seq = seqs[0];
     seq.createDatasetSequence();
-    if (group != null)
+    if (ac instanceof SequenceGroup)
     {
-      seq.insertCharAt(0, group.getStartRes(), '-');
-      seq.insertCharAt(group.getEndRes() + 1,
-              alignment.getWidth() - group.getEndRes() - 1, '-');
+      SequenceGroup grp = (SequenceGroup) ac;
+      seq.insertCharAt(0, ac.getStartRes(), '-');
+      seq.insertCharAt(ac.getEndRes() + 1,
+              alignment.getWidth() - ac.getEndRes() - 1, '-');
       seq.updateHMMMapping();
-      SequenceI topSeq = group.getSequencesInOrder(alignment)[0];
+      SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
       int topIndex = alignment.findIndex(topSeq);
       alignment.insertSequenceAt(topIndex, seq);
-      group.setSeqrep(seq);
-      group.addSequence(seq, false);
+      ac.setSeqrep(seq);
+      grp.addSequence(seq, false);
     }
     else
     {
@@ -345,13 +370,14 @@ public class HMMBuildThread extends HmmerCommand implements Runnable
     AlignViewport viewport = af.getViewport();
     if (viewport != null)
     {
-      viewport.alignmentChanged(viewport.getAlignPanel());
-      viewport.getAlignPanel().adjustAnnotationHeight();
+      AlignmentPanel alignPanel = viewport.getAlignPanel();
+      viewport.alignmentChanged(alignPanel);
+      alignPanel.adjustAnnotationHeight();
       viewport.updateSequenceIdColours();
 
-      if (viewport.getAlignPanel().alignFrame.getSelectedHMM() == null)
+      if (alignPanel.alignFrame.getSelectedHMM() == null)
       {
-        viewport.getAlignPanel().alignFrame.setSelectedHMMSequence(seq);
+        alignPanel.alignFrame.setSelectedHMMSequence(seq);
       }
     }
   }
index 04af232..46ebe01 100644 (file)
@@ -844,12 +844,6 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public AlignmentAnnotation getInformationAnnotation(int index)
-  {
-    return information.get(index);
-  }
-
-  @Override
   public AlignmentAnnotation getAlignmentGapAnnotation()
   {
     return gapcounts;
@@ -2174,8 +2168,6 @@ public abstract class AlignmentViewport
                 new Annotation[1], 0f, 6.52f,
                 AlignmentAnnotation.BAR_GRAPH);
         info.hasText = true;
-        info.autoCalculated = true;
-        info.hasText = true;
         info.autoCalculated = false;
         info.sequenceRef = seq;
         info.setCalcId(InformationThread.HMM_CALC_ID);
@@ -2183,7 +2175,6 @@ public abstract class AlignmentViewport
         hinformation.add(new Profiles(new ProfileI[1]));
         alignment.addAnnotation(info);
         seq.updateHMMMapping();
-        seq.setHasInfo(true);
         seq.addAlignmentAnnotation(info);
       }
     }
index 5385359..09b428b 100644 (file)
@@ -197,7 +197,7 @@ public class InformationThread extends AlignCalcWorker
     int index = 0;
     for (AlignmentAnnotation information : annots)
     {
-      ProfilesI hinformation = (ProfilesI) getSequenceInformation(index);
+      ProfilesI hinformation = getSequenceInformation(index);
       if (immediate || !calcMan.isWorking(this) && information != null
               && hinformation != null)
       {
@@ -230,7 +230,7 @@ public class InformationThread extends AlignCalcWorker
    * 
    * @return
    */
-  protected Object getSequenceInformation(int index)
+  protected ProfilesI getSequenceInformation(int index)
   {
     return alignViewport.getSequenceInformationHash(index);
   }