Merge branch 'develop' into trialMerge
[jalview.git] / src / jalview / gui / AlignFrame.java
index d843c7f..6302f69 100644 (file)
@@ -54,6 +54,7 @@ import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SeqCigar;
@@ -62,6 +63,12 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.ColourMenuHelper.ColourChangeListener;
 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+import jalview.hmmer.HMMAlign;
+import jalview.hmmer.HMMBuild;
+import jalview.hmmer.HMMERParamStore;
+import jalview.hmmer.HMMERPreset;
+import jalview.hmmer.HMMSearch;
+import jalview.hmmer.HmmerCommand;
 import jalview.io.AlignmentProperties;
 import jalview.io.AnnotationFile;
 import jalview.io.BioJsHTMLOutput;
@@ -81,12 +88,14 @@ import jalview.io.JnetAnnotationMaker;
 import jalview.io.NewickFile;
 import jalview.io.ScoreMatrixFile;
 import jalview.io.TCoffeeScoreFile;
+import jalview.io.vcf.VCFLoader;
 import jalview.jbgui.GAlignFrame;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.ResidueColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
 import jalview.util.MessageManager;
+import jalview.util.StringUtils;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
 import jalview.ws.DBRefFetcher;
@@ -94,6 +103,9 @@ import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
 import jalview.ws.jws1.Discoverer;
 import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.WsParamSetI;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.awt.BorderLayout;
@@ -123,22 +135,29 @@ import java.awt.print.PrinterJob;
 import java.beans.PropertyChangeEvent;
 import java.io.File;
 import java.io.FileWriter;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Deque;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
 import java.util.Vector;
 
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JEditorPane;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
 import javax.swing.JInternalFrame;
 import javax.swing.JLayeredPane;
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
 
@@ -152,6 +171,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
 {
 
+  Map<String, Float> distribution = new HashMap<>(); // temporary
+
   public static final int DEFAULT_WIDTH = 700;
 
   public static final int DEFAULT_HEIGHT = 500;
@@ -163,9 +184,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
   AlignViewport viewport;
 
-  ViewportRanges vpRanges;
-
   public AlignViewControllerI avc;
+  /*
+   * The selected HMM for this align frame
+   */
+  SequenceI selectedHMMSequence;
 
   List<AlignmentPanel> alignPanels = new ArrayList<>();
 
@@ -179,6 +202,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   String fileName = null;
 
+
   /**
    * Creates a new AlignFrame object with specific width and height.
    * 
@@ -336,7 +360,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       progressBar = new ProgressBar(this.statusPanel, this.statusBar);
     }
 
-    vpRanges = viewport.getRanges();
     avc = new jalview.controller.AlignViewController(this, viewport,
             alignPanel);
     if (viewport.getAlignmentConservationAnnotation() == null)
@@ -654,9 +677,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                   { (viewport.cursorMode ? "on" : "off") }));
           if (viewport.cursorMode)
           {
-            alignPanel.getSeqPanel().seqCanvas.cursorX = vpRanges
+            ViewportRanges ranges = viewport.getRanges();
+            alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
                     .getStartRes();
-            alignPanel.getSeqPanel().seqCanvas.cursorY = vpRanges
+            alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
                     .getStartSeq();
           }
           alignPanel.getSeqPanel().seqCanvas.repaint();
@@ -689,10 +713,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           break;
         }
         case KeyEvent.VK_PAGE_UP:
-          vpRanges.pageUp();
+          viewport.getRanges().pageUp();
           break;
         case KeyEvent.VK_PAGE_DOWN:
-          vpRanges.pageDown();
+          viewport.getRanges().pageDown();
           break;
         }
       }
@@ -763,6 +787,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       ap.av.updateConservation(ap);
       ap.av.updateConsensus(ap);
       ap.av.updateStrucConsensus(ap);
+      ap.av.updateInformation(ap);
     }
   }
 
@@ -841,6 +866,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     AlignmentI al = getViewport().getAlignment();
     boolean nucleotide = al.isNucleotide();
 
+    loadVcf.setVisible(nucleotide);
     showTranslation.setVisible(nucleotide);
     showReverse.setVisible(nucleotide);
     showReverseComplement.setVisible(nucleotide);
@@ -904,6 +930,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
     showSequenceLogo.setSelected(av.isShowSequenceLogo());
     normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
+    showInformationHistogram.setSelected(av.isShowInformationHistogram());
+    showHMMSequenceLogo.setSelected(av.isShowHMMSequenceLogo());
+    normaliseHMMSequenceLogo.setSelected(av.isNormaliseHMMSequenceLogo());
 
     ColourMenuHelper.setColourSelected(colourMenu,
             av.getGlobalColourScheme());
@@ -995,6 +1024,202 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   @Override
+  public void hmmBuildSettings_actionPerformed()
+  {
+    if (!(alignmentIsSufficient(1)))
+    {
+      return;
+    }
+    WsParamSetI set = new HMMERPreset();
+    List<ArgumentI> args = new ArrayList<>();
+    ParamDatastoreI store = new HMMERParamStore("hmmbuild");
+    WsJobParameters params = new WsJobParameters(new JFrame(), store, set,
+            args);
+    if (params.showRunDialog())
+    {
+      new Thread(new HMMBuild(this, params.getJobParams())).start();
+    }
+    alignPanel.repaint();
+
+  }
+
+  @Override
+  public void hmmAlignSettings_actionPerformed()
+  {
+    if (!(checkForHMM() && alignmentIsSufficient(2)))
+    {
+      return;
+    }
+    WsParamSetI set = new HMMERPreset();
+    List<ArgumentI> args = new ArrayList<>();
+    ParamDatastoreI store = new HMMERParamStore("hmmalign");
+    WsJobParameters params = new WsJobParameters(new JFrame(), store, set,
+            args);
+    if (params.showRunDialog())
+    {
+      new Thread(new HMMAlign(this, params.getJobParams()))
+            .start();
+    }
+    alignPanel.repaint();
+  }
+
+  @Override
+  public void hmmSearchSettings_actionPerformed()
+  {
+    if (!checkForHMM())
+    {
+      return;
+    }
+    WsParamSetI set = new HMMERPreset();
+    List<ArgumentI> args = new ArrayList<>();
+    ParamDatastoreI store = new HMMERParamStore("hmmsearch");
+    WsJobParameters params = new WsJobParameters(new JFrame(), store, set,
+            args);
+    if (params.showRunDialog())
+    {
+      new Thread(new HMMSearch(this, params.getJobParams()))
+            .start();
+    }
+    alignPanel.repaint();
+  }
+
+  @Override
+  public void hmmBuildRun_actionPerformed()
+  {
+    if (!alignmentIsSufficient(1))
+    {
+      return;
+    }
+    new Thread(new HMMBuild(this, null))
+            .start();
+  }
+
+  @Override
+  public void hmmAlignRun_actionPerformed()
+  {
+    if (!(checkForHMM() && alignmentIsSufficient(2)))
+    {
+      return;
+    }
+    new Thread(new HMMAlign(this, null)).start();
+  }
+
+  @Override
+  public void hmmSearchRun_actionPerformed()
+  {
+    if (!checkForHMM())
+    {
+      return;
+    }
+    new Thread(new HMMSearch(this, null)).start();
+  }
+
+  /**
+   * Checks if the frame has a selected hidden Markov model
+   * 
+   * @return
+   */
+  private boolean checkForHMM()
+  {
+    if (getSelectedHMM() == null)
+    {
+      JOptionPane.showMessageDialog(this,
+              MessageManager.getString("warn.no_selected_hmm"));
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Checks if the alignment contains the required number of sequences.
+   * 
+   * @param required
+   * @return
+   */
+  public boolean alignmentIsSufficient(int required)
+  {
+    if (getViewport().getAlignment().getSequences().size() < required)
+    {
+      JOptionPane.showMessageDialog(this,
+              MessageManager.getString("warn.not_enough_sequences"));
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public void addDatabase_actionPerformed() throws IOException
+  {
+    if (Cache.getProperty(Preferences.HMMSEARCH_DB_PATHS) == null)
+    {
+      Cache.setProperty(Preferences.HMMSEARCH_DBS, "");
+      Cache.setProperty(Preferences.HMMSEARCH_DB_PATHS, "");
+    }
+
+    String path = openFileChooser(false);
+    if (new File(path).exists())
+    {
+      IdentifyFile identifier = new IdentifyFile();
+      FileFormatI format = identifier.identify(path, DataSourceType.FILE);
+      if (format == FileFormat.Fasta || format == FileFormat.Stockholm
+              || format == FileFormat.Pfam)
+      {
+        String currentDbs = Cache.getProperty(Preferences.HMMSEARCH_DBS);
+        String currentDbPaths = Cache
+                .getProperty(Preferences.HMMSEARCH_DB_PATHS);
+        currentDbPaths += " " + path;
+
+        String fileName = StringUtils.getLastToken(path, File.separator);
+        Scanner scanner = new Scanner(fileName).useDelimiter(".");
+        String name = scanner.next();
+        scanner.close();
+        currentDbs += " " + path; // TODO remove path from file name
+        scanner.close();
+
+        Cache.setProperty(Preferences.HMMSEARCH_DB_PATHS, currentDbPaths);
+        Cache.setProperty(Preferences.HMMSEARCH_DBS, currentDbPaths);
+      }
+      else
+      {
+        JOptionPane.showMessageDialog(this,
+                MessageManager.getString("warn.invalid_format"));
+      }
+    }
+    else
+    {
+      JOptionPane.showMessageDialog(this,
+              MessageManager.getString("warn.not_enough_sequences"));
+    }
+  }
+
+  /**
+   * Opens a file chooser
+   * 
+   * @param forFolder
+   * @return
+   */
+  protected String openFileChooser(boolean forFolder)
+  {
+    String choice = null;
+    JFileChooser chooser = new JFileChooser();
+    if (forFolder)
+    {
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+    }
+    chooser.setDialogTitle(
+            MessageManager.getString("label.open_local_file"));
+    chooser.setToolTipText(MessageManager.getString("action.open"));
+
+    int value = chooser.showOpenDialog(this);
+
+    if (value == JFileChooser.APPROVE_OPTION)
+    {
+      choice = chooser.getSelectedFile().getPath();
+    }
+    return choice;
+  }
+
+  @Override
   public void reload_actionPerformed(ActionEvent e)
   {
     if (fileName != null)
@@ -1392,17 +1617,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void exportFeatures_actionPerformed(ActionEvent e)
   {
-    new AnnotationExporter().exportFeatures(alignPanel);
+    new AnnotationExporter(alignPanel).exportFeatures();
   }
 
   @Override
   public void exportAnnotations_actionPerformed(ActionEvent e)
   {
-    new AnnotationExporter().exportAnnotations(alignPanel);
+    new AnnotationExporter(alignPanel).exportAnnotations();
   }
 
   @Override
   public void associatedData_actionPerformed(ActionEvent e)
+          throws IOException, InterruptedException
   {
     // Pick the tree file
     JalviewFileChooser chooser = new JalviewFileChooser(
@@ -1711,7 +1937,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     viewport.getAlignment().moveSelectedSequencesByOne(sg,
             viewport.getHiddenRepSequences(), up);
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   synchronized void slideSequences(boolean right, int size)
@@ -1889,9 +2115,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param e
    *          DOCUMENT ME!
+   * @throws InterruptedException
+   * @throws IOException
    */
   @Override
   protected void pasteNew_actionPerformed(ActionEvent e)
+          throws IOException, InterruptedException
   {
     paste(true);
   }
@@ -1901,9 +2130,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param e
    *          DOCUMENT ME!
+   * @throws InterruptedException
+   * @throws IOException
    */
   @Override
   protected void pasteThis_actionPerformed(ActionEvent e)
+          throws IOException, InterruptedException
   {
     paste(false);
   }
@@ -1913,8 +2145,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param newAlignment
    *          true to paste to a new alignment, otherwise add to this.
+   * @throws InterruptedException
+   * @throws IOException
    */
-  void paste(boolean newAlignment)
+  void paste(boolean newAlignment) throws IOException, InterruptedException
   {
     boolean externalPaste = true;
     try
@@ -2141,7 +2375,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       {
 
         // propagate alignment changed.
-        vpRanges.setEndSeq(alignment.getHeight());
+        viewport.getRanges().setEndSeq(alignment.getHeight());
         if (annotationAdded)
         {
           // Duplicate sequence annotation in all views.
@@ -2242,7 +2476,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       System.out.println("Exception whilst pasting: " + ex);
       // could be anything being pasted in here
     }
-
   }
 
   @Override
@@ -2259,11 +2492,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       if (Desktop.jalviewClipboard != null
               && Desktop.jalviewClipboard[2] != null)
       {
-        List<int[]> hc = (List<int[]>) Desktop.jalviewClipboard[2];
-        for (int region[] : hc)
-        {
-          af.viewport.hideColumns(region[0], region[1]);
-        }
+        HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+        af.viewport.setHiddenColumns(hc);
       }
 
       // >>>This is a fix for the moment, until a better solution is
@@ -2388,7 +2618,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
-      alignPanel.paintAlignment(true);
+      alignPanel.paintAlignment(true, true);
     }
   }
 
@@ -2414,7 +2644,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // JAL-2034 - should delegate to
     // alignPanel to decide if overview needs
     // updating.
-    alignPanel.paintAlignment(false);
+    alignPanel.paintAlignment(false, false);
     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
   }
 
@@ -2439,7 +2669,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // JAL-2034 - should delegate to
     // alignPanel to decide if overview needs
     // updating.
-    alignPanel.paintAlignment(false);
+    alignPanel.paintAlignment(false, false);
     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
     viewport.sendSelection();
   }
@@ -2470,7 +2700,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // alignPanel to decide if overview needs
     // updating.
 
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
     viewport.sendSelection();
   }
@@ -2479,7 +2709,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void invertColSel_actionPerformed(ActionEvent e)
   {
     viewport.invertColumnSelection();
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
     viewport.sendSelection();
   }
 
@@ -2539,7 +2769,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       {
         trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
                 column, viewport.getAlignment());
-        vpRanges.setStartRes(0);
+        viewport.getRanges().setStartRes(0);
       }
       else
       {
@@ -2604,13 +2834,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // This is to maintain viewport position on first residue
     // of first sequence
     SequenceI seq = viewport.getAlignment().getSequenceAt(0);
-    int startRes = seq.findPosition(vpRanges.getStartRes());
+    ViewportRanges ranges = viewport.getRanges();
+    int startRes = seq.findPosition(ranges.getStartRes());
     // ShiftList shifts;
     // viewport.getAlignment().removeGaps(shifts=new ShiftList());
     // edit.alColumnChanges=shifts.getInverse();
     // if (viewport.hasHiddenColumns)
     // viewport.getColumnSelection().compensateForEdits(shifts);
-    vpRanges.setStartRes(seq.findIndex(startRes) - 1);
+    ranges.setStartRes(seq.findIndex(startRes) - 1);
     viewport.firePropertyChange("alignment", null,
             viewport.getAlignment().getSequences());
 
@@ -2643,12 +2874,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // This is to maintain viewport position on first residue
     // of first sequence
     SequenceI seq = viewport.getAlignment().getSequenceAt(0);
-    int startRes = seq.findPosition(vpRanges.getStartRes());
+    int startRes = seq.findPosition(viewport.getRanges().getStartRes());
 
     addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
             viewport.getAlignment()));
 
-    vpRanges.setStartRes(seq.findIndex(startRes) - 1);
+    viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
 
     viewport.firePropertyChange("alignment", null,
             viewport.getAlignment().getSequences());
@@ -2704,8 +2935,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     /*
      * Create a new AlignmentPanel (with its own, new Viewport)
      */
-    AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel,
-            true);
+    AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel);
     if (!copyAnnotation)
     {
       /*
@@ -2859,21 +3089,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     alignPanel.getIdPanel().getIdCanvas()
             .setPreferredSize(alignPanel.calculateIdWidth());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   @Override
   public void idRightAlign_actionPerformed(ActionEvent e)
   {
     viewport.setRightAlignIds(idRightAlign.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   @Override
   public void centreColumnLabels_actionPerformed(ActionEvent e)
   {
     viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   /*
@@ -2906,7 +3136,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void colourTextMenuItem_actionPerformed(ActionEvent e)
   {
     viewport.setColourText(colourTextMenuItem.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   /**
@@ -2935,7 +3165,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void showAllColumns_actionPerformed(ActionEvent e)
   {
     viewport.showAllHiddenColumns();
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, true);
     viewport.sendSelection();
   }
 
@@ -3039,7 +3269,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.expandColSelection(sg, false);
     viewport.hideAllSelectedSeqs();
     viewport.hideSelectedColumns();
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, true);
     viewport.sendSelection();
   }
 
@@ -3055,7 +3285,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   {
     viewport.showAllHiddenColumns();
     viewport.showAllHiddenSeqs();
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, true);
     viewport.sendSelection();
   }
 
@@ -3063,7 +3293,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void hideSelColumns_actionPerformed(ActionEvent e)
   {
     viewport.hideSelectedColumns();
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, true);
     viewport.sendSelection();
   }
 
@@ -3084,7 +3314,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void scaleAbove_actionPerformed(ActionEvent e)
   {
     viewport.setScaleAboveWrapped(scaleAbove.isSelected());
-    alignPanel.paintAlignment(true);
+    // TODO: do we actually need to update overview for scale above change ?
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3097,7 +3328,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void scaleLeft_actionPerformed(ActionEvent e)
   {
     viewport.setScaleLeftWrapped(scaleLeft.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3110,7 +3341,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void scaleRight_actionPerformed(ActionEvent e)
   {
     viewport.setScaleRightWrapped(scaleRight.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3123,7 +3354,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
   {
     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   /**
@@ -3136,7 +3367,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void viewTextMenuItem_actionPerformed(ActionEvent e)
   {
     viewport.setShowText(viewTextMenuItem.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   /**
@@ -3149,7 +3380,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
   {
     viewport.setRenderGaps(renderGapsMenuItem.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   public FeatureSettings featureSettings;
@@ -3187,7 +3418,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void showSeqFeatures_actionPerformed(ActionEvent evt)
   {
     viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, true);
   }
 
   /**
@@ -3344,7 +3575,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     viewport.setGlobalColourScheme(cs);
 
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, true);
   }
 
   /**
@@ -3429,7 +3660,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             viewport.getAlignment().getSequenceAt(0));
     addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
             viewport.getAlignment()));
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3445,7 +3676,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     AlignmentSorter.sortByID(viewport.getAlignment());
     addHistoryItem(
             new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3461,7 +3692,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     AlignmentSorter.sortByLength(viewport.getAlignment());
     addHistoryItem(new OrderCommand("Length Sort", oldOrder,
             viewport.getAlignment()));
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3478,7 +3709,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     addHistoryItem(new OrderCommand("Group Sort", oldOrder,
             viewport.getAlignment()));
 
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
   }
 
   /**
@@ -3635,7 +3866,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         addHistoryItem(new OrderCommand(order.getName(), oldOrder,
                 viewport.getAlignment()));
 
-        alignPanel.paintAlignment(true);
+        alignPanel.paintAlignment(true, false);
       }
     });
   }
@@ -3664,7 +3895,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 viewport.getAlignment());// ,viewport.getSelectionGroup());
         addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
                 viewport.getAlignment()));
-        alignPanel.paintAlignment(true);
+        alignPanel.paintAlignment(true, false);
       }
     });
   }
@@ -3779,7 +4010,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       addHistoryItem(new OrderCommand(undoname, oldOrder,
               viewport.getAlignment()));
     }
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(true, false);
     return true;
   }
 
@@ -4250,7 +4481,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
           final String source)
   {
-    new Thread(CrossRefAction.showProductsFor(sel, _odna, source, this))
+    new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
             .start();
   }
 
@@ -4494,7 +4725,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                       assocfiles++;
                     }
                   }
-                  alignPanel.paintAlignment(true);
+                  // TODO: do we need to update overview ? only if features are
+                  // shown I guess
+                  alignPanel.paintAlignment(true, false);
                 }
               }
             }
@@ -4542,6 +4775,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param file
    *          either a filename or a URL string.
+   * @throws InterruptedException
+   * @throws IOException
    */
   public void loadJalviewDataFile(String file, DataSourceType sourceType,
           FileFormatI format, SequenceI assocSeq)
@@ -4629,11 +4864,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             new JnetAnnotationMaker();
             JnetAnnotationMaker.add_annotation(predictions,
                     viewport.getAlignment(), 0, false);
-            SequenceI repseq = viewport.getAlignment().getSequenceAt(0);
-            viewport.getAlignment().setSeqrep(repseq);
-            HiddenColumns cs = new HiddenColumns();
-            cs.hideInsertionsFor(repseq);
-            viewport.getAlignment().setHiddenColumns(cs);
+            viewport.getAlignment().setupJPredAlignment();
             isAnnotation = true;
           }
           // else if (IdentifyFile.FeaturesFile.equals(format))
@@ -4641,7 +4872,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           {
             if (parseFeaturesFile(file, sourceType))
             {
-              alignPanel.paintAlignment(true);
+              alignPanel.paintAlignment(true, true);
             }
           }
           else
@@ -4652,11 +4883,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       }
       if (isAnnotation)
       {
-
         alignPanel.adjustAnnotationHeight();
         viewport.updateSequenceIdColours();
         buildSortByAnnotationScoresMenu();
-        alignPanel.paintAlignment(true);
+        alignPanel.paintAlignment(true, true);
       }
     } catch (Exception ex)
     {
@@ -4855,14 +5085,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             MessageManager.getString("option.trim_retrieved_seqs"));
     trimrs.setToolTipText(
             MessageManager.getString("label.trim_retrieved_sequences"));
-    trimrs.setSelected(Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true));
+    trimrs.setSelected(
+            Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
     trimrs.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
         trimrs.setSelected(trimrs.isSelected());
-        Cache.setProperty("TRIM_FETCHED_DATASET_SEQS",
+        Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
                 Boolean.valueOf(trimrs.isSelected()).toString());
       };
     });
@@ -5181,7 +5412,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
   {
     viewport.setShowUnconserved(showNonconservedMenuItem.getState());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   /*
@@ -5251,6 +5482,30 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   @Override
+  protected void showInformationHistogram_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowInformationHistogram(
+            showInformationHistogram.getState());
+    alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+  }
+
+  @Override
+  protected void showHMMSequenceLogo_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowHMMSequenceLogo(showHMMSequenceLogo.getState());
+    alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+  }
+
+  @Override
+  protected void normaliseHMMSequenceLogo_actionPerformed(ActionEvent e)
+  {
+    showHMMSequenceLogo.setState(true);
+    viewport.setShowHMMSequenceLogo(true);
+    viewport.setNormaliseHMMSequenceLogo(normaliseSequenceLogo.getState());
+    alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+  }
+
+  @Override
   protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
   {
     alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
@@ -5270,7 +5525,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
-      alignPanel.paintAlignment(true);
+      alignPanel.paintAlignment(true, true);
     }
   }
 
@@ -5282,7 +5537,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       viewport.getAlignment().setSeqrep(null);
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
-      alignPanel.paintAlignment(true);
+      alignPanel.paintAlignment(true, true);
     }
   }
 
@@ -5372,7 +5627,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
     this.alignPanel.av
             .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
-    alignPanel.paintAlignment(true);
+    alignPanel.paintAlignment(false, false);
   }
 
   /**
@@ -5575,6 +5830,89 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       new CalculationChooser(AlignFrame.this);
     }
   }
+
+  /**
+   * Sets the status of the HMMER menu
+   */
+  public void updateHMMERStatus()
+  {
+    hmmerMenu.setEnabled(HmmerCommand.isHmmerAvailable());
+  }
+
+  /**
+   * Returns the selected hidden Markov model.
+   * 
+   * @return
+   */
+  public HiddenMarkovModel getSelectedHMM()
+  {
+    if (selectedHMMSequence == null)
+    {
+      return null;
+    }
+    return selectedHMMSequence.getHMM();
+  }
+
+  /**
+   * Returns the selected hidden Markov model.
+   * 
+   * @return
+   */
+  public SequenceI getSelectedHMMSequence()
+  {
+    return selectedHMMSequence;
+  }
+
+  /**
+   * Sets the selected hidden Markov model
+   * 
+   * @param selectedHMM
+   */
+  public void setSelectedHMMSequence(SequenceI selectedHMM)
+  {
+    this.selectedHMMSequence = selectedHMM;
+    hmmAlign.setText(MessageManager.getString("label.hmmalign") + " to "
+            + selectedHMM.getHMM().getName());
+    hmmSearch.setText(MessageManager.getString("label.hmmsearch") + " with "
+            + selectedHMM.getHMM().getName());
+  }
+
+  @Override
+  public void hmmerMenu_actionPerformed(ActionEvent e)
+  {
+    SequenceGroup grp = getViewport().getSelectionGroup();
+    if (grp != null)
+    {
+      hmmBuild.setText(MessageManager.getString("label.hmmbuild") + " from "
+              + grp.getName());
+    }
+    else
+    {
+      hmmBuild.setText(MessageManager.getString("label.hmmbuild")
+              + " from Alignment");
+    }
+  }
+
+  @Override
+  protected void loadVcf_actionPerformed()
+  {
+    JalviewFileChooser chooser = new JalviewFileChooser(
+            Cache.getProperty("LAST_DIRECTORY"));
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
+    chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
+
+    int value = chooser.showOpenDialog(null);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+      String choice = chooser.getSelectedFile().getPath();
+      Cache.setProperty("LAST_DIRECTORY", choice);
+      SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
+      new VCFLoader(choice).loadVCF(seqs, this);
+    }
+
+  }
 }
 
 class PrintThread extends Thread